1*4882a593SmuzhiyunFrom 26f367d760afdf598f62d205da5c825ee48a727d 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/33] 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/wayland/gstwaylandsink.c | 32 ++++++++++++++++++++------------ 12*4882a593Smuzhiyun ext/wayland/gstwaylandsink.h | 1 + 13*4882a593Smuzhiyun ext/wayland/wlwindow.c | 29 ++++++++++++++++++++++------- 14*4882a593Smuzhiyun ext/wayland/wlwindow.h | 5 +++-- 15*4882a593Smuzhiyun 4 files changed, 46 insertions(+), 21 deletions(-) 16*4882a593Smuzhiyun 17*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c 18*4882a593Smuzhiyunindex 9e55e4f..6647123 100644 19*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.c 20*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.c 21*4882a593Smuzhiyun@@ -63,7 +63,8 @@ enum 22*4882a593Smuzhiyun { 23*4882a593Smuzhiyun PROP_0, 24*4882a593Smuzhiyun PROP_DISPLAY, 25*4882a593Smuzhiyun- PROP_FULLSCREEN 26*4882a593Smuzhiyun+ PROP_FULLSCREEN, 27*4882a593Smuzhiyun+ PROP_LAST 28*4882a593Smuzhiyun }; 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun GST_DEBUG_CATEGORY (gstwayland_debug); 31*4882a593Smuzhiyun@@ -212,6 +213,8 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) 32*4882a593Smuzhiyun "Whether the surface should be made fullscreen ", FALSE, 33*4882a593Smuzhiyun G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun+ gst_video_overlay_install_properties (gobject_class, PROP_LAST); 36*4882a593Smuzhiyun+ 37*4882a593Smuzhiyun gst_type_mark_as_plugin_api (GST_TYPE_WAYLAND_VIDEO, 0); 38*4882a593Smuzhiyun } 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun@@ -275,7 +278,8 @@ gst_wayland_sink_set_property (GObject * object, 41*4882a593Smuzhiyun GST_OBJECT_UNLOCK (sink); 42*4882a593Smuzhiyun break; 43*4882a593Smuzhiyun default: 44*4882a593Smuzhiyun- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 45*4882a593Smuzhiyun+ if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) 46*4882a593Smuzhiyun+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 47*4882a593Smuzhiyun break; 48*4882a593Smuzhiyun } 49*4882a593Smuzhiyun } 50*4882a593Smuzhiyun@@ -721,7 +725,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 51*4882a593Smuzhiyun if (!sink->window) { 52*4882a593Smuzhiyun /* if we were not provided a window, create one ourselves */ 53*4882a593Smuzhiyun sink->window = gst_wl_window_new_toplevel (sink->display, 54*4882a593Smuzhiyun- &sink->video_info, sink->fullscreen, &sink->render_lock); 55*4882a593Smuzhiyun+ &sink->video_info, sink->fullscreen, &sink->render_lock, 56*4882a593Smuzhiyun+ &sink->render_rectangle); 57*4882a593Smuzhiyun g_signal_connect_object (sink->window, "closed", 58*4882a593Smuzhiyun G_CALLBACK (on_window_closed), sink, 0); 59*4882a593Smuzhiyun } 60*4882a593Smuzhiyun@@ -994,16 +999,19 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay, 61*4882a593Smuzhiyun g_return_if_fail (sink != NULL); 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun g_mutex_lock (&sink->render_lock); 64*4882a593Smuzhiyun- if (!sink->window) { 65*4882a593Smuzhiyun- g_mutex_unlock (&sink->render_lock); 66*4882a593Smuzhiyun- GST_WARNING_OBJECT (sink, 67*4882a593Smuzhiyun- "set_render_rectangle called without window, ignoring"); 68*4882a593Smuzhiyun- return; 69*4882a593Smuzhiyun- } 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun- GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d", 72*4882a593Smuzhiyun- x, y, w, h); 73*4882a593Smuzhiyun- gst_wl_window_set_render_rectangle (sink->window, x, y, w, h); 74*4882a593Smuzhiyun+ if (sink->window) { 75*4882a593Smuzhiyun+ GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d", 76*4882a593Smuzhiyun+ x, y, w, h); 77*4882a593Smuzhiyun+ gst_wl_window_set_render_rectangle (sink->window, x, y, w, h, TRUE); 78*4882a593Smuzhiyun+ } else { 79*4882a593Smuzhiyun+ GST_DEBUG_OBJECT (sink, "caching window geometry (%d, %d) %d x %d", 80*4882a593Smuzhiyun+ x, y, w, h); 81*4882a593Smuzhiyun+ sink->render_rectangle.x = x; 82*4882a593Smuzhiyun+ sink->render_rectangle.y = y; 83*4882a593Smuzhiyun+ sink->render_rectangle.w = w; 84*4882a593Smuzhiyun+ sink->render_rectangle.h = h; 85*4882a593Smuzhiyun+ } 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun g_mutex_unlock (&sink->render_lock); 88*4882a593Smuzhiyun } 89*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h 90*4882a593Smuzhiyunindex 1c5fb07..9872c29 100644 91*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.h 92*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.h 93*4882a593Smuzhiyun@@ -69,6 +69,7 @@ struct _GstWaylandSink 94*4882a593Smuzhiyun gboolean redraw_pending; 95*4882a593Smuzhiyun GMutex render_lock; 96*4882a593Smuzhiyun GstBuffer *last_buffer; 97*4882a593Smuzhiyun+ GstVideoRectangle render_rectangle; 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun struct wl_callback *callback; 100*4882a593Smuzhiyun }; 101*4882a593Smuzhiyundiff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c 102*4882a593Smuzhiyunindex 57b5491..7814cb8 100644 103*4882a593Smuzhiyun--- a/ext/wayland/wlwindow.c 104*4882a593Smuzhiyun+++ b/ext/wayland/wlwindow.c 105*4882a593Smuzhiyun@@ -79,7 +79,7 @@ handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, 106*4882a593Smuzhiyun if (width <= 0 || height <= 0) 107*4882a593Smuzhiyun return; 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun- gst_wl_window_set_render_rectangle (window, 0, 0, width, height); 110*4882a593Smuzhiyun+ gst_wl_window_set_render_rectangle (window, 0, 0, width, height, FALSE); 111*4882a593Smuzhiyun } 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun static const struct xdg_toplevel_listener xdg_toplevel_listener = { 114*4882a593Smuzhiyun@@ -123,7 +123,7 @@ handle_configure (void *data, struct wl_shell_surface *wl_shell_surface, 115*4882a593Smuzhiyun if (width == 0 || height == 0) 116*4882a593Smuzhiyun return; 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun- gst_wl_window_set_render_rectangle (window, 0, 0, width, height); 119*4882a593Smuzhiyun+ gst_wl_window_set_render_rectangle (window, 0, 0, width, height, FALSE); 120*4882a593Smuzhiyun } 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun static void 123*4882a593Smuzhiyun@@ -256,7 +256,8 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen) 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun GstWlWindow * 126*4882a593Smuzhiyun gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 127*4882a593Smuzhiyun- gboolean fullscreen, GMutex * render_lock) 128*4882a593Smuzhiyun+ gboolean fullscreen, GMutex * render_lock, 129*4882a593Smuzhiyun+ GstVideoRectangle * render_rectangle) 130*4882a593Smuzhiyun { 131*4882a593Smuzhiyun GstWlWindow *window; 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun@@ -325,12 +326,22 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 134*4882a593Smuzhiyun } 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* render_rectangle is already set via toplevel_configure in 137*4882a593Smuzhiyun- * xdg_shell fullscreen mode */ 138*4882a593Smuzhiyun- if (!(display->xdg_wm_base && fullscreen)) { 139*4882a593Smuzhiyun+ * fullscreen mode */ 140*4882a593Smuzhiyun+ if (fullscreen) 141*4882a593Smuzhiyun+ return window; 142*4882a593Smuzhiyun+ 143*4882a593Smuzhiyun+ if (render_rectangle->w || render_rectangle->h) { 144*4882a593Smuzhiyun+ /* apply cached position and size */ 145*4882a593Smuzhiyun+ GST_DEBUG ("Applying window position (%d, %d)", 146*4882a593Smuzhiyun+ render_rectangle->x, render_rectangle->y); 147*4882a593Smuzhiyun+ gst_wl_window_set_render_rectangle (window, render_rectangle->x, 148*4882a593Smuzhiyun+ render_rectangle->y, render_rectangle->w, render_rectangle->h, TRUE); 149*4882a593Smuzhiyun+ } else { 150*4882a593Smuzhiyun /* set the initial size to be the same as the reported video size */ 151*4882a593Smuzhiyun gint width = 152*4882a593Smuzhiyun gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); 153*4882a593Smuzhiyun- gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); 154*4882a593Smuzhiyun+ gst_wl_window_set_render_rectangle (window, 0, 0, 155*4882a593Smuzhiyun+ width, info->height, FALSE); 156*4882a593Smuzhiyun } 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun return window; 159*4882a593Smuzhiyun@@ -546,7 +557,7 @@ gst_wl_window_update_borders (GstWlWindow * window) 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun void 162*4882a593Smuzhiyun gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, 163*4882a593Smuzhiyun- gint w, gint h) 164*4882a593Smuzhiyun+ gint w, gint h, gboolean with_position) 165*4882a593Smuzhiyun { 166*4882a593Smuzhiyun g_return_if_fail (window != NULL); 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun@@ -559,6 +570,10 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, 169*4882a593Smuzhiyun window->render_rectangle.w = w; 170*4882a593Smuzhiyun window->render_rectangle.h = h; 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun+ /* try to position the xdg surface with hacked wayland server API */ 173*4882a593Smuzhiyun+ if (with_position && window->xdg_surface) 174*4882a593Smuzhiyun+ xdg_surface_set_window_geometry (window->xdg_surface, x, y, 0, 0); 175*4882a593Smuzhiyun+ 176*4882a593Smuzhiyun /* position the area inside the parent - needs a parent commit to apply */ 177*4882a593Smuzhiyun if (window->area_subsurface) 178*4882a593Smuzhiyun wl_subsurface_set_position (window->area_subsurface, x, y); 179*4882a593Smuzhiyundiff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h 180*4882a593Smuzhiyunindex 303c336..ba61d7a 100644 181*4882a593Smuzhiyun--- a/ext/wayland/wlwindow.h 182*4882a593Smuzhiyun+++ b/ext/wayland/wlwindow.h 183*4882a593Smuzhiyun@@ -83,7 +83,8 @@ GType gst_wl_window_get_type (void); 184*4882a593Smuzhiyun void gst_wl_window_ensure_fullscreen (GstWlWindow * window, 185*4882a593Smuzhiyun gboolean fullscreen); 186*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, 187*4882a593Smuzhiyun- const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock); 188*4882a593Smuzhiyun+ const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock, 189*4882a593Smuzhiyun+ GstVideoRectangle * render_rectangle); 190*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, 191*4882a593Smuzhiyun struct wl_surface * parent, GMutex * render_lock); 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun@@ -94,7 +95,7 @@ gboolean gst_wl_window_is_toplevel (GstWlWindow *window); 194*4882a593Smuzhiyun void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, 195*4882a593Smuzhiyun const GstVideoInfo * info); 196*4882a593Smuzhiyun void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, 197*4882a593Smuzhiyun- gint w, gint h); 198*4882a593Smuzhiyun+ gint w, gint h, gboolean with_position); 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun G_END_DECLS 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun-- 203*4882a593Smuzhiyun2.20.1 204*4882a593Smuzhiyun 205