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