diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index 58a6cd8db..0052a8868 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -167,7 +167,8 @@ gst_pipewire_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) { GstPipeWireSink *pwsink = GST_PIPEWIRE_SINK (bsink); - if (pwsink->use_bufferpool != USE_BUFFERPOOL_NO) + if (pwsink->use_bufferpool != USE_BUFFERPOOL_NO && + pwsink->mode != GST_PIPEWIRE_SINK_MODE_PROVIDE) gst_query_add_allocation_pool (query, GST_BUFFER_POOL_CAST (pwsink->stream->pool), 0, PIPEWIRE_POOL_MIN_BUFFERS, PIPEWIRE_POOL_MAX_BUFFERS); @@ -618,6 +619,8 @@ on_remove_buffer (void *_data, struct pw_buffer *b) GST_DEBUG_OBJECT (pwsink, "remove pw_buffer %p", b); gst_pipewire_pool_remove_buffer (pwsink->stream->pool, b); + g_cond_signal (&pwsink->stream->pool->cond); + if (!gst_pipewire_pool_has_buffers (pwsink->stream->pool) && !GST_BUFFER_POOL_IS_FLUSHING (GST_BUFFER_POOL_CAST (pwsink->stream->pool))) { if (pwsink->mode != GST_PIPEWIRE_SINK_MODE_PROVIDE) { @@ -835,12 +838,14 @@ on_param_changed (void *data, uint32_t id, const struct spa_pod *param) if (param == NULL || id != SPA_PARAM_Format) return; - 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)); + if (pwsink->mode != GST_PIPEWIRE_SINK_MODE_PROVIDE) { + 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_OBJECT_UNLOCK (pool); gst_pipewire_sink_update_params (pwsink); } @@ -978,6 +983,9 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) } gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pwsink->stream->pool), config); + if (pwsink->mode == GST_PIPEWIRE_SINK_MODE_PROVIDE) + gst_buffer_pool_set_active (GST_BUFFER_POOL_CAST (pwsink->stream->pool), TRUE); + pw_thread_loop_unlock (pwsink->stream->core->loop); pwsink->negotiated = TRUE; @@ -1039,13 +1047,17 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) * buffer size which is acquired from the pool of pipewiresink. Need split * the buffer and send them in turn for this case */ while (buf_size) { - GstBuffer *b = NULL; + g_autoptr (GstBuffer) b = NULL; GstMapInfo info = { 0, }; GstBufferPoolAcquireParams params = { 0, }; pw_thread_loop_unlock (pwsink->stream->core->loop); - params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_LAST; + if (pwsink->mode == GST_PIPEWIRE_SINK_MODE_PROVIDE) + params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT; + else + params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_LAST; + res = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL_CAST (pwsink->stream->pool), &b, ¶ms); if (res == GST_FLOW_CUSTOM_ERROR_1) { @@ -1054,8 +1066,15 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) goto done; continue; } - if (res != GST_FLOW_OK) + if (res != GST_FLOW_OK) { + if (pwsink->mode == GST_PIPEWIRE_SINK_MODE_PROVIDE) { + if (res != GST_FLOW_EOS) + GST_WARNING_OBJECT (pwsink, "buffer acquire failed in provide mode: %s", + gst_flow_get_name (res)); + return GST_FLOW_OK; + } goto done; + } if (pwsink->is_rawvideo) { GstVideoFrame src, dst; @@ -1099,13 +1118,10 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) } pw_thread_loop_lock (pwsink->stream->core->loop); - if (pw_stream_get_state (pwsink->stream->pwstream, &error) != PW_STREAM_STATE_STREAMING) { - gst_buffer_unref (b); + if (pw_stream_get_state (pwsink->stream->pwstream, &error) != PW_STREAM_STATE_STREAMING) goto done_unlock; - } do_send_buffer (pwsink, b); - gst_buffer_unref (b); if (pw_stream_is_driving (pwsink->stream->pwstream)) pw_loop_invoke(pw_stream_get_data_loop(pwsink->stream->pwstream),