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