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.
This commit is contained in:
Michael Tretter 2024-06-19 17:40:56 +02:00 committed by Wim Taymans
parent 21358526d5
commit 1b7cf61632

View file

@ -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