mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
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>
This commit is contained in:
parent
9084a960a5
commit
965117b400
3 changed files with 124 additions and 79 deletions
|
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
g_object_unref (alloc);
|
||||
gst_gtk_wayland_update_pool (self, alloc);
|
||||
gst_object_unref (alloc);
|
||||
|
||||
return pool;
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
g_object_unref (alloc);
|
||||
gst_wayland_update_pool (self, alloc);
|
||||
gst_object_unref (alloc);
|
||||
|
||||
return pool;
|
||||
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);
|
||||
|
@ -636,6 +664,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:
|
||||
|
@ -663,8 +694,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)
|
||||
|
@ -841,25 +878,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)
|
||||
|
|
|
@ -56,6 +56,7 @@ struct _GstWaylandSink
|
|||
gboolean video_info_changed;
|
||||
GstVideoInfo video_info;
|
||||
gboolean fullscreen;
|
||||
GstCaps *caps;
|
||||
|
||||
gchar *display_name;
|
||||
|
||||
|
|
Loading…
Reference in a new issue