gst: pipewiresink: fix provide mode for virtual camera usage

This commit is contained in:
Morgan 2026-03-04 10:05:32 +09:00
parent a3853c2c3d
commit 661aae1ae5
No known key found for this signature in database

View file

@ -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, &params);
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),