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.

(cherry picked from commit 49300d8ee0)
This commit is contained in:
Robert Mader 2026-03-03 20:51:58 +01:00
parent 0d14f44f47
commit e208a465ea

View file

@ -1592,22 +1592,23 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
if (pwsrc->eos) { if (pwsrc->eos) {
if (pwsrc->last_buffer == NULL) if (pwsrc->last_buffer == NULL)
goto streaming_eos; goto streaming_eos;
buf = pwsrc->last_buffer; buf = gst_buffer_steal (&pwsrc->last_buffer);
pwsrc->last_buffer = NULL;
update_time = TRUE; update_time = TRUE;
GST_LOG_OBJECT (pwsrc, "EOS, send last buffer"); GST_LOG_OBJECT (pwsrc, "EOS, send last buffer");
break; break;
} else if (timeout && pwsrc->last_buffer != NULL) { } else if (timeout && pwsrc->last_buffer != NULL) {
buf = gst_buffer_copy (pwsrc->last_buffer);
update_time = TRUE; update_time = TRUE;
buf = gst_buffer_ref(pwsrc->last_buffer);
GST_LOG_OBJECT (pwsrc, "timeout, send keepalive buffer"); GST_LOG_OBJECT (pwsrc, "timeout, send keepalive buffer");
break; break;
} else { } else {
buf = dequeue_buffer (pwsrc); buf = dequeue_buffer (pwsrc);
GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf); GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf);
if (buf != NULL) { if (buf != NULL) {
if (pwsrc->resend_last || pwsrc->keepalive_time > 0) if (pwsrc->resend_last || pwsrc->keepalive_time > 0) {
gst_buffer_replace (&pwsrc->last_buffer, buf); gst_buffer_take (&pwsrc->last_buffer, gst_buffer_copy (buf));
gst_buffer_add_parent_buffer_meta (pwsrc->last_buffer, buf);
}
break; break;
} }
} }