new/yocto/meta-rockchip/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.20/0009-waylandsink-Support-setting-toplevel-window-position.patch
2025-05-10 21:58:58 +08:00

205 lines
7.5 KiB
Diff

From 26f367d760afdf598f62d205da5c825ee48a727d Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
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 <jeffy.chen@rock-chips.com>
---
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