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.
This commit is contained in:
Robert Mader 2026-03-03 01:52:55 +01:00
parent 49300d8ee0
commit efd1526423
2 changed files with 30 additions and 6 deletions

View file

@ -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;
@ -1617,8 +1618,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;
}
@ -1644,21 +1655,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;

View file

@ -83,6 +83,7 @@ struct _GstPipeWireSrc {
GstClockTime max_latency;
GstBuffer *last_buffer;
GstClockTime last_buffer_clock_time;
enum spa_meta_videotransform_value transform_value;