From 86da3e11830f10358ddb6eac21cba72c645b34f3 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Tue, 3 Mar 2026 01:52:55 +0100 Subject: [PATCH] pipewiresrc: Use clock time difference to update last_buffer time Setting the current clock time when resending buffers is often wrong. Especially for pseudo-live sources - the default mode - it discards the original buffer time, which again is used by the base-class to adjust the timestamps further, ultimately resulting in very wrong timestamps. Instead, try to calculate the delta between when we originally got the buffer and now. (cherry picked from commit efd15264230b5b644a18a5f1a0c330dcdf5fb969) --- src/gst/gstpipewiresrc.c | 35 +++++++++++++++++++++++++++++------ src/gst/gstpipewiresrc.h | 1 + 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 0bcbe21a3..7394b7272 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -531,6 +531,7 @@ gst_pipewire_src_init (GstPipeWireSrc * src) src->autoconnect = DEFAULT_AUTOCONNECT; src->min_latency = 0; src->max_latency = GST_CLOCK_TIME_NONE; + src->last_buffer_clock_time = GST_CLOCK_TIME_NONE; src->n_buffers = 0; src->flushing_on_remove_buffer = FALSE; src->on_disconnect = DEFAULT_ON_DISCONNECT; @@ -1606,8 +1607,18 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf); if (buf != NULL) { if (pwsrc->resend_last || pwsrc->keepalive_time > 0) { + GstClock *clock; + gst_buffer_take (&pwsrc->last_buffer, gst_buffer_copy (buf)); gst_buffer_add_parent_buffer_meta (pwsrc->last_buffer, buf); + + clock = gst_element_get_clock (GST_ELEMENT_CAST (pwsrc)); + if (clock != NULL) { + pwsrc->last_buffer_clock_time = gst_clock_get_time (clock); + gst_object_unref (clock); + } else { + pwsrc->last_buffer_clock_time = GST_CLOCK_TIME_NONE; + } } break; } @@ -1633,21 +1644,33 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) if (update_time) { GstClock *clock; - GstClockTime pts, dts; + GstClockTime current_clock_time; clock = gst_element_get_clock (GST_ELEMENT_CAST (pwsrc)); if (clock != NULL) { - pts = dts = gst_clock_get_time (clock); + current_clock_time = gst_clock_get_time (clock); gst_object_unref (clock); } else { - pts = dts = GST_CLOCK_TIME_NONE; + current_clock_time = GST_CLOCK_TIME_NONE; } - GST_BUFFER_PTS (*buffer) = pts; - GST_BUFFER_DTS (*buffer) = dts; + if (GST_CLOCK_TIME_IS_VALID (current_clock_time) && + GST_CLOCK_TIME_IS_VALID (pwsrc->last_buffer_clock_time) && + GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (*buffer)) && + GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DTS (*buffer))) { + GstClockTime diff; + + diff = current_clock_time - pwsrc->last_buffer_clock_time; + + GST_BUFFER_PTS (*buffer) += diff; + GST_BUFFER_DTS (*buffer) += diff; + } else { + GST_BUFFER_PTS (*buffer) = GST_BUFFER_DTS (*buffer) = current_clock_time; + } GST_LOG_OBJECT (pwsrc, "Sending keepalive buffer pts/dts: %" GST_TIME_FORMAT - " (%" G_GUINT64_FORMAT ")", GST_TIME_ARGS (pts), pts); + " (%" G_GUINT64_FORMAT ")", GST_TIME_ARGS (current_clock_time), + current_clock_time); } return GST_FLOW_OK; diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index 869877fcb..4b0f57e0e 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -83,6 +83,7 @@ struct _GstPipeWireSrc { GstClockTime max_latency; GstBuffer *last_buffer; + GstClockTime last_buffer_clock_time; enum spa_meta_videotransform_value transform_value;