more notes and some opengl light in the tunnel
This commit is contained in:
parent
a7c31193bc
commit
8f0d4b30bb
|
@ -1,174 +0,0 @@
|
|||
;(load (sb-ext:posix-getenv "ASDF"))
|
||||
(asdf:load-system 'dbus)
|
||||
|
||||
(defpackage
|
||||
#:screencasting
|
||||
(:use #:cl)
|
||||
(:export call-with-all-predefined))
|
||||
(in-package #:screencasting)
|
||||
|
||||
;; https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.ScreenCast.html
|
||||
(defconstant +screen-cast-interface+ "org.freedesktop.portal.ScreenCast")
|
||||
(defconstant +request-interface+ "org.freedesktop.portal.Request")
|
||||
|
||||
;; some iolib tutorial https://pages.cs.wisc.edu/~psilord/blog/data/iolib-tutorial/tutorial.html
|
||||
;; i hoped it would help me understand the 'publish-events'
|
||||
|
||||
;; i'm not sure how to do interactive calls,
|
||||
;; since maybe i need to "publish objects"
|
||||
;; and that means the callbacks are set in stone?
|
||||
;; i guess i could try to do a Notification call in the callback on screenshot request?
|
||||
|
||||
(defun send-notification (bus message)
|
||||
(dbus:with-introspected-object (notification bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
|
||||
(notification "org.freedesktop.Notifications" "Notify"
|
||||
"Test" 0 "" "Test" (or message "This is a test; I repeat, this is a test.") '() '() -1)))
|
||||
|
||||
;; well, i suppose i would need to open multiple connections?
|
||||
;; let's do something like this https://github.com/Lautaro-Garcia/cl-notify/blob/main/src/dbus-protocol.lisp#L27
|
||||
;; (defmacro with-dbus-method-inovaction ((result-var method &rest args) &body body)
|
||||
;; (alexandria:with-gensyms (bus notifications-object)
|
||||
;; `(dbus:with-open-bus (,bus (dbus:session-server-addresses))
|
||||
;; (dbus:with-introspected-object (,notifications-object ,bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
|
||||
;; (let ((,result-var (,notifications-object "org.freedesktop.Notifications" ,method ,@args)))
|
||||
;; ,@body)))))
|
||||
|
||||
;; but. this supposes result-var being a resulting value
|
||||
;; and i'd want to what? pass in a callback to register?
|
||||
|
||||
;; alright, let's have function startup new bus connection for each call
|
||||
;; but then try to do these multiple calls
|
||||
|
||||
(defun call-screencast-method (method-name params)
|
||||
(handler-case
|
||||
(dbus:with-open-bus (bus (dbus:session-server-addresses))
|
||||
(let*
|
||||
((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1))
|
||||
(request-name "yayay")
|
||||
(resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/"
|
||||
requester-name
|
||||
"/"
|
||||
request-name)))
|
||||
(dbus:define-dbus-object request-object
|
||||
(:path resp-path))
|
||||
|
||||
(dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT))))
|
||||
(:interface +request-interface+)
|
||||
(format t "Got response ~S with results ~S~%" id results)
|
||||
(format t "before sending notification")
|
||||
(send-notification bus "yayaya from the first response")
|
||||
(format t "ending signal handler")
|
||||
(force-output))
|
||||
|
||||
(format T "Will try to listen on ~A~%" resp-path)
|
||||
(format T "Bus connection name ~A~%" (dbus:bus-name bus))
|
||||
(dbus:add-match bus :type :signal
|
||||
:interface +request-interface+)
|
||||
(dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
|
||||
(desktop +screen-cast-interface+ method-name ; "CreateSession"
|
||||
params
|
||||
;; '(("handle_token" ((:string) "yayay"))
|
||||
;; ("session_handle_token" ((:string) "hohoyyy")))
|
||||
))
|
||||
(dbus:publish-objects bus '(request-object) )))
|
||||
(end-of-file ()
|
||||
:disconnected-by-bus)))
|
||||
|
||||
'(call-screencast-method "CreateSession"
|
||||
'(("handle_token" ((:string) "yayay"))
|
||||
("session_handle_token" ((:string) "hohoyyy"))))
|
||||
|
||||
;; let's define ALL beforehand?
|
||||
(defun call-with-all-predefined ()
|
||||
(handler-case
|
||||
(dbus:with-open-bus (bus (dbus:session-server-addresses))
|
||||
(let*
|
||||
((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1))
|
||||
(request-create-session-name "createSessionReq")
|
||||
(resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/"
|
||||
requester-name
|
||||
"/"
|
||||
request-create-session-name))
|
||||
(request-select-sources "selectSourcesReq")
|
||||
(select-sources-resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/"
|
||||
requester-name
|
||||
"/"
|
||||
request-select-sources))
|
||||
(request-start "startReq")
|
||||
(start-resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/"
|
||||
requester-name
|
||||
"/"
|
||||
request-start))
|
||||
(session-handle-hardcoded "yayay")
|
||||
(session-handle-path (concatenate 'string "/org/freedesktop/portal/desktop/session/"
|
||||
requester-name
|
||||
"/"
|
||||
session-handle-hardcoded)))
|
||||
(dbus:define-dbus-object request-object
|
||||
(:path resp-path))
|
||||
|
||||
(dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT))))
|
||||
(:interface +request-interface+)
|
||||
(format t "Got response ~S with results ~S~%" id results)
|
||||
(send-notification bus "yayaya from the first response")
|
||||
(format t "About sto send SelectSources with path ~S~%" session-handle-path)
|
||||
(force-output)
|
||||
(dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
|
||||
(desktop +screen-cast-interface+ "SelectSources"
|
||||
session-handle-path ; hardcoded session-handle
|
||||
`(("handle_token" ((:string) ,request-select-sources)))))
|
||||
(format t "Still first callback, after calling SelectSources~%")
|
||||
(force-output))
|
||||
|
||||
(dbus:define-dbus-object select-sources-request-obj
|
||||
(:path select-sources-resp-path))
|
||||
|
||||
(dbus:define-dbus-signal-handler (select-sources-request-obj response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT))))
|
||||
(:interface +request-interface+)
|
||||
(format t ">> Got inside of SelectSources callback ~A ~A~%" id results)
|
||||
(dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
|
||||
(desktop +screen-cast-interface+ "Start"
|
||||
session-handle-path
|
||||
"parent-window"
|
||||
`(("handle_token" ((:string) , request-start)))))
|
||||
(format t ">> Still inside SelectSources callback, after calling Start~%")
|
||||
(force-output))
|
||||
|
||||
(dbus:define-dbus-object start-request-obj
|
||||
(:path start-resp-path))
|
||||
|
||||
(dbus:define-dbus-signal-handler (start-request-obj response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT))))
|
||||
(:interface +request-interface+)
|
||||
(format t ">> Got inside of Start callback ~A ~A~%" id results))
|
||||
|
||||
(format T "Will try to listen on ~A~%" resp-path)
|
||||
(format T "Bus connection name ~A~%" (dbus:bus-name bus))
|
||||
(dbus:add-match bus :type :signal
|
||||
:interface +request-interface+)
|
||||
(dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
|
||||
(desktop +screen-cast-interface+ "CreateSession"
|
||||
`(("handle_token" ((:string) ,request-create-session-name))
|
||||
("session_handle_token" ((:string) ,session-handle-hardcoded)))))
|
||||
(dbus:publish-objects bus)))
|
||||
(end-of-file ()
|
||||
:disconnected-by-bus)))
|
||||
|
||||
|
||||
;; ok
|
||||
;; >> Got inside of Start callback 0 ((streams
|
||||
;; ((43
|
||||
;; ((position (0 0)) (size (1920 1080)))))))
|
||||
;; interesting. now what do do with the streams?
|
||||
;; An array of PipeWire streams. Each stream consists of a PipeWire node ID (the first element in the tuple, and a Vardict of properties.
|
||||
;; ok, now i need to figure out how
|
||||
;; yeah, nix shell nixpkgs#qpwgraph
|
||||
;; with this tool i see new 'out' node, maybe i can even already connect to it with
|
||||
;; some program?
|
||||
;; yes. enefedov@LLF33A87M:~/Documents/personal/learning-screen-share$ gst-launch-1.0 pipewiresrc path=43 ! videoconvert ! autovideosink
|
||||
|
||||
;; cool.
|
||||
;; now i want to have a window with this video stream created by my program
|
||||
;; this is new level of "i have no idea where to go"
|
||||
;; https://github.com/death/dbus/issues/31
|
||||
;; asked my question about multiple async dbus requests
|
||||
|
|
@ -145,6 +145,7 @@
|
|||
(format T "Bus connection name ~A~%" (dbus:bus-name bus))
|
||||
(dbus:add-match bus :type :signal
|
||||
:interface +request-interface+)
|
||||
(format T "About to send first message to dbus : Create Seccion~%")
|
||||
(dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
|
||||
(desktop +screen-cast-interface+ "CreateSession"
|
||||
`(("handle_token" ((:string) ,request-create-session-name))
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1719597372,
|
||||
"narHash": "sha256-SpZKwy6sjgH00xiYmfjVAX+JaNkPQ2Q/BrEhNtWJvH4=",
|
||||
"lastModified": 1734802620,
|
||||
"narHash": "sha256-rUg5S3bKZu1rNPY5/EqQNXN9DNpXIZXc/AnbcK/h/sU=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dd66e39ec4c7252fab7e6f8fd57b5ab2a3c7d63c",
|
||||
"rev": "8ddbc4432614ed034cb69f02eedd723250d9513e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
22
flake.nix
22
flake.nix
|
@ -4,8 +4,7 @@
|
|||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem
|
||||
(system:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
# https://nixos.org/manual/nixpkgs/stable/#lisp-overriding-package-attributes
|
||||
|
@ -19,28 +18,23 @@
|
|||
hash = "sha256-xbg3tPYfRNGJo+9F/58w2bDeZqV33Z871+ClSg4ACPk=";
|
||||
};
|
||||
});
|
||||
sbcl' = pkgs.sbcl.withPackages (ps: [ ps.alexandria
|
||||
sbcl' = pkgs.sbcl.withPackages (ps: [
|
||||
ps.alexandria
|
||||
dbus'
|
||||
ps.cl-cffi-gtk
|
||||
ps.sdl2
|
||||
ps.cl-opengl
|
||||
ps.cl-gobject-introspection
|
||||
]);
|
||||
in
|
||||
{
|
||||
# Create a wrapper that uses system's Wayland
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
SDL_VIDEODRIVER="wayland";
|
||||
WAYLAND_DISPLAY="wayland-1";
|
||||
EGL_PLATFORM="wayland";
|
||||
buildInputs = [
|
||||
pkgs.gst_all_1.gstreamer
|
||||
pkgs.gst_all_1.gst-plugins-base
|
||||
pkgs.gst_all_1.gst-plugins-good
|
||||
pkgs.pipewire
|
||||
sbcl'
|
||||
|
||||
pkgs.nixfmt
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
});
|
||||
# see https://serokell.io/blog/practical-nix-flakes
|
||||
}
|
||||
|
|
118
notes.org
118
notes.org
|
@ -677,4 +677,122 @@ but maybe i want something else?
|
|||
|
||||
let's read docs on appsrc
|
||||
https://github.com/go-gst/go-gst/tree/v1.1.0/examples/appsrc
|
||||
* [2024-12-08 Sun]
|
||||
** well, i guess i will maybe return to this?
|
||||
https://www.youtube.com/watch?v=Jn_09BeUEI0
|
||||
here is gltransformation
|
||||
this looks like what i'd really want, no?
|
||||
** and this is documentation
|
||||
https://gstreamer.freedesktop.org/documentation/opengl/index.html?gi-language=c
|
||||
|
||||
https://gstreamer.freedesktop.org/documentation/opengl/gltransformation.html?gi-language=c#gltransformation
|
||||
why doesn't it work?
|
||||
* [2024-12-21 Sat]
|
||||
** wait. it works now? how and why
|
||||
maybe because it's installed via apt?
|
||||
yes. if i try to use
|
||||
gst-launch-1.0 gltestsrc ! gltransformation scale-y=0.5 scale-x=0.5 ! glimagesink
|
||||
in the nix shell i get
|
||||
#+begin_src
|
||||
Setting pipeline to PAUSED ...
|
||||
Caught SIGSEGV
|
||||
Spinning. Please run 'gdb gst-launch-1.0 242683' to continue debugging, Ctrl-C to quit, or Ctrl-\ to dump core.
|
||||
#+end_src
|
||||
** for now found article about other ways to transform
|
||||
https://lubosz.wordpress.com/2014/06/16/transforming-video-on-the-gpu/
|
||||
but that this opengl way is much faster
|
||||
|
||||
comparing with this:
|
||||
https://gstreamer.freedesktop.org/documentation/videoconvertscale/videoscale.html?gi-language=c
|
||||
gst-launch-1.0 -v videotestsrc ! videoscale ! autovideosink
|
||||
|
||||
|
||||
gst-launch-1.0 -v videotestsrc ! videoscale ! video/x-raw,width=1000 ! autovideosink
|
||||
** the ordinary error is
|
||||
gst-launch-1.0 gltestsrc ! gltransformation rotation-z=45 ! glimagesink
|
||||
Setting pipeline to PAUSED ...
|
||||
Caught SIGSEGV
|
||||
Spinning. Please run 'gdb gst-launch-1.0 7843' to continue debugging, Ctrl-C to quit, or Ctrl-\ to dump core.
|
||||
|
||||
** huh. trying previous nixpkgs releases
|
||||
and in 23.05 the error is different
|
||||
efim-nefedov@LLF33A87M:~/Documents/personal/scratch-screen-share$ gst-launch-1.0 gltestsrc ! gltransformation rotation-z=45 ! glimagesink
|
||||
Setting pipeline to PAUSED ...
|
||||
ERROR: from element /GstPipeline:pipeline0/GstGLImageSinkBin:glimagesinkbin0/GstGLImageSink:sink: Could not find any FBConfig's to use (check attributes?)
|
||||
Additional debug info:
|
||||
../ext/gl/gstglimagesink.c(1131): _ensure_gl_setup (): /GstPipeline:pipeline0/GstGLImageSinkBin:glimagesinkbin0/GstGLImageSink:sink
|
||||
ERROR: pipeline doesn't want to preroll.
|
||||
Failed to set pipeline to PAUSED.
|
||||
Setting pipeline to NULL ...
|
||||
Freeing pipeline ...
|
||||
|
||||
** ok, looking at the error the problem is in creating connection
|
||||
WARN gldisplayegl gstgldisplay_egl.c:408:gst_gl_display_egl_from_gl_display:<gldisplayegl1> failed to get EGLDisplay from native display
|
||||
|
||||
but beats me if i know what needs to be done
|
||||
claude.ai recommends adding LD_LIBRARY_PATH to gstreamer
|
||||
so trying
|
||||
#+begin_src nix
|
||||
gstWrapper = pkgs.writeScriptBin "gst-launch-wrapped" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
|
||||
exec ${pkgs.gst_all_1.gstreamer}/bin/gst-launch-1.0 "$@"
|
||||
'';
|
||||
#+end_src
|
||||
|
||||
but that fails
|
||||
$ gst-launch-wrapped gltestsrc ! gltransformation rotation-z=45 ! glimagesink
|
||||
/nix/store/p6k7xp1lsfmbdd731mlglrdj2d66mr82-bash-5.2p37/bin/bash: error while loading shared libraries: __vdso_gettimeofday: invalid mode for dlopen(): Invalid argument
|
||||
|
||||
* [2024-12-22 Sun]
|
||||
|
||||
** ok, let's try what
|
||||
let's try default video out after i turn on the screen sharing from cl part
|
||||
|
||||
with code cleaned up i can start the share, that's nice
|
||||
|
||||
gst-launch-1.0 pipewiresrc path=90 ! videoconvert ! autovideosink
|
||||
|
||||
let's also try to add opengl processing
|
||||
gst-launch-1.0 pipewiresrc path=90 ! videoconvert ! gltransformation rotation-z=45 ! glimagesink
|
||||
|
||||
so, this kind of works
|
||||
gst-launch-1.0 pipewiresrc path=90 ! videoconvert ! capsfilter caps="video/x-raw,format=RGBA" ! glupload ! gltransformation rotation-z=45 ! glimagesink
|
||||
|
||||
even if the thing is small
|
||||
|
||||
** trying to figure out why gl things open a small window
|
||||
*** one that works
|
||||
GST_DEBUG=4,caps:5 gst-launch-1.0 pipewiresrc path=90 ! videoconvert ! autovideosink
|
||||
has
|
||||
deterministic way of creating a stream-id
|
||||
0:00:00.032812186 44186 0x74b020000b70 INFO GST_EVENT gstevent.c:918:gst_event_new_caps: creating caps event video/x-raw, format=(string)BGRA, width=(int)1920, height=(int)1080, framerate=(fraction)0/1, max-framerate=(fraction)60/1
|
||||
0:00:00.033493070 44186 0x74b020000b70 INFO GST_EVENT gstevent.c:918:gst_event_new_caps: creating caps event video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)0/1, max-framerate=(fraction)60/1, format=(string)YV12
|
||||
|
||||
*** and comparing with
|
||||
GST_DEBUG=4,caps:5 gst-launch-1.0 pipewiresrc path=90 ! videoconvert ! capsfilter caps="video/x-raw,format=RGBA" ! glupload ! gltransformation rotation-z=45 ! glimagesink
|
||||
(by recommendation of claude)
|
||||
0:00:00.152714238 44533 0x784a70000b70 INFO GST_EVENT gstevent.c:918:gst_event_new_caps: creating caps event video/x-raw(memory:GLMemory), width=(int)1920, height=(int)1080, framerate=(fraction)0/1, max-framerate=(fraction)60/1, format=(string)RGBA, texture-target=(string)2D
|
||||
0:00:00.152789062 44533 0x784a70000b70 INFO basetransform gstbasetransform.c:1326:gst_base_transform_setcaps:<glcolorbalance0> reuse caps
|
||||
0:00:00.152821256 44533 0x784a70000b70 INFO GST_EVENT gstevent.c:918:gst_event_new_caps: creating caps event video/x-raw(memory:GLMemory), width=(int)1920, height=(int)1080, framerate=(fraction)0/1, max-framerate=(fraction)60/1, format=(string)RGBA, texture-target=(string)2D
|
||||
|
||||
well, i guess i can just open the window full size
|
||||
|
||||
*** ok! looks like it does stream full resolution.
|
||||
now. i'd want to open the displaying pipeline programmatically
|
||||
and then maybe try to dynamically change params
|
||||
|
||||
i guess even without a window embedding, just starting a window is good enough
|
||||
but also, hm.
|
||||
|
||||
do i need any ui for the video window? i really don't think so.
|
||||
maybe let's figure out the missing cursor
|
||||
gst-launch-1.0 pipewiresrc path=90 ! videoconvert ! capsfilter caps="video/x-raw,format=RGBA" ! glupload ! gltransformation rotation-x=-15 ortho=True ! glimagesink
|
||||
gst-launch-1.0 gltestsrc ! gltransformation rotation-x=-45 ortho=True ! glimagesink
|
||||
|
||||
|
||||
** am i not getting into Create Session? after the Start?
|
||||
https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.ScreenCast.html
|
||||
(also note that here are cursor options)
|
||||
|
||||
** ok, let's try writing this in java then
|
||||
|
|
Loading…
Reference in New Issue