From 26f367d760afdf598f62d205da5c825ee48a727d Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Mon, 15 Jun 2020 10:11:42 +0800 Subject: [PATCH 09/33] waylandsink: Support setting toplevel window position Needs hacked wayland server, tested with: waylandsink render-rectangle="<100,200,300,400>" Signed-off-by: Jeffy Chen --- ext/wayland/gstwaylandsink.c | 32 ++++++++++++++++++++------------ ext/wayland/gstwaylandsink.h | 1 + ext/wayland/wlwindow.c | 29 ++++++++++++++++++++++------- ext/wayland/wlwindow.h | 5 +++-- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c index 9e55e4f..6647123 100644 --- a/ext/wayland/gstwaylandsink.c +++ b/ext/wayland/gstwaylandsink.c @@ -63,7 +63,8 @@ enum { PROP_0, PROP_DISPLAY, - PROP_FULLSCREEN + PROP_FULLSCREEN, + PROP_LAST }; GST_DEBUG_CATEGORY (gstwayland_debug); @@ -212,6 +213,8 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) "Whether the surface should be made fullscreen ", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_video_overlay_install_properties (gobject_class, PROP_LAST); + gst_type_mark_as_plugin_api (GST_TYPE_WAYLAND_VIDEO, 0); } @@ -275,7 +278,8 @@ gst_wayland_sink_set_property (GObject * object, GST_OBJECT_UNLOCK (sink); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -721,7 +725,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) if (!sink->window) { /* if we were not provided a window, create one ourselves */ sink->window = gst_wl_window_new_toplevel (sink->display, - &sink->video_info, sink->fullscreen, &sink->render_lock); + &sink->video_info, sink->fullscreen, &sink->render_lock, + &sink->render_rectangle); g_signal_connect_object (sink->window, "closed", G_CALLBACK (on_window_closed), sink, 0); } @@ -994,16 +999,19 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay, g_return_if_fail (sink != NULL); g_mutex_lock (&sink->render_lock); - if (!sink->window) { - g_mutex_unlock (&sink->render_lock); - GST_WARNING_OBJECT (sink, - "set_render_rectangle called without window, ignoring"); - return; - } - GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d", - x, y, w, h); - gst_wl_window_set_render_rectangle (sink->window, x, y, w, h); + if (sink->window) { + GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d", + x, y, w, h); + gst_wl_window_set_render_rectangle (sink->window, x, y, w, h, TRUE); + } else { + GST_DEBUG_OBJECT (sink, "caching window geometry (%d, %d) %d x %d", + x, y, w, h); + sink->render_rectangle.x = x; + sink->render_rectangle.y = y; + sink->render_rectangle.w = w; + sink->render_rectangle.h = h; + } g_mutex_unlock (&sink->render_lock); } diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h index 1c5fb07..9872c29 100644 --- a/ext/wayland/gstwaylandsink.h +++ b/ext/wayland/gstwaylandsink.h @@ -69,6 +69,7 @@ struct _GstWaylandSink gboolean redraw_pending; GMutex render_lock; GstBuffer *last_buffer; + GstVideoRectangle render_rectangle; struct wl_callback *callback; }; diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c index 57b5491..7814cb8 100644 --- a/ext/wayland/wlwindow.c +++ b/ext/wayland/wlwindow.c @@ -79,7 +79,7 @@ handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, if (width <= 0 || height <= 0) return; - gst_wl_window_set_render_rectangle (window, 0, 0, width, height); + gst_wl_window_set_render_rectangle (window, 0, 0, width, height, FALSE); } static const struct xdg_toplevel_listener xdg_toplevel_listener = { @@ -123,7 +123,7 @@ handle_configure (void *data, struct wl_shell_surface *wl_shell_surface, if (width == 0 || height == 0) return; - gst_wl_window_set_render_rectangle (window, 0, 0, width, height); + gst_wl_window_set_render_rectangle (window, 0, 0, width, height, FALSE); } static void @@ -256,7 +256,8 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen) GstWlWindow * gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, - gboolean fullscreen, GMutex * render_lock) + gboolean fullscreen, GMutex * render_lock, + GstVideoRectangle * render_rectangle) { GstWlWindow *window; @@ -325,12 +326,22 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, } /* render_rectangle is already set via toplevel_configure in - * xdg_shell fullscreen mode */ - if (!(display->xdg_wm_base && fullscreen)) { + * fullscreen mode */ + if (fullscreen) + return window; + + if (render_rectangle->w || render_rectangle->h) { + /* apply cached position and size */ + GST_DEBUG ("Applying window position (%d, %d)", + render_rectangle->x, render_rectangle->y); + gst_wl_window_set_render_rectangle (window, render_rectangle->x, + render_rectangle->y, render_rectangle->w, render_rectangle->h, TRUE); + } else { /* set the initial size to be the same as the reported video size */ gint width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); - gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); + gst_wl_window_set_render_rectangle (window, 0, 0, + width, info->height, FALSE); } return window; @@ -546,7 +557,7 @@ gst_wl_window_update_borders (GstWlWindow * window) void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, - gint w, gint h) + gint w, gint h, gboolean with_position) { g_return_if_fail (window != NULL); @@ -559,6 +570,10 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, window->render_rectangle.w = w; window->render_rectangle.h = h; + /* try to position the xdg surface with hacked wayland server API */ + if (with_position && window->xdg_surface) + xdg_surface_set_window_geometry (window->xdg_surface, x, y, 0, 0); + /* position the area inside the parent - needs a parent commit to apply */ if (window->area_subsurface) wl_subsurface_set_position (window->area_subsurface, x, y); diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h index 303c336..ba61d7a 100644 --- a/ext/wayland/wlwindow.h +++ b/ext/wayland/wlwindow.h @@ -83,7 +83,8 @@ GType gst_wl_window_get_type (void); void gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen); GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, - const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock); + const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock, + GstVideoRectangle * render_rectangle); GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, struct wl_surface * parent, GMutex * render_lock); @@ -94,7 +95,7 @@ gboolean gst_wl_window_is_toplevel (GstWlWindow *window); void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info); void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, - gint w, gint h); + gint w, gint h, gboolean with_position); G_END_DECLS -- 2.20.1