From 1b7cf6163217a79344c0d11d15e49aec65c44716 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Wed, 19 Jun 2024 17:40:56 +0200 Subject: [PATCH] gst: pipewiresink: wait for activated buffer pool before updating buffers PipeWire expects the SPA_TYPE_OBJECT_ParamBuffers to be valid after setting SPA_PARAM_Format. The pipewiresink knows the final buffer size only after the pipewirepool has been activated. There is a race between PipeWire asking the pipewiresink for the buffers and GStreamer activating the buffer pool. If GStreamer has not activated the buffer pool before PipeWire asks for the Buffer params, PipeWire won't allocate buffers with the correct type and size. The chance of hitting this window increases, if the upstream GStreamer element doesn't use the buffer pool. In this case the buffer pool is activated by the first buffer that arrives at the pipewiresink, which may take some time. Instead of not updating the Buffer params when the buffer pool is not active, wait for the buffer pool to become active. --- src/gst/gstpipewiresink.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index b4f9c39e0..b39a335d8 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -297,7 +297,7 @@ static void pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) { GST_DEBUG_OBJECT (pool, "activated"); - gst_pipewire_sink_update_params (sink); + g_cond_signal (&sink->stream->pool->cond); } static void @@ -580,12 +580,19 @@ static void on_param_changed (void *data, uint32_t id, const struct spa_pod *param) { GstPipeWireSink *pwsink = data; + GstPipeWirePool *pool = pwsink->stream->pool; if (param == NULL || id != SPA_PARAM_Format) return; - if (gst_buffer_pool_is_active (GST_BUFFER_POOL_CAST (pwsink->stream->pool))) - gst_pipewire_sink_update_params (pwsink); + GST_OBJECT_LOCK (pool); + while (!gst_buffer_pool_is_active (GST_BUFFER_POOL (pool))) { + GST_DEBUG_OBJECT (pool, "waiting for pool to become active"); + g_cond_wait(&pool->cond, GST_OBJECT_GET_LOCK (pool)); + } + GST_OBJECT_UNLOCK (pool); + + gst_pipewire_sink_update_params (pwsink); } static gboolean