<div dir="ltr">Did you call set_window_handle(wl_handle) when on_sync_message triggered?<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 30 Apr 2024 at 03:04, Gregoire Gentil <<a href="mailto:gregoire@gentil.com">gregoire@gentil.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello Max,<br>
<br>
Based on your python code, I have added:<br>
<br>
GdkDisplay *display = gdk_display_get_default();<br>
struct wl_display *wl_handle = gdk_wayland_display_get_wl_display(display);<br>
GstContext *context = <br>
gst_context_new("GstWaylandDisplayHandleContextType", True);<br>
GstStructure *structure = gst_context_writable_structure(context);<br>
gst_structure_set(structure, "display", G_TYPE_POINTER, wl_handle, NULL);<br>
gst_element_set_context(data.video_sink, context);<br>
<br>
That's the only difference I see. But I'm still receiving the error message:<br>
Error received from element waylandsink0: Application did not provide a <br>
wayland display handle<br>
Debugging information: ../ext/wayland/gstwaylandsink.c(1102): <br>
gst_wayland_sink_set_window_handle (): <br>
/GstPipeline:pipeline0/GstWaylandSink:waylandsink0:<br>
waylandsink cannot use an externally-supplied surface without an <br>
externally-supplied display handle. Consider providing a display handle <br>
from your application with GstContext<br>
<br>
Any idea what I'm missing else?<br>
<br>
Grégoire<br>
<br>
<br>
On 4/28/24 23:53, Max Weng wrote:<br>
> I forgot to mention that handling window operations in Wayland is a bit <br>
> different from X11.there is a c example for wayland gtk in the gstreamer <br>
> repo, but I can not find it now.<br>
> here is my python code, shall be easy convert to C++<br>
> <br>
> libgdk = ctypes.CDLL(find_library("libgdk-3"))<br>
> libgst = ctypes.CDLL(find_library("libgstreamer-1.0"))<br>
> <br>
> def get_wayland_window_handle(widget):<br>
> return libgdk.gdk_wayland_window_get_wl_surface(hash(widget.get_window()))<br>
> <br>
> <br>
> def get_default_wayland_display_context():<br>
> wl_display = libgdk.gdk_wayland_display_get_wl_display(<br>
> hash(Gdk.Display.get_default())<br>
> )<br>
> context = Gst.Context.new("GstWaylandDisplayHandleContextType", True)<br>
> structure = libgst.gst_context_writable_structure(hash(context))<br>
> libgst.gst_structure_set(<br>
> structure,<br>
> ctypes.c_char_p("display".encode()),<br>
> hash(GObject.TYPE_POINTER),<br>
> wl_display,<br>
> 0,<br>
> )<br>
> return context<br>
> <br>
> def set_window(self):<br>
> if self.window is not None:<br>
> # window already set, when refresh/update, do not create new window<br>
> return<br>
> window = Gtk.Window()<br>
> window.set_title("Video Streaming")<br>
> self.window = window<br>
> self.window.connect("destroy", Gtk.main_quit, "WM destroy")<br>
> window.set_default_size(1200, 800)<br>
> self.window.show_all()<br>
> self.window.fullscreen()<br>
> <br>
> def set_stream(self, url):<br>
> command = f"rtspsrc name=rtspsrc location={url}protocols=tcp latency=10 <br>
> max-rtcp-rtp-time-diff=10 ! errorignore ! rtph265depay name=depay ! <br>
> h265parse ! avdec_h265 name=avdec ! videoconvert ! video/x-raw, <br>
> format=RGBA ! waylandsink name=sink"<br>
> <a href="http://self.logger.info" rel="noreferrer" target="_blank">self.logger.info</a>(f"command {command}")<br>
> self.pipeline = Gst.parse_launch(command)<br>
> <br>
> bus = self.pipeline.get_bus()<br>
> bus.add_signal_watch()<br>
> bus.connect("message", self.on_message)<br>
> <br>
> if self.drawing_area is not None:<br>
> self.window.remove(self.drawing_area)<br>
> self.drawing_area = Gtk.DrawingArea()<br>
> # set background color<br>
> self.drawing_area.modify_bg(<br>
> Gtk.StateType.NORMAL, Gdk.color_parse(self.background_color_str)<br>
> )<br>
> <br>
> glsink = self.pipeline.get_by_name("sink")<br>
> <br>
> # Wayland display context wrapped as a GStreamer context.<br>
> wl_display = get_default_wayland_display_context()<br>
> glsink.set_context(wl_display)<br>
> <br>
> self.window.connect("delete-event", Gtk.main_quit)<br>
> self.window.add(self.drawing_area)<br>
> self.drawing_area.realize()<br>
> <br>
> self.window.show_all()<br>
> <br>
> bus.enable_sync_message_emission()<br>
> bus.connect("sync-message", self.on_sync_message)<br>
> <br>
> def on_sync_message(self, bus: Gst.Bus, message: Gst.Message):<br>
> if message.get_structure() is None:<br>
> return 1<br>
> <br>
> if message.get_structure().get_name() == "prepare-window-handle":<br>
> <a href="http://self.logger.info" rel="noreferrer" target="_blank">self.logger.info</a>(f"[on_sync_message] {message.get_structure().get_name()}")<br>
> sink = message.src<br>
> <a href="http://self.logger.info" rel="noreferrer" target="_blank">self.logger.info</a>(f"[on_sync_message] sink: {sink}")<br>
> <br>
> # Wayland window handle.<br>
> wl_handle = get_wayland_window_handle(self.drawing_area)<br>
> sink.set_window_handle(wl_handle)<br>
> <br>
> allocation = self.drawing_area.get_allocation()<br>
> sink.set_render_rectangle(<br>
> allocation.x, allocation.y, allocation.width, allocation.height<br>
> )<br>
> <br>
> On Mon, 29 Apr 2024 at 12:15, Gregoire Gentil <<a href="mailto:gregoire@gentil.com" target="_blank">gregoire@gentil.com</a> <br>
> <mailto:<a href="mailto:gregoire@gentil.com" target="_blank">gregoire@gentil.com</a>>> wrote:<br>
> <br>
>     Thanks for helping. Still not working.<br>
> <br>
>     I have replaced glimagesink by waylandsink. If I don't call<br>
>     "gst_video_overlay_set_window_handle", the video appears in the<br>
>     back. So<br>
>     at least, waylandsink is working. But note that the video is appearing<br>
>     without being part of any window at all.<br>
> <br>
>     If I call "gst_video_overlay_set_window_handle", the video doesn't<br>
>     appear and doesn't play. I also receive the following message:<br>
> <br>
>     waylandsink cannot use an externally-supplied surface without an<br>
>     externally-supplied display handle. Consider providing a display handle<br>
>     from your application with GstContext<br>
> <br>
>     Am I missing another API call?<br>
> <br>
>     Grégoire<br>
> <br>
> <br>
>     On 4/28/24 20:28, Max Weng wrote:<br>
>      > I understand your situation better now. :) I've noticed that the<br>
>     video<br>
>      > indeed appears in a separate window with other sinks as well. It<br>
>     seems<br>
>      > that in my experience, only |waylandsink|consistently integrates<br>
>      > directly into the GTK window without issues.<br>
>      ><br>
>      > On Mon, 29 Apr 2024 at 10:51, Gregoire Gentil<br>
>     <<a href="mailto:gregoire@gentil.com" target="_blank">gregoire@gentil.com</a> <mailto:<a href="mailto:gregoire@gentil.com" target="_blank">gregoire@gentil.com</a>><br>
>      > <mailto:<a href="mailto:gregoire@gentil.com" target="_blank">gregoire@gentil.com</a> <mailto:<a href="mailto:gregoire@gentil.com" target="_blank">gregoire@gentil.com</a>>>> wrote:<br>
>      ><br>
>      >     I could have been more precise: the glimageslink pipeline<br>
>     does work and<br>
>      >     the video appears in a separated window if I don't link it to the<br>
>      >     window<br>
>      >     with the code mentioned below. What I want to do is to insert<br>
>     the video<br>
>      >     inside the gtk window.<br>
>      ><br>
>      >     Also glimagesink has the unique advantage to work on both<br>
>     wayland and<br>
>      >     non-wayland systems,<br>
>      ><br>
>      >     Grégoire<br>
>      ><br>
>      ><br>
>      ><br>
>      ><br>
>      >     On 4/28/24 19:12, Max Weng wrote:<br>
>      >      > try use waylandsink?<br>
>      >      ><br>
>      >      > this work for me "rtspsrc name=rtspsrc location={url}<br>
>     protocols=tcp<br>
>      >      > latency=10 max-rtcp-rtp-time-diff=10 ! errorignore !<br>
>     rtph265depay<br>
>      >      > name=depay ! h265parse ! avdec_h265 name=avdec !<br>
>     videoconvert !<br>
>      >      > video/x-raw, format=RGBA ! waylandsink name=sink"<br>
>      >      ><br>
>      >      > On Mon, 29 Apr 2024 at 06:18, Gregoire Gentil via<br>
>     gstreamer-devel<br>
>      >      > <<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a><br>
>     <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a>><br>
>      >     <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a><br>
>     <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a>>><br>
>      >      > <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a><br>
>     <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a>><br>
>      >     <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a><br>
>     <mailto:<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a>>>>> wrote:<br>
>      >      ><br>
>      >      >     Hello,<br>
>      >      ><br>
>      >      >     I had an application with a gtk+-3.0 window and a<br>
>     pipeline "... !<br>
>      >      >     imagesink". The video is rendered inside the gtk window.<br>
>      >      ><br>
>      >      >     I was doing:<br>
>      >      >     static void realize_cb(GtkWidget *widget, CustomData<br>
>     *data) {<br>
>      >      >     GdkWindow *window = gtk_widget_get_window(widget);<br>
>      >      >     data->window_handle = GDK_WINDOW_XID(window);<br>
>      >      ><br>
>      >      >     and then:<br>
>      >      ><br>
>      >      >     static GstBusSyncReply bus_sync_handler(GstBus * bus,<br>
>      >     GstMessage *<br>
>      >      >     message, CustomData *data) {<br>
>      >      ><br>
>      >     <br>
>       gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(data->video_sink),<br>
>      >      >     data->window_handle);<br>
>      >      ><br>
>      >      >     Everything was working fine. I want now to support wayland<br>
>      >     system.<br>
>      >      ><br>
>      >      >     Pipeline becomes: "... ! glimagesink".<br>
>      >      ><br>
>      >      >     in the realize_cb function, I have now:<br>
>      >      >     GdkWindow *window = gtk_widget_get_window(widget);<br>
>      >      >     data->window_handle =<br>
>      >      >     (guintptr)gdk_wayland_window_get_wl_surface(window);<br>
>      >      ><br>
>      >      ><br>
>      >      >     At run-time, I'm getting hundreds of:<br>
>      >      >     "GStreamer-GL-CRITICAL **: 14:06:48.263: Failed to<br>
>     flush Wayland<br>
>      >      >     connection"<br>
>      >      ><br>
>      >      >     What am I doing wrong? Many thanks in advance for any<br>
>     hint,<br>
>      >      ><br>
>      >      >     Grégoire<br>
>      >      ><br>
>      ><br>
> <br>
</blockquote></div>