From fbc65309c609ff1f2362259e1125108208781502 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/31] 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
|