Files
yoctor-layers/meta-st/meta-st-openstlinux/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-waylandsink-Refactor-internal-pool-handling.patch
2024-07-11 14:16:35 +02:00

349 lines
12 KiB
Diff

From 79405fb8592f22d62b4faa2f7098b814cc2a0d49 Mon Sep 17 00:00:00 2001
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Date: Thu, 16 Feb 2023 13:54:42 -0500
Subject: [PATCH 06/17] waylandsink: Refactor internal pool handling
This is to make it easier to support more then one allocators
including falling back from one to another.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3801>
---
ext/gtk/gstgtkwaylandsink.c | 101 +++++++++++++++++++++--------------
ext/wayland/gstwaylandsink.c | 101 +++++++++++++++++++++--------------
ext/wayland/gstwaylandsink.h | 1 +
3 files changed, 124 insertions(+), 79 deletions(-)
diff --git a/ext/gtk/gstgtkwaylandsink.c b/ext/gtk/gstgtkwaylandsink.c
index 1afad32..8967d97 100644
--- a/ext/gtk/gstgtkwaylandsink.c
+++ b/ext/gtk/gstgtkwaylandsink.c
@@ -109,6 +109,7 @@ typedef struct _GstGtkWaylandSinkPrivate
gboolean video_info_changed;
GstVideoInfo video_info;
+ GstCaps *caps;
gboolean redraw_pending;
GMutex render_lock;
@@ -200,6 +201,7 @@ gst_gtk_wayland_sink_finalize (GObject * object)
gst_gtk_wayland_sink_get_instance_private (self);
g_clear_object (&priv->gtk_widget);
+ gst_clear_caps (&priv->caps);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -801,30 +803,57 @@ gst_gtk_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
return caps;
}
-static GstBufferPool *
-gst_gtk_wayland_create_pool (GstGtkWaylandSink * self, GstCaps * caps)
+static gboolean
+gst_gtk_wayland_update_pool (GstGtkWaylandSink * self, GstAllocator * allocator)
{
GstGtkWaylandSinkPrivate *priv =
gst_gtk_wayland_sink_get_instance_private (self);
- GstBufferPool *pool = NULL;
- GstStructure *structure;
gsize size = priv->video_info.size;
- GstAllocator *alloc;
+ GstStructure *config;
- pool = gst_wl_video_buffer_pool_new ();
+ /* Pools with outstanding buffer cannot be reconfigured, so we must use
+ * a new pool. */
+ if (priv->pool) {
+ gst_buffer_pool_set_active (priv->pool, FALSE);
+ gst_object_unref (priv->pool);
+ }
+ priv->pool = gst_wl_video_buffer_pool_new ();
- structure = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_set_params (structure, caps, size, 2, 0);
+ config = gst_buffer_pool_get_config (priv->pool);
+ gst_buffer_pool_config_set_params (config, priv->caps, size, 2, 0);
+ gst_buffer_pool_config_set_allocator (config, allocator, NULL);
- alloc = gst_wl_shm_allocator_get ();
- gst_buffer_pool_config_set_allocator (structure, alloc, NULL);
- if (!gst_buffer_pool_set_config (pool, structure)) {
- g_object_unref (pool);
- pool = NULL;
+ if (!gst_buffer_pool_set_config (priv->pool, config))
+ return FALSE;
+
+ return gst_buffer_pool_set_active (priv->pool, TRUE);
+}
+
+static gboolean
+gst_gtk_wayland_activate_shm_pool (GstGtkWaylandSink * self)
+{
+ GstGtkWaylandSinkPrivate *priv =
+ gst_gtk_wayland_sink_get_instance_private (self);
+ GstAllocator *alloc = NULL;
+
+ if (priv->pool && gst_buffer_pool_is_active (priv->pool)) {
+ GstStructure *config = gst_buffer_pool_get_config (priv->pool);
+ gboolean is_shm = FALSE;
+
+ if (gst_buffer_pool_config_get_allocator (config, &alloc, NULL) && alloc)
+ is_shm = GST_IS_WL_SHM_ALLOCATOR (alloc);
+
+ gst_structure_free (config);
+
+ if (is_shm)
+ return TRUE;
}
- g_object_unref (alloc);
- return pool;
+ alloc = gst_wl_shm_allocator_get ();
+ gst_gtk_wayland_update_pool (self, alloc);
+ gst_object_unref (alloc);
+
+ return TRUE;
}
static gboolean
@@ -845,10 +874,11 @@ gst_gtk_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
format = GST_VIDEO_INFO_FORMAT (&priv->video_info);
priv->video_info_changed = TRUE;
- /* create a new pool for the new caps */
- if (priv->pool)
- gst_object_unref (priv->pool);
- priv->pool = gst_gtk_wayland_create_pool (self, caps);
+ /* free pooled buffer used with previous caps */
+ if (priv->pool) {
+ gst_buffer_pool_set_active (priv->pool, FALSE);
+ gst_clear_object (&priv->pool);
+ }
use_dmabuf = gst_caps_features_contains (gst_caps_get_features (caps, 0),
GST_CAPS_FEATURE_MEMORY_DMABUF);
@@ -884,6 +914,8 @@ gst_gtk_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
GST_OBJECT_UNLOCK (self);
priv->use_dmabuf = use_dmabuf;
+ /* Will be used to create buffer pools */
+ gst_caps_replace (&priv->caps, caps);
return TRUE;
@@ -914,8 +946,14 @@ gst_gtk_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
gst_query_parse_allocation (query, &caps, &need_pool);
- if (need_pool)
- pool = gst_gtk_wayland_create_pool (self, caps);
+ if (need_pool) {
+ GstStructure *config;
+ pool = gst_wl_video_buffer_pool_new ();
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set_allocator (config,
+ gst_wl_shm_allocator_get (), NULL);
+ gst_buffer_pool_set_config (pool, config);
+ }
gst_query_add_allocation_pool (query, pool, priv->video_info.size, 2, 0);
if (pool)
@@ -1077,25 +1115,10 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
"buffer %" GST_PTR_FORMAT " cannot have a wl_buffer, "
"copying to wl_shm memory", buffer);
- /* priv->pool always exists (created in set_caps), but it may not
- * be active if upstream is not using it */
- if (!gst_buffer_pool_is_active (priv->pool)) {
- GstStructure *config;
- GstCaps *caps;
- config = gst_buffer_pool_get_config (priv->pool);
- gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL);
-
- /* revert back to default strides and offsets */
- gst_video_info_from_caps (&priv->video_info, caps);
- gst_buffer_pool_config_set_params (config, caps, priv->video_info.size,
- 2, 0);
-
- /* This is a video pool, it should not fail with basic settings */
- if (!gst_buffer_pool_set_config (priv->pool, config) ||
- !gst_buffer_pool_set_active (priv->pool, TRUE))
- goto activate_failed;
- }
+ /* ensure the internal pool is configured for SHM */
+ if (!gst_gtk_wayland_activate_shm_pool (self))
+ goto activate_failed;
ret = gst_buffer_pool_acquire_buffer (priv->pool, &to_render, NULL);
if (ret != GST_FLOW_OK)
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index 7077ee9..b9b6267 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -315,6 +315,8 @@ gst_wayland_sink_finalize (GObject * object)
if (self->pool)
gst_object_unref (self->pool);
+ gst_clear_caps (&self->caps);
+
g_free (self->display_name);
g_mutex_clear (&self->display_lock);
@@ -578,28 +580,53 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
return caps;
}
-static GstBufferPool *
-gst_wayland_create_pool (GstWaylandSink * self, GstCaps * caps)
+static gboolean
+gst_wayland_update_pool (GstWaylandSink * self, GstAllocator * allocator)
{
- GstBufferPool *pool = NULL;
- GstStructure *structure;
gsize size = self->video_info.size;
- GstAllocator *alloc;
+ GstStructure *config;
- pool = gst_wl_video_buffer_pool_new ();
+ /* Pools with outstanding buffer cannot be reconfigured, so we must use
+ * a new pool. */
+ if (self->pool) {
+ gst_buffer_pool_set_active (self->pool, FALSE);
+ gst_object_unref (self->pool);
+ }
+ self->pool = gst_wl_video_buffer_pool_new ();
- structure = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_set_params (structure, caps, size, 2, 0);
+ config = gst_buffer_pool_get_config (self->pool);
+ gst_buffer_pool_config_set_params (config, self->caps, size, 2, 0);
+ gst_buffer_pool_config_set_allocator (config, allocator, NULL);
- alloc = gst_wl_shm_allocator_get ();
- gst_buffer_pool_config_set_allocator (structure, alloc, NULL);
- if (!gst_buffer_pool_set_config (pool, structure)) {
- g_object_unref (pool);
- pool = NULL;
+ if (!gst_buffer_pool_set_config (self->pool, config))
+ return FALSE;
+
+ return gst_buffer_pool_set_active (self->pool, TRUE);
+}
+
+static gboolean
+gst_wayland_activate_shm_pool (GstWaylandSink * self)
+{
+ GstAllocator *alloc = NULL;
+
+ if (self->pool && gst_buffer_pool_is_active (self->pool)) {
+ GstStructure *config = gst_buffer_pool_get_config (self->pool);
+ gboolean is_shm = FALSE;
+
+ if (gst_buffer_pool_config_get_allocator (config, &alloc, NULL) && alloc)
+ is_shm = GST_IS_WL_SHM_ALLOCATOR (alloc);
+
+ gst_structure_free (config);
+
+ if (is_shm)
+ return TRUE;
}
- g_object_unref (alloc);
- return pool;
+ alloc = gst_wl_shm_allocator_get ();
+ gst_wayland_update_pool (self, alloc);
+ gst_object_unref (alloc);
+
+ return TRUE;
}
static gboolean
@@ -618,10 +645,11 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
format = GST_VIDEO_INFO_FORMAT (&self->video_info);
self->video_info_changed = TRUE;
- /* create a new pool for the new caps */
- if (self->pool)
- gst_object_unref (self->pool);
- self->pool = gst_wayland_create_pool (self, caps);
+ /* free pooled buffer used with previous caps */
+ if (self->pool) {
+ gst_buffer_pool_set_active (self->pool, FALSE);
+ gst_clear_object (&self->pool);
+ }
use_dmabuf = gst_caps_features_contains (gst_caps_get_features (caps, 0),
GST_CAPS_FEATURE_MEMORY_DMABUF);
@@ -639,6 +667,9 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
self->use_dmabuf = use_dmabuf;
+ /* Will be used to create buffer pools */
+ gst_caps_replace (&self->caps, caps);
+
return TRUE;
invalid_format:
@@ -666,8 +697,14 @@ gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
gst_query_parse_allocation (query, &caps, &need_pool);
- if (need_pool)
- pool = gst_wayland_create_pool (self, caps);
+ if (need_pool) {
+ GstStructure *config;
+ pool = gst_wl_video_buffer_pool_new ();
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set_allocator (config,
+ gst_wl_shm_allocator_get (), NULL);
+ gst_buffer_pool_set_config (pool, config);
+ }
gst_query_add_allocation_pool (query, pool, self->video_info.size, 2, 0);
if (pool)
@@ -844,25 +881,9 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
"buffer %" GST_PTR_FORMAT " cannot have a wl_buffer, "
"copying to wl_shm memory", buffer);
- /* self->pool always exists (created in set_caps), but it may not
- * be active if upstream is not using it */
- if (!gst_buffer_pool_is_active (self->pool)) {
- GstStructure *config;
- GstCaps *caps;
-
- config = gst_buffer_pool_get_config (self->pool);
- gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL);
-
- /* revert back to default strides and offsets */
- gst_video_info_from_caps (&self->video_info, caps);
- gst_buffer_pool_config_set_params (config, caps, self->video_info.size,
- 2, 0);
-
- /* This is a video pool, it should not fail with basic settings */
- if (!gst_buffer_pool_set_config (self->pool, config) ||
- !gst_buffer_pool_set_active (self->pool, TRUE))
- goto activate_failed;
- }
+ /* ensure the internal pool is configured for SHM */
+ if (!gst_wayland_activate_shm_pool (self))
+ goto activate_failed;
ret = gst_buffer_pool_acquire_buffer (self->pool, &to_render, NULL);
if (ret != GST_FLOW_OK)
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
index 3243d8c..1ff50d1 100644
--- a/ext/wayland/gstwaylandsink.h
+++ b/ext/wayland/gstwaylandsink.h
@@ -56,6 +56,7 @@ struct _GstWaylandSink
gboolean video_info_changed;
GstVideoInfo video_info;
gboolean fullscreen;
+ GstCaps *caps;
gchar *display_name;
--
2.25.1