From 2319581d4848e5763abe25059ad43148baa95aaf Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Tue, 28 Dec 2021 14:06:19 +0800 Subject: [PATCH 19/33] waylandsink: Support window alpha property Tested with: gst-launch-1.0 videotestsrc ! waylandsink alpha=0.5 Signed-off-by: Jeffy Chen --- ext/wayland/gstwaylandsink.c | 32 ++++++++++++++++++++++++++++++++ ext/wayland/gstwaylandsink.h | 1 + ext/wayland/wlwindow.c | 23 ++++++++++++++++------- ext/wayland/wlwindow.h | 1 + 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c index 1bf4511..ff79ddf 100644 --- a/ext/wayland/gstwaylandsink.c +++ b/ext/wayland/gstwaylandsink.c @@ -65,6 +65,7 @@ enum PROP_DISPLAY, PROP_FULLSCREEN, PROP_LAYER, + PROP_ALPHA, PROP_LAST }; @@ -238,6 +239,11 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) GST_TYPE_WL_WINDOW_LAYER, GST_WL_WINDOW_LAYER_NORMAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ALPHA, + g_param_spec_double ("alpha", "Window alpha", + "Wayland window alpha", 0.0, 1.0, 1.0, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + gst_video_overlay_install_properties (gobject_class, PROP_LAST); gst_type_mark_as_plugin_api (GST_TYPE_WAYLAND_VIDEO, 0); @@ -251,6 +257,7 @@ gst_wayland_sink_init (GstWaylandSink * sink) sink->window_handle = 1; sink->layer = GST_WL_WINDOW_LAYER_NORMAL; + sink->alpha = 1.0; } static void @@ -277,6 +284,18 @@ gst_wayland_sink_set_layer (GstWaylandSink * sink, GstWlWindowLayer layer) g_mutex_unlock (&sink->render_lock); } +static void +gst_wayland_sink_set_alpha (GstWaylandSink * sink, gdouble alpha) +{ + if (alpha == sink->alpha) + return; + + g_mutex_lock (&sink->render_lock); + sink->alpha = alpha; + gst_wl_window_ensure_alpha (sink->window, alpha); + g_mutex_unlock (&sink->render_lock); +} + static void gst_wayland_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) @@ -299,6 +318,11 @@ gst_wayland_sink_get_property (GObject * object, g_value_set_enum (value, sink->layer); GST_OBJECT_UNLOCK (sink); break; + case PROP_ALPHA: + GST_OBJECT_LOCK (sink); + g_value_set_double (value, sink->alpha); + GST_OBJECT_UNLOCK (sink); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -327,6 +351,11 @@ gst_wayland_sink_set_property (GObject * object, gst_wayland_sink_set_layer (sink, g_value_get_enum (value)); GST_OBJECT_UNLOCK (sink); break; + case PROP_ALPHA: + GST_OBJECT_LOCK (sink); + gst_wayland_sink_set_alpha (sink, g_value_get_double (value)); + GST_OBJECT_UNLOCK (sink); + break; default: if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -783,6 +812,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) sink->window = gst_wl_window_new_toplevel (sink->display, &sink->video_info, sink->fullscreen, sink->layer, &sink->render_lock, &sink->render_rectangle); + gst_wl_window_ensure_alpha (sink->window, sink->alpha); + g_signal_connect_object (sink->window, "closed", G_CALLBACK (on_window_closed), sink, 0); } @@ -1035,6 +1066,7 @@ gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle) } else { sink->window = gst_wl_window_new_in_surface (sink->display, surface, &sink->render_lock); + gst_wl_window_ensure_alpha (sink->window, sink->alpha); if (sink->last_buffer) { /* Resend video info to force resize video surface */ diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h index 3adddf2..f798969 100644 --- a/ext/wayland/gstwaylandsink.h +++ b/ext/wayland/gstwaylandsink.h @@ -63,6 +63,7 @@ struct _GstWaylandSink GstVideoInfo video_info; gboolean fullscreen; GstWlWindowLayer layer; + gdouble alpha; gchar *display_name; diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c index 7f7f3b6..58e65dd 100644 --- a/ext/wayland/wlwindow.c +++ b/ext/wayland/wlwindow.c @@ -24,6 +24,7 @@ #include #endif +#include #include #include "wlwindow.h" @@ -235,19 +236,25 @@ gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock) } static void -gst_wl_window_set_flags (GstWlWindow * window, const char *flags) +gst_wl_window_set_config (GstWlWindow * window, const char *config) { - /* HACK: set window flags through title */ - char s[128] = "flags="; - strcat (s, flags); - + /* HACK: set window config through title */ if (!window) return; if (window->xdg_toplevel) - xdg_toplevel_set_title (window->xdg_toplevel, s); + xdg_toplevel_set_title (window->xdg_toplevel, config); else if (window->wl_shell_surface) - wl_shell_surface_set_title (window->wl_shell_surface, s); + wl_shell_surface_set_title (window->wl_shell_surface, config); +} + +void +gst_wl_window_ensure_alpha (GstWlWindow * window, gdouble alpha) +{ + char s[128]; + + snprintf (s, sizeof (s), "attrs=alpha:%f;", alpha); + gst_wl_window_set_config (window, s); } void @@ -268,6 +275,8 @@ gst_wl_window_ensure_layer (GstWlWindow * window, GstWlWindowLayer layer) default: return; } + + gst_wl_window_set_config (window, s); } void diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h index 97ea79e..6fb8285 100644 --- a/ext/wayland/wlwindow.h +++ b/ext/wayland/wlwindow.h @@ -87,6 +87,7 @@ typedef enum GST_WL_WINDOW_LAYER_BOTTOM = 2, } GstWlWindowLayer; +void gst_wl_window_ensure_alpha (GstWlWindow * window, gdouble alpha); void gst_wl_window_ensure_layer (GstWlWindow * window, GstWlWindowLayer layer); void gst_wl_window_ensure_fullscreen (GstWlWindow * window, -- 2.20.1