1*4882a593SmuzhiyunFrom 78fdb1abc730d97e5937ee3414779b9bbdff0413 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Fri, 5 Mar 2021 10:15:51 +0800 4*4882a593SmuzhiyunSubject: [PATCH 19/43] waylandsink: Support window layer property 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunSupport setting top|normal|bottom window layer. 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunTested with: 9*4882a593Smuzhiyungst-launch-1.0 videotestsrc ! waylandsink layer=top 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 12*4882a593Smuzhiyun--- 13*4882a593Smuzhiyun ext/wayland/gstwaylandsink.c | 52 ++++++++++++++++++++++++++++-- 14*4882a593Smuzhiyun ext/wayland/gstwaylandsink.h | 1 + 15*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlwindow.c | 40 ++++++++++++++++++++++- 16*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlwindow.h | 15 +++++++-- 17*4882a593Smuzhiyun 4 files changed, 103 insertions(+), 5 deletions(-) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c 20*4882a593Smuzhiyunindex 071bc5a..f492d72 100644 21*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.c 22*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.c 23*4882a593Smuzhiyun@@ -61,6 +61,7 @@ enum 24*4882a593Smuzhiyun PROP_DISPLAY, 25*4882a593Smuzhiyun PROP_FULLSCREEN, 26*4882a593Smuzhiyun PROP_ROTATE_METHOD, 27*4882a593Smuzhiyun+ PROP_LAYER, 28*4882a593Smuzhiyun PROP_LAST 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun@@ -116,6 +117,24 @@ G_DEFINE_TYPE_WITH_CODE (GstWaylandSink, gst_wayland_sink, GST_TYPE_VIDEO_SINK, 32*4882a593Smuzhiyun GST_ELEMENT_REGISTER_DEFINE (waylandsink, "waylandsink", GST_RANK_MARGINAL, 33*4882a593Smuzhiyun GST_TYPE_WAYLAND_SINK); 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun+#define GST_TYPE_WL_WINDOW_LAYER (gst_wl_window_layer_get_type ()) 36*4882a593Smuzhiyun+static GType 37*4882a593Smuzhiyun+gst_wl_window_layer_get_type (void) 38*4882a593Smuzhiyun+{ 39*4882a593Smuzhiyun+ static GType layer = 0; 40*4882a593Smuzhiyun+ 41*4882a593Smuzhiyun+ if (!layer) { 42*4882a593Smuzhiyun+ static const GEnumValue layers[] = { 43*4882a593Smuzhiyun+ {GST_WL_WINDOW_LAYER_TOP, "Top", "top"}, 44*4882a593Smuzhiyun+ {GST_WL_WINDOW_LAYER_NORMAL, "Normal", "normal"}, 45*4882a593Smuzhiyun+ {GST_WL_WINDOW_LAYER_BOTTOM, "Bottom", "bottom"}, 46*4882a593Smuzhiyun+ {0, NULL, NULL} 47*4882a593Smuzhiyun+ }; 48*4882a593Smuzhiyun+ layer = g_enum_register_static ("GstWlWindowLayer", layers); 49*4882a593Smuzhiyun+ } 50*4882a593Smuzhiyun+ return layer; 51*4882a593Smuzhiyun+} 52*4882a593Smuzhiyun+ 53*4882a593Smuzhiyun static void 54*4882a593Smuzhiyun gst_wayland_sink_class_init (GstWaylandSinkClass * klass) 55*4882a593Smuzhiyun { 56*4882a593Smuzhiyun@@ -177,6 +196,12 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) 57*4882a593Smuzhiyun GST_TYPE_VIDEO_ORIENTATION_METHOD, GST_VIDEO_ORIENTATION_IDENTITY, 58*4882a593Smuzhiyun G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun+ g_object_class_install_property (gobject_class, PROP_LAYER, 61*4882a593Smuzhiyun+ g_param_spec_enum ("layer", "Window layer", 62*4882a593Smuzhiyun+ "Wayland window layer", 63*4882a593Smuzhiyun+ GST_TYPE_WL_WINDOW_LAYER, GST_WL_WINDOW_LAYER_NORMAL, 64*4882a593Smuzhiyun+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 65*4882a593Smuzhiyun+ 66*4882a593Smuzhiyun /** 67*4882a593Smuzhiyun * waylandsink:render-rectangle: 68*4882a593Smuzhiyun * 69*4882a593Smuzhiyun@@ -195,6 +220,7 @@ gst_wayland_sink_init (GstWaylandSink * self) 70*4882a593Smuzhiyun g_mutex_init (&self->render_lock); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun self->window_handle = 1; 73*4882a593Smuzhiyun+ self->layer = GST_WL_WINDOW_LAYER_NORMAL; 74*4882a593Smuzhiyun } 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun static void 77*4882a593Smuzhiyun@@ -246,6 +272,18 @@ gst_wayland_sink_set_rotate_method (GstWaylandSink * self, 78*4882a593Smuzhiyun GST_OBJECT_UNLOCK (self); 79*4882a593Smuzhiyun } 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun+static void 82*4882a593Smuzhiyun+gst_wayland_sink_set_layer (GstWaylandSink * self, GstWlWindowLayer layer) 83*4882a593Smuzhiyun+{ 84*4882a593Smuzhiyun+ if (layer == self->layer) 85*4882a593Smuzhiyun+ return; 86*4882a593Smuzhiyun+ 87*4882a593Smuzhiyun+ g_mutex_lock (&self->render_lock); 88*4882a593Smuzhiyun+ self->layer = layer; 89*4882a593Smuzhiyun+ gst_wl_window_ensure_layer (self->window, layer); 90*4882a593Smuzhiyun+ g_mutex_unlock (&self->render_lock); 91*4882a593Smuzhiyun+} 92*4882a593Smuzhiyun+ 93*4882a593Smuzhiyun static void 94*4882a593Smuzhiyun gst_wayland_sink_get_property (GObject * object, 95*4882a593Smuzhiyun guint prop_id, GValue * value, GParamSpec * pspec) 96*4882a593Smuzhiyun@@ -268,6 +306,11 @@ gst_wayland_sink_get_property (GObject * object, 97*4882a593Smuzhiyun g_value_set_enum (value, self->current_rotate_method); 98*4882a593Smuzhiyun GST_OBJECT_UNLOCK (self); 99*4882a593Smuzhiyun break; 100*4882a593Smuzhiyun+ case PROP_LAYER: 101*4882a593Smuzhiyun+ GST_OBJECT_LOCK (self); 102*4882a593Smuzhiyun+ g_value_set_enum (value, self->layer); 103*4882a593Smuzhiyun+ GST_OBJECT_UNLOCK (self); 104*4882a593Smuzhiyun+ break; 105*4882a593Smuzhiyun default: 106*4882a593Smuzhiyun G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 107*4882a593Smuzhiyun break; 108*4882a593Smuzhiyun@@ -295,6 +338,11 @@ gst_wayland_sink_set_property (GObject * object, 109*4882a593Smuzhiyun gst_wayland_sink_set_rotate_method (self, g_value_get_enum (value), 110*4882a593Smuzhiyun FALSE); 111*4882a593Smuzhiyun break; 112*4882a593Smuzhiyun+ case PROP_LAYER: 113*4882a593Smuzhiyun+ GST_OBJECT_LOCK (self); 114*4882a593Smuzhiyun+ gst_wayland_sink_set_layer (self, g_value_get_enum (value)); 115*4882a593Smuzhiyun+ GST_OBJECT_UNLOCK (self); 116*4882a593Smuzhiyun+ break; 117*4882a593Smuzhiyun default: 118*4882a593Smuzhiyun if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) 119*4882a593Smuzhiyun G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 120*4882a593Smuzhiyun@@ -773,8 +821,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 121*4882a593Smuzhiyun if (!self->window) { 122*4882a593Smuzhiyun /* if we were not provided a window, create one ourselves */ 123*4882a593Smuzhiyun self->window = gst_wl_window_new_toplevel (self->display, 124*4882a593Smuzhiyun- &self->video_info, self->fullscreen, &self->render_lock, 125*4882a593Smuzhiyun- &self->render_rectangle); 126*4882a593Smuzhiyun+ &self->video_info, self->fullscreen, self->layer, 127*4882a593Smuzhiyun+ &self->render_lock, &self->render_rectangle); 128*4882a593Smuzhiyun g_signal_connect_object (self->window, "closed", 129*4882a593Smuzhiyun G_CALLBACK (on_window_closed), self, 0); 130*4882a593Smuzhiyun gst_wl_window_set_rotate_method (self->window, 131*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h 132*4882a593Smuzhiyunindex d4c3764..a417788 100644 133*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.h 134*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.h 135*4882a593Smuzhiyun@@ -57,6 +57,7 @@ struct _GstWaylandSink 136*4882a593Smuzhiyun gboolean video_info_changed; 137*4882a593Smuzhiyun GstVideoInfo video_info; 138*4882a593Smuzhiyun gboolean fullscreen; 139*4882a593Smuzhiyun+ GstWlWindowLayer layer; 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun gchar *display_name; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlwindow.c b/gst-libs/gst/wayland/gstwlwindow.c 144*4882a593Smuzhiyunindex dd6e1c2..7a3016c 100644 145*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlwindow.c 146*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlwindow.c 147*4882a593Smuzhiyun@@ -252,6 +252,43 @@ gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock) 148*4882a593Smuzhiyun return self; 149*4882a593Smuzhiyun } 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun+static void 152*4882a593Smuzhiyun+gst_wl_window_set_config (GstWlWindow * self, const char *config) 153*4882a593Smuzhiyun+{ 154*4882a593Smuzhiyun+ GstWlWindowPrivate *priv; 155*4882a593Smuzhiyun+ 156*4882a593Smuzhiyun+ /* TODO: support non-toplevel */ 157*4882a593Smuzhiyun+ if (!self || !gst_wl_window_is_toplevel (self)) 158*4882a593Smuzhiyun+ return; 159*4882a593Smuzhiyun+ 160*4882a593Smuzhiyun+ priv = gst_wl_window_get_instance_private (self); 161*4882a593Smuzhiyun+ 162*4882a593Smuzhiyun+ /* HACK: set window config through title */ 163*4882a593Smuzhiyun+ xdg_toplevel_set_title (priv->xdg_toplevel, config); 164*4882a593Smuzhiyun+} 165*4882a593Smuzhiyun+ 166*4882a593Smuzhiyun+void 167*4882a593Smuzhiyun+gst_wl_window_ensure_layer (GstWlWindow * self, GstWlWindowLayer layer) 168*4882a593Smuzhiyun+{ 169*4882a593Smuzhiyun+ char s[128] = "flags="; 170*4882a593Smuzhiyun+ 171*4882a593Smuzhiyun+ switch (layer) { 172*4882a593Smuzhiyun+ case GST_WL_WINDOW_LAYER_TOP: 173*4882a593Smuzhiyun+ strcat (s, "stay-on-top|-stay-on-bottom"); 174*4882a593Smuzhiyun+ break; 175*4882a593Smuzhiyun+ case GST_WL_WINDOW_LAYER_NORMAL: 176*4882a593Smuzhiyun+ strcat (s, "-stay-on-top|-stay-on-bottom"); 177*4882a593Smuzhiyun+ break; 178*4882a593Smuzhiyun+ case GST_WL_WINDOW_LAYER_BOTTOM: 179*4882a593Smuzhiyun+ strcat (s, "-stay-on-top|stay-on-bottom"); 180*4882a593Smuzhiyun+ break; 181*4882a593Smuzhiyun+ default: 182*4882a593Smuzhiyun+ return; 183*4882a593Smuzhiyun+ } 184*4882a593Smuzhiyun+ 185*4882a593Smuzhiyun+ gst_wl_window_set_config (self, s); 186*4882a593Smuzhiyun+} 187*4882a593Smuzhiyun+ 188*4882a593Smuzhiyun void 189*4882a593Smuzhiyun gst_wl_window_ensure_fullscreen (GstWlWindow * self, gboolean fullscreen) 190*4882a593Smuzhiyun { 191*4882a593Smuzhiyun@@ -269,7 +306,7 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * self, gboolean fullscreen) 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun GstWlWindow * 194*4882a593Smuzhiyun gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 195*4882a593Smuzhiyun- gboolean fullscreen, GMutex * render_lock, 196*4882a593Smuzhiyun+ gboolean fullscreen, GstWlWindowLayer layer, GMutex * render_lock, 197*4882a593Smuzhiyun GstVideoRectangle * render_rectangle) 198*4882a593Smuzhiyun { 199*4882a593Smuzhiyun GstWlWindow *self; 200*4882a593Smuzhiyun@@ -306,6 +343,7 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 201*4882a593Smuzhiyun &xdg_toplevel_listener, self); 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun gst_wl_window_ensure_fullscreen (self, fullscreen); 204*4882a593Smuzhiyun+ gst_wl_window_ensure_layer (self, layer); 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun /* Finally, commit the xdg_surface state as toplevel */ 207*4882a593Smuzhiyun priv->configured = FALSE; 208*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlwindow.h b/gst-libs/gst/wayland/gstwlwindow.h 209*4882a593Smuzhiyunindex 2bbd643..a0b05c3 100644 210*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlwindow.h 211*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlwindow.h 212*4882a593Smuzhiyun@@ -28,19 +28,30 @@ G_BEGIN_DECLS 213*4882a593Smuzhiyun #define GST_TYPE_WL_WINDOW (gst_wl_window_get_type ()) 214*4882a593Smuzhiyun G_DECLARE_FINAL_TYPE (GstWlWindow, gst_wl_window, GST, WL_WINDOW, GObject); 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun+typedef enum 217*4882a593Smuzhiyun+{ 218*4882a593Smuzhiyun+ GST_WL_WINDOW_LAYER_TOP = 0, 219*4882a593Smuzhiyun+ GST_WL_WINDOW_LAYER_NORMAL = 1, 220*4882a593Smuzhiyun+ GST_WL_WINDOW_LAYER_BOTTOM = 2, 221*4882a593Smuzhiyun+} GstWlWindowLayer; 222*4882a593Smuzhiyun+ 223*4882a593Smuzhiyun struct _GstWlWindow 224*4882a593Smuzhiyun { 225*4882a593Smuzhiyun GObject parent_instance; 226*4882a593Smuzhiyun }; 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun+GST_WL_API 229*4882a593Smuzhiyun+void gst_wl_window_ensure_layer (GstWlWindow * self, 230*4882a593Smuzhiyun+ GstWlWindowLayer layer); 231*4882a593Smuzhiyun+ 232*4882a593Smuzhiyun GST_WL_API 233*4882a593Smuzhiyun void gst_wl_window_ensure_fullscreen (GstWlWindow * self, 234*4882a593Smuzhiyun gboolean fullscreen); 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun GST_WL_API 237*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, 238*4882a593Smuzhiyun- const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock, 239*4882a593Smuzhiyun- GstVideoRectangle * render_rectangle); 240*4882a593Smuzhiyun+ const GstVideoInfo * info, gboolean fullscreen, GstWlWindowLayer layer, 241*4882a593Smuzhiyun+ GMutex * render_lock, GstVideoRectangle * render_rectangle); 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun GST_WL_API 244*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, 245*4882a593Smuzhiyun-- 246*4882a593Smuzhiyun2.20.1 247*4882a593Smuzhiyun 248