After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 726193 - waylandsink: subsurface & scaling support, plus many other improvements
waylandsink: subsurface & scaling support, plus many other improvements
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
git master
Other Linux
: Normal enhancement
: 1.3.3
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks: 727818 732804
 
 
Reported: 2014-03-12 18:09 UTC by George Kiagiadakis
Modified: 2014-07-06 21:52 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description George Kiagiadakis 2014-03-12 18:09:48 UTC
I've been working recently on improving waylandsink in various aspects. At the moment I have reached to a point where this work is mergeable, so I am submitting it here for comments. Of course, there is still a lot of room for improvement.

The branch is available at:
http://cgit.collabora.com/git/user/gkiagia/gst-plugins-bad.git/log/?h=waylandsink

Some details now about what changes are included in this branch:

* Implemented GstVideoOverlay and all the needed functionality to allow waylandsink to draw into an externally supplied wl_surface. The needed functionality includes:
** Processing display events properly in a dedicated thread
** The GstWaylandVideo interface, which allows the application to resize the embedded video surface
* Implemented support for the wl_scaler extension, which allows buffer scaling in the compositor/hardware
* Support all the video buffer formats that are supported by the compositor/hardware
* Various fixes for the wayland buffer pool
* Many code cleanups, improvements & some refactoring

Testing of this branch has been done with:
* Standard gst-launch (top-level window)

* One demo I wrote with weston's toytoolkit, available at:
http://cgit.collabora.com/git/user/gkiagia/weston.git/log/?h=gst-wayland

* One hacky demo I wrote with gtk, which however does not work well and needs effort from the gtk side to become usable:
http://cgit.collabora.com/git/user/gkiagia/gst-wayland-gtk-demo.git/
Comment 1 Daniel Stone 2014-04-02 11:45:39 UTC
For what it's worth, I've reviewed this from the Wayland side of things, and it looks fine to me.
Comment 2 Julien Isorce 2014-04-02 17:30:45 UTC
Hi George, well done!

Just trying to catch-up, do you have the log of the discussion somewhere that leads to this GstWaylandVideo interface ? :)

As I have not followed those discussions I wonder if gst_video_overlay_set_render_rectangle could have been used instead of a new gst_wayland_video_set_surface_size ?

Also why is it not possible to manage the _pause_rendering / _resume_rendering in the waylandsink directly ?
I'm not against, I just wonder :). Also this GstWaylandVideo could be useful in glimagesink for our wayland backend.

I think one commit for the lib, and 1 (or 2 if you have initial cleanup) commit for ext/wayland would be fine to merge it.

Finally I asked gtk maintainer if it could be possible to handle most of the subsurface code of gtk itself when using "gdk_window_ensure_native (gdkwindow)".
Could save some lines here http://cgit.collabora.com/git/user/gkiagia/gst-wayland-gtk-demo.git/tree/main.c and avoid to duplicate same code over and over on each application etc...
They said it sounds useful. So at this point we should just open a bug and ask them to implement the prototypes we need. We can discuss that on IRC.

Having this in gtk, would it allow to remove those 2 _pause_rendering / _resume_rendering functions ?

Cheers!
Comment 3 George Kiagiadakis 2014-04-04 14:22:42 UTC
(In reply to comment #2)
> Hi George, well done!
> 
> Just trying to catch-up, do you have the log of the discussion somewhere that
> leads to this GstWaylandVideo interface ? :)

I don't think there was a discussion about that. There was only an irc discussion with Daniel about the requirements of the sink for resizing and after that I came up with this interface.

> As I have not followed those discussions I wonder if
> gst_video_overlay_set_render_rectangle could have been used instead of a new
> gst_wayland_video_set_surface_size ?
> 
> Also why is it not possible to manage the _pause_rendering / _resume_rendering
> in the waylandsink directly ?
> I'm not against, I just wonder :). Also this GstWaylandVideo could be useful in
> glimagesink for our wayland backend.

I'm glad that you raised this topic.

gst_video_overlay_set_render_rectangle can indeed be used instead of gst_wayland_video_set_surface_size. The reason I didn't do that is because the semantics are slightly different I think. set_render_rectangle is to specify a sub-region inside the given surface, while in our case we want to draw in the whole given surface, the only problem being that surfaces in wayland have no specific size. So we need a method to set that size and complement the lack of such an api in wayland directly. This is no big deal, though, especially if we document it. But for the moment we need GstWaylandVideo anyway (see below), so that's why I have kept it like this.

_pause_rendering and _resume_rendering now are another problem. These functions intend to solve the problem that we need to synchronize the main drawing thread with waylandsink's drawing thread when a resizing happens.

In general, wayland subsurfaces have an API for synchronization, wl_subsurface_set_(de)sync (afair). When a subsurface is set in sync mode, all its redrawing operations are queued to happen when the parent (sub)surface is redrawn. This is handy here and of course we expect toolkits to use it, but it's not enough. When the parent (sub)surface is redrawn, we cannot guarantee that the last drawn frame of the gstreamer subsurface has the correct geometry. This is why _resume_rendering exists and as you can see, it waits for a new frame to be drawn (which will be drawn with the new geometry). If we don't do that, resizing has quite visible artifacts.

Now before I added the wl_scaler support, _pause_rendering was also quite useful, but I've started to think that it perhaps can go away now. The reason it was added in the first place was to avoid rendering anything while the internal state of the sink was being changed, as a resize would trigger a caps & pool change, which would have to be negotiated before continuing. It also still serves as an optimization in order to avoid sending buffers to wayland that will never be shown, as the subsurface is in sync mode and it will be redrawn in _resume_rendering before the end of the resize operation.

So, perhaps if we drop _pause_rendering and its performance optimization and replace _set_surface_size with _set_render_rectangle, then maybe we can also replace _resume_rendering with gst_video_overlay_expose, but again the semantics are different imho. It's doable if we document it, though.

> Finally I asked gtk maintainer if it could be possible to handle most of the
> subsurface code of gtk itself when using "gdk_window_ensure_native
> (gdkwindow)".
> Could save some lines here
> http://cgit.collabora.com/git/user/gkiagia/gst-wayland-gtk-demo.git/tree/main.c
> and avoid to duplicate same code over and over on each application etc...
> They said it sounds useful. So at this point we should just open a bug and ask
> them to implement the prototypes we need. We can discuss that on IRC.

Yes, gtk definitely needs to implement that stuff. And also fix a lot of bugs...
Comment 4 Julien Isorce 2014-04-08 23:22:13 UTC
Also about GstWaylandWindowHandle http://cgit.collabora.com/git/user/gkiagia/gst-plugins-bad.git/tree/gst-libs/gst/wayland/wayland.h?h=waylandsink#n37 there is a solution to remove it.


struct wl_display *display = gdk_wayland_display_get_wl_display (gdk_window_get_display (gtk_widget_get_window (widget)));
GstContext *context = gst_context_new_display_handle ((guintptr) display, FALSE);

In gstgl we use gst_element_set_context (GST_ELEMENT (GST_MESSAGE_SRC (message)), context); from the application to pass the wl_display

The waylandsink should call msg = gst_message_new_need_context (GST_OBJECT_CAST (waylandsink), GST_DISPLAY_HANDLE_CONTEXT_TYPE); 

See https://bug709747.bugzilla-attachments.gnome.org/attachment.cgi?id=266903 the whole commit is wrong but just about how to use GstContext. There are other examples in gstg (http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/gst-libs/gst/gl/gstglfilter.c#n221)l and eglglessink.

That would be great to pass the wl_display this way because we already do this way in gstgl. In order to uniform.

Also this way you could just pass directly the wl_surface handle to set_window_handle, and set the siwe using the function you introduced gst_wayland_sink_set_surface_size.

The it will remain gst_wayland_video_set_surface_size, pause / resume in libgstwayland.

As we discuss on IRC it's ok to add this in the mean time gtk has no subsurface support and also to have more control (to optimize also). Also we should not rely on if an UI tool kit has the wl_subsurface support or not. So we will still need those 3 functions.

Later we could move those 3 functions to GstVideoOverlay.
Comment 5 Julien Isorce 2014-04-15 14:18:25 UTC
Before I forget there were also 4 small things I noticed:
- G_BEGIN_DECLS/ END are missing in ext/wayland/wldisplay.h and wlvideoformat.h
- if wrong location in filesrc, "warning : gst_wl_window_is_top_level : assertion window != NULL failed", gkiagia: "missing check, in case the window does not exist when the sink stops"
- scaler-client-protocol.h is not generated though present in Makefile.am
- crash when its bufferpool get negotiated with upstream, it seems the pool get stopped twice
Comment 6 George Kiagiadakis 2014-05-22 07:23:44 UTC
I have fixed most of the mentioned issues:
* Use GstContext for the display handle
* G_BEGIN/END_DECLS
* assertion failure if the window does not exist when the sink stops
* scaler-client-protocol.h not being generated

Plus I have rebased on top of master, fixed a g-i generation issue and updated wl_scaler to version 2.

I cannot reproduce the mentioned crash in the buffer pool, but afair from my discussion with Julien on irc at the time of writing of his comments, the backtrace was showing a possible bug in GStreamer core (the buffer pool was being stopped twice, which should not be possible to happen normally)
Comment 7 George Kiagiadakis 2014-06-10 11:26:29 UTC
And with some more improvements last week, I fixed some locking issues and also simplified the GstWaylandVideo interface as it has been discussed in the past:

* set_surface_size is gone & replaced by gst_video_overlay_set_render_rectangle

The semantics also changed a bit there. The subsurface is now being created inside waylandsink, so the parent application only needs to set its top-level surface as the window handle and use set_render_rectangle to specify the sub-area of the window where the video should appear.

* pause_rendering is now begin_geometry_change
* resume_rendering is now end_geometry_change

The implementation of these methods has also changed to just do wl_subsurface_set_sync/desync and resizing is implemented by directly committing a wl_viewport.set_destination change inside set_render_rectangle (instead of waiting for the next redraw in the streaming thread). This way, resizing is independent of rendering and the API is faster and simpler. This is only possible because of wl_scaler version 2, though, and tbh, there is a bug in weston that prevents it from fully working as expected (so resizing is not really smooth unless you also call gst_video_overlay_expose() after set_render_rectangle() and there are some complications there, but this needs fixing in weston)

The nice part about these changes is that waylandsink can now be used properly with gtk without ugly hacks in the client and it works pretty well. The sample code has also been updated:

http://cgit.collabora.com/git/user/gkiagia/gst-wayland-gtk-demo.git/tree/main.c
Comment 8 Julien Isorce 2014-06-13 12:20:09 UTC
Great!

Are the (4 or 5) gstwaylandsink patches submitted recently obsoletes ?

I have no other remarks but maybe the contributors mentioned in the copyright have ? Otherwise please push.
Comment 9 George Kiagiadakis 2014-06-13 14:19:17 UTC
(In reply to comment #8)
> Great!
> 
> Are the (4 or 5) gstwaylandsink patches submitted recently obsoletes ?

If you mean the patches on bugzilla, yes, they are obsolete.

> I have no other remarks but maybe the contributors mentioned in the copyright
> have ? Otherwise please push.

Thanks! :)
Comment 10 George Kiagiadakis 2014-06-17 12:16:27 UTC
Merged in master. eb8ab3732e0abb0e364b99037819b8ce1b337b88 up to 0badc1f5fb3d5669d3ef9bcc5a586f80572360f5

Arnaud Vrac (1):
      wayland: install .pc file

George Kiagiadakis (66):
      waylandsink: tidy up the header files
      waylandsink: process display events in a separate thread
      waylandsink: remove unused variables
      waylandsink: Use XDG_RUNTIME_DIR instead of /tmp for the shm file
      waylandsink: move struct shm_pool and its related functions to waylandpool.c
      waylandsink/waylandpool: move code around for better readability
      waylandsink: split video format related functions out to a separate file
      waylandsink/waylandpool: refactor code
      waylandsink/waylandpool: find the video format from the GstVideoInfo instead of accessing the sink
      waylandsink/waylandpool: improve debug message
      waylandsink: remove callback and redraw_pending variables from the window structure
      waylandsink: split window-related code out to a new GstWlWindow class
      waylandsink: cleanup header includes
      waylandsink: apply the same debug category to all the subobjects
      waylandsink: remove the useless wayland_lock
      waylandsink: access sink->pool in a more atomic fashion
      waylandsink: make the display property useful
      waylandsink/waylandpool: ref the display instead of the sink to avoid cyclic references
      waylandsink: unref the buffer pool
      waylandsink/wlvideoformat: add mappings for many common formats
      waylandsink: handle the list of supported formats properly
      wayland: Add new gst-wayland library containing a new GstWaylandVideo interface
      waylandsink: implement with stubs the GstWaylandVideo & GstVideoOverlay interfaces
      waylandsink: implement the GstVideoOverlay & GstWaylandVideo interfaces
      waylandsink/waylandpool: unlink mmaped shm files so that they don't remain on the file system
      waylandsink/waylandpool: call the start/stop methods of the parent class
      waylandsink/waylandpool: remove useless munmap call
      waylandsink: Handle wl_buffer::release and don't reuse buffers that are not released
      waylandsink: Wait for the frame_cb to redraw and drop frames meanwhile
      waylandsink: Set external surfaces and their child objects to use our own event queue
      waylandsink: Build bindings for the unstable wl_scaler spec
      waylandsink: Use wl_scaler/wl_viewport to scale the surface in the compositor/hardware
      waylandsink: Implement expose() and handle resizing properly in non-PLAYING states
      waylandsink: Use a boolean in combination with render_cond to comply with GCond's usage documentation
      waylandsink: increase debug messages
      waylandsink/wlwindow: reuse code between the two constructors
      waylandsink: set an empty input region on the video surface
      waylandsink: fix crash in case there is no pool because of a caps negotiation error
      waylandsink: Support all video formats supported by the display
      waylandsink: create/destroy the display when entering/leaving the READY state instead of PAUSED
      waylandsink/wldisplay: bind to the latest available wl_compositor version
      waylandsink: Add myself to the authors list
      waylandsink: remove unused functions
      waylandsink/Makefile.am: Fix scaler-client-protocol.h generation
      wayland/Makefile.am: link with gstvideo to avoid introspection errors
      waylandsink: Update wl_scaler to version 2
      waylandsink: fix assertion failure when stopping immediately after starting, without displaying anything
      waylandsink: add G_BEGIN/END_DECLS on all headers for consistency
      waylandsink: drop width/height arguments from gst_wl_window_new_from_surface()
      waylandsink: get the external display handle using GstContext
      wayland: add public API for creating & using the display handle GstContext
      waylandsink: create and maintain the subsurface inside the sink
      wayland: remove gst_wayland_video_set_surface_size()
      waylandsink: cleanup GstWlWindow a bit after the overlaying semantics change
      waylandsink: move surface resizing logic to the GstWlWindow and make it be called from the main thread
      waylandsink: Replace the OBJECT_LOCK with a private render_lock to lock render operations
      waylandsink: remove the OBJECT_LOCK from set_caps()
      waylandsink: protect access to the display with a new display_lock
      waylandsink: protect access to properties with the OBJECT_LOCK
      waylandsink: remove the manual synchronization from pause/resume_rendering and use subsurface sync/desync
      waylandsink: rename pause/resume_rendering to begin/end_geometry_change and update their documentation
      waylandsink: improve the way the video size is passed to wlwindow and also improve the code for window creation
      waylandsink/wlwindow: take into account the video aspect ratio when determining the size of the surface
      waylandsink/wlwindow: do not commit a resize when it happens due to a video info change
      waylandsink: remove the buffer from the surface when going PAUSED -> READY
      waylandsink/wldisplay: verify that all the required interfaces have been found on the compositor
Comment 11 Tim-Philipp Müller 2014-07-04 13:20:10 UTC
I'm a bit unhappy how this set of commits just snuck in a new library with new application API here.

Even if it's gst-plugins-bad and not necessarily API stable, that's not how we do things.

New API and new libraries should be explicitly posted in bugzilla for review, and I understand in this case there have even been conversations that indicated that this might not be the best or final solution yet.

It's one thing if this is a helper lib for plugins, but this is application API so it's doubly unfortunate that we're now adding new API for applications that's possibly dead on arrival and deprecated before even having been released.

Can we disable the new lib for the time being and aim to sort this out in the next cycle?
Comment 12 Sebastian Dröge (slomo) 2014-07-04 13:22:33 UTC
Also see bug #732207 and bug #732280
Comment 13 Sebastian Dröge (slomo) 2014-07-04 13:24:12 UTC
IMHO we should not install the headers of the lib at all as it's not even clear that this is how toolkits are supposed to work with Wayland. This is all very experimental and not a finished design yet.

See discussion in bug #732280.
Comment 14 George Kiagiadakis 2014-07-04 16:27:17 UTC
(In reply to comment #11) 
> New API and new libraries should be explicitly posted in bugzilla for review,
> and I understand in this case there have even been conversations that indicated
> that this might not be the best or final solution yet.

Well, the purpose of this bug report was exactly that, although I admit I probably did not make it very clear. Sorry for the confusion.
 
> Can we disable the new lib for the time being and aim to sort this out in the
> next cycle?

We can, but then waylandsink can't be embedded anywhere. Unless we can disable it by default and have people build it on demand if needed.


(In reply to comment #13)
> IMHO we should not install the headers of the lib at all as it's not even clear
> that this is how toolkits are supposed to work with Wayland. This is all very
> experimental and not a finished design yet.

About the GstWaylandVideo interface, OK. Maybe we can follow Julien's advice (bug 732280 comment 3) and transform those two functions into action signals and kill the interface then.

But what about the GstContext methods that this library contains?

(from the header)
-----------------
/* The type of GstContext used to pass the wl_display pointer
 * from the application to the sink */
#define GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE "GstWaylandDisplayHandleContextType"

gboolean gst_is_wayland_display_handle_need_context_message (GstMessage * msg);
GstContext *
gst_wayland_display_handle_context_new (struct wl_display * display);
struct wl_display *
gst_wayland_display_handle_context_get_handle (GstContext * context);
------------------

This should for sure be useful as well to any element that connects to wayland (ex. glimagesink) and I don't think it should go away.
Comment 15 George Kiagiadakis 2014-07-04 16:30:09 UTC
(In reply to comment #14)
> We can, but then waylandsink can't be embedded anywhere. Unless we can disable
> it by default and have people build it on demand if needed.

Sorry, just to clarify: The GstWaylandVideo interface is optional to embed waylandsink (although recommended), but the wayland display GstContext is required.
Comment 16 Nicolas Dufresne (ndufresne) 2014-07-04 18:44:31 UTC
Maybe worth some clarity, but I think the idea is to drop the lib from the public API (that might mean dropping the feature involved) for 1.4, so nobody builds on top of it, then it can be re-introduce for 1.5, and hopefully it will be right and ready for 1.6.