From 419bc600a883a63c9ce7e3a2191bd9c2597b9b09 Mon Sep 17 00:00:00 2001 From: Elliot Chen Date: Fri, 3 Jan 2025 14:38:54 +0900 Subject: [PATCH] pipewiresink: split buffer and send them in turn if needed For some streams, the buffer size is changed and may exceed the acquired buffer size which is acquired from the pool of pipewiresink. Need split buffer and send them in turn for this case. --- src/gst/gstpipewiresink.c | 64 ++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index 6441f12e2..b0564d539 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -822,7 +822,6 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GstPipeWireSink *pwsink; GstFlowReturn res = GST_FLOW_OK; const char *error = NULL; - gboolean unref_buffer = FALSE; pwsink = GST_PIPEWIRE_SINK (bsink); @@ -855,35 +854,52 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) goto done_unlock; if (buffer->pool != GST_BUFFER_POOL_CAST (pwsink->stream->pool)) { - GstBuffer *b = NULL; - GstMapInfo info = { 0, }; - GstBufferPoolAcquireParams params = { 0, }; + gsize offset = 0; + gsize buf_size = 0; + gst_buffer_get_sizes (buffer, NULL, &buf_size); - pw_thread_loop_unlock (pwsink->stream->core->loop); + /* For some streams, the buffer size is changed and may exceed the acquired + * 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; + GstMapInfo info = { 0, }; + GstBufferPoolAcquireParams params = { 0, }; - if ((res = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL_CAST (pwsink->stream->pool), &b, ¶ms)) != GST_FLOW_OK) - goto done; + pw_thread_loop_unlock (pwsink->stream->core->loop); - gst_buffer_map (b, &info, GST_MAP_WRITE); - gst_buffer_extract (buffer, 0, info.data, info.maxsize); - gst_buffer_unmap (b, &info); - gst_buffer_resize (b, 0, gst_buffer_get_size (buffer)); - gst_buffer_copy_into(b, buffer, GST_BUFFER_COPY_METADATA, 0, -1); - buffer = b; - unref_buffer = TRUE; + if ((res = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL_CAST (pwsink->stream->pool), + &b, ¶ms)) != GST_FLOW_OK) + goto done; - pw_thread_loop_lock (pwsink->stream->core->loop); - if (pw_stream_get_state (pwsink->stream->pwstream, &error) != PW_STREAM_STATE_STREAMING) - goto done_unlock; + gst_buffer_map (b, &info, GST_MAP_WRITE); + gsize extract_size = (buf_size <= info.maxsize) ? buf_size: info.maxsize; + gst_buffer_extract (buffer, offset, info.data, info.maxsize); + gst_buffer_unmap (b, &info); + gst_buffer_resize (b, 0, extract_size); + gst_buffer_copy_into(b, buffer, GST_BUFFER_COPY_METADATA, 0, -1); + buf_size -= extract_size; + offset += extract_size; + + 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); + goto done_unlock; + } + + do_send_buffer (pwsink, b); + gst_buffer_unref (b); + + if (pw_stream_is_driving (pwsink->stream->pwstream)) + pw_stream_trigger_process (pwsink->stream->pwstream); + } + } else { + do_send_buffer (pwsink, buffer); + + if (pw_stream_is_driving (pwsink->stream->pwstream)) + pw_stream_trigger_process (pwsink->stream->pwstream); } - do_send_buffer (pwsink, buffer); - if (unref_buffer) - gst_buffer_unref (buffer); - - if (pw_stream_is_driving (pwsink->stream->pwstream)) - pw_stream_trigger_process (pwsink->stream->pwstream); - done_unlock: pw_thread_loop_unlock (pwsink->stream->core->loop); done: