1From e41dc6584d0abbb7b61ab132625e96d9b1d1cd8f Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Mon, 15 Jun 2020 10:11:42 +0800 4Subject: [PATCH 09/43] waylandsink: Support setting toplevel window position 5 6Needs hacked wayland server, tested with: 7 waylandsink render-rectangle="<100,200,300,400>" 8 9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 10--- 11 ext/gtk/gstgtkwaylandsink.c | 6 +++--- 12 ext/wayland/gstwaylandsink.c | 27 ++++++++++++++++----------- 13 ext/wayland/gstwaylandsink.h | 2 ++ 14 gst-libs/gst/wayland/gstwlwindow.c | 26 ++++++++++++++++++++------ 15 gst-libs/gst/wayland/gstwlwindow.h | 5 +++-- 16 5 files changed, 44 insertions(+), 22 deletions(-) 17 18diff --git a/ext/gtk/gstgtkwaylandsink.c b/ext/gtk/gstgtkwaylandsink.c 19index e4dd06e..9030982 100644 20--- a/ext/gtk/gstgtkwaylandsink.c 21+++ b/ext/gtk/gstgtkwaylandsink.c 22@@ -254,7 +254,7 @@ widget_size_allocate_cb (GtkWidget * widget, GtkAllocation * allocation, 23 GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 24 allocation->x, allocation->y, allocation->width, allocation->height); 25 gst_wl_window_set_render_rectangle (priv->wl_window, allocation->x, 26- allocation->y, allocation->width, allocation->height); 27+ allocation->y, allocation->width, allocation->height, FALSE); 28 29 g_mutex_unlock (&priv->render_lock); 30 31@@ -425,7 +425,7 @@ scrollable_window_adjustment_changed_cb (GtkAdjustment * adjustment, 32 gtk_widget_get_allocation (priv->gtk_widget, &allocation); 33 calculate_adjustment (priv->gtk_widget, &allocation); 34 gst_wl_window_set_render_rectangle (priv->wl_window, allocation.x, 35- allocation.y, allocation.width, allocation.height); 36+ allocation.y, allocation.width, allocation.height, FALSE); 37 38 return FALSE; 39 } 40@@ -481,7 +481,7 @@ setup_wl_window (GstGtkWaylandSink * self) 41 gtk_widget_get_allocation (priv->gtk_widget, &allocation); 42 calculate_adjustment (priv->gtk_widget, &allocation); 43 gst_wl_window_set_render_rectangle (priv->wl_window, allocation.x, 44- allocation.y, allocation.width, allocation.height); 45+ allocation.y, allocation.width, allocation.height, FALSE); 46 47 /* Make subsurfaces syncronous during resizes. 48 * Unfortunately GTK/GDK does not provide easier to use signals. 49diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c 50index 5d2721c..5ee0b9f 100644 51--- a/ext/wayland/gstwaylandsink.c 52+++ b/ext/wayland/gstwaylandsink.c 53@@ -294,7 +294,8 @@ gst_wayland_sink_set_property (GObject * object, 54 FALSE); 55 break; 56 default: 57- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 58+ if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) 59+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 60 break; 61 } 62 } 63@@ -764,7 +765,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 64 if (!self->window) { 65 /* if we were not provided a window, create one ourselves */ 66 self->window = gst_wl_window_new_toplevel (self->display, 67- &self->video_info, self->fullscreen, &self->render_lock); 68+ &self->video_info, self->fullscreen, &self->render_lock, 69+ &self->render_rectangle); 70 g_signal_connect_object (self->window, "closed", 71 G_CALLBACK (on_window_closed), self, 0); 72 gst_wl_window_set_rotate_method (self->window, 73@@ -1047,16 +1049,19 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay, 74 g_return_if_fail (self != NULL); 75 76 g_mutex_lock (&self->render_lock); 77- if (!self->window) { 78- g_mutex_unlock (&self->render_lock); 79- GST_WARNING_OBJECT (self, 80- "set_render_rectangle called without window, ignoring"); 81- return; 82- } 83 84- GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 85- x, y, w, h); 86- gst_wl_window_set_render_rectangle (self->window, x, y, w, h); 87+ if (self->window) { 88+ GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 89+ x, y, w, h); 90+ gst_wl_window_set_render_rectangle (self->window, x, y, w, h, TRUE); 91+ } else { 92+ GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 93+ x, y, w, h); 94+ self->render_rectangle.x = x; 95+ self->render_rectangle.y = y; 96+ self->render_rectangle.w = w; 97+ self->render_rectangle.h = h; 98+ } 99 100 g_mutex_unlock (&self->render_lock); 101 } 102diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h 103index 46b5faa..d4c3764 100644 104--- a/ext/wayland/gstwaylandsink.h 105+++ b/ext/wayland/gstwaylandsink.h 106@@ -70,6 +70,8 @@ struct _GstWaylandSink 107 GstVideoOrientationMethod current_rotate_method; 108 109 struct wl_callback *callback; 110+ 111+ GstVideoRectangle render_rectangle; 112 }; 113 114 struct _GstWaylandSinkClass 115diff --git a/gst-libs/gst/wayland/gstwlwindow.c b/gst-libs/gst/wayland/gstwlwindow.c 116index e7c429c..7080c8c 100644 117--- a/gst-libs/gst/wayland/gstwlwindow.c 118+++ b/gst-libs/gst/wayland/gstwlwindow.c 119@@ -122,7 +122,7 @@ handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, 120 if (width <= 0 || height <= 0) 121 return; 122 123- gst_wl_window_set_render_rectangle (self, 0, 0, width, height); 124+ gst_wl_window_set_render_rectangle (self, 0, 0, width, height, FALSE); 125 } 126 127 static const struct xdg_toplevel_listener xdg_toplevel_listener = { 128@@ -268,7 +268,8 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * self, gboolean fullscreen) 129 130 GstWlWindow * 131 gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 132- gboolean fullscreen, GMutex * render_lock) 133+ gboolean fullscreen, GMutex * render_lock, 134+ GstVideoRectangle * render_rectangle) 135 { 136 GstWlWindow *self; 137 GstWlWindowPrivate *priv; 138@@ -329,12 +330,21 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 139 } 140 141 /* render_rectangle is already set via toplevel_configure in 142- * xdg_shell fullscreen mode */ 143- if (!(xdg_wm_base && fullscreen)) { 144+ * fullscreen mode */ 145+ if (fullscreen) 146+ return self; 147+ 148+ if (render_rectangle->w || render_rectangle->h) { 149+ /* apply cached position and size */ 150+ GST_DEBUG ("Applying window position (%d, %d)", 151+ render_rectangle->x, render_rectangle->y); 152+ gst_wl_window_set_render_rectangle (self, render_rectangle->x, 153+ render_rectangle->y, render_rectangle->w, render_rectangle->h, TRUE); 154+ } else { 155 /* set the initial size to be the same as the reported video size */ 156 gint width = 157 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); 158- gst_wl_window_set_render_rectangle (self, 0, 0, width, info->height); 159+ gst_wl_window_set_render_rectangle (self, 0, 0, width, info->height, FALSE); 160 } 161 162 return self; 163@@ -623,7 +633,7 @@ gst_wl_window_update_geometry (GstWlWindow * self) 164 165 void 166 gst_wl_window_set_render_rectangle (GstWlWindow * self, gint x, gint y, 167- gint w, gint h) 168+ gint w, gint h, gboolean with_position) 169 { 170 GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self); 171 172@@ -637,6 +647,10 @@ gst_wl_window_set_render_rectangle (GstWlWindow * self, gint x, gint y, 173 priv->render_rectangle.h = h; 174 175 gst_wl_window_update_geometry (self); 176+ 177+ /* try to position the xdg surface with hacked wayland server API */ 178+ if (with_position && priv->xdg_surface) 179+ xdg_surface_set_window_geometry (priv->xdg_surface, x, y, 0, 0); 180 } 181 182 const GstVideoRectangle * 183diff --git a/gst-libs/gst/wayland/gstwlwindow.h b/gst-libs/gst/wayland/gstwlwindow.h 184index 06c4001..2bbd643 100644 185--- a/gst-libs/gst/wayland/gstwlwindow.h 186+++ b/gst-libs/gst/wayland/gstwlwindow.h 187@@ -39,7 +39,8 @@ void gst_wl_window_ensure_fullscreen (GstWlWindow * self, 188 189 GST_WL_API 190 GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, 191- const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock); 192+ const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock, 193+ GstVideoRectangle * render_rectangle); 194 195 GST_WL_API 196 GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, 197@@ -63,7 +64,7 @@ void gst_wl_window_render (GstWlWindow * self, GstWlBuffer * buffer, 198 199 GST_WL_API 200 void gst_wl_window_set_render_rectangle (GstWlWindow * self, gint x, gint y, 201- gint w, gint h); 202+ gint w, gint h, gboolean with_position); 203 204 GST_WL_API 205 const GstVideoRectangle *gst_wl_window_get_render_rectangle (GstWlWindow * self); 206-- 2072.20.1 208 209