From 49300d8ee0e997ecd67de73d9bfecaf0b952bf5b Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Tue, 3 Mar 2026 20:51:58 +0100 Subject: [PATCH] pipewiresrc: Take a copy instead of a reference for last_buffer Buffer timestamps get adjusted by the base class, GstBaseSrc, even if we take an additional ref. Arguably the base class should check if buffers are writable (gst_buffer_make_writable()), which would trigger a buffer copy. That is currently not the case, though, thus do so on our side. Notes: 1. Usually a buffer copy doesn't copy the underlying memory, i.e. copying is cheap. 2. The copy holds a reference to the copied buffer, preventing the buffer from getting recycled as before. --- src/gst/gstpipewiresrc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 1755a8d4f..2896d7f75 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -1603,22 +1603,23 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) if (pwsrc->eos) { if (pwsrc->last_buffer == NULL) goto streaming_eos; - buf = pwsrc->last_buffer; - pwsrc->last_buffer = NULL; + buf = gst_buffer_steal (&pwsrc->last_buffer); update_time = TRUE; GST_LOG_OBJECT (pwsrc, "EOS, send last buffer"); break; } else if (timeout && pwsrc->last_buffer != NULL) { + buf = gst_buffer_copy (pwsrc->last_buffer); update_time = TRUE; - buf = gst_buffer_ref(pwsrc->last_buffer); GST_LOG_OBJECT (pwsrc, "timeout, send keepalive buffer"); break; } else { buf = dequeue_buffer (pwsrc); GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf); if (buf != NULL) { - if (pwsrc->resend_last || pwsrc->keepalive_time > 0) - gst_buffer_replace (&pwsrc->last_buffer, buf); + if (pwsrc->resend_last || pwsrc->keepalive_time > 0) { + gst_buffer_take (&pwsrc->last_buffer, gst_buffer_copy (buf)); + gst_buffer_add_parent_buffer_meta (pwsrc->last_buffer, buf); + } break; } }