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.
This commit is contained in:
Robert Mader 2026-03-03 20:51:58 +01:00
parent a3853c2c3d
commit 49300d8ee0

View file

@ -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;
}
}