From 39b9cc554c960fec8d41f8394c41390883cadeed Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Thu, 23 Apr 2020 16:24:15 -0400 Subject: [PATCH] basesink: Fix clock synchronization running time in reverse playback In reverse playback, buffers have to be displayed at buffer.stop running time, otherwise a same set of buffer can't be displayed in the exact opposite order to forward playback. For example, seeking a video stream at 1fps with start=0, stop=5s, rate=1.0 will display the following buffers: b0.pts = 0s, b0.duration = 1s - at running time = 0s b1.pts = 1s, b1.duration = 1s - at running time = 1s b2.pts = 2s, b2.duration = 1s - at running time = 2s b3.pts = 3s, b3.duration = 1s - at running time = 3s b4.pts = 4s, b4.duration = 1s - at running time = 4s Now, playing that reverse with start=0, stop=5s, rate=1.0 has to display the following buffers: b0.pts = 4s, b0.duration = 1s - at running time = 0s b1.pts = 3s, b1.duration = 1s - at running time = 1s b2.pts = 2s, b2.duration = 1s - at running time = 2s b3.pts = 1s, b3.duration = 1s - at running time = 3s b4.pts = 0s, b4.duration = 1s - at running time = 4s With the previous code, it reproduced the following: b0.pts = 4s, b0.duration = 1s - at running time = 1s b1.pts = 3s, b1.duration = 1s - at running time = 2s b2.pts = 2s, b2.duration = 1s - at running time = 3s b3.pts = 1s, b3.duration = 1s - at running time = 4s b4.pts = 0s, b4.duration = 1s - at running time = 5s This is being tested with the `validate.launch_pipeline.sink.reverse_playback_clock_waits.*` set of tests Part-of: --- libs/gst/base/gstbasesink.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index c75dbcb16c..8bfc49563d 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -2197,6 +2197,13 @@ do_times: rstart = gst_segment_to_running_time (segment, format, cstart); rstop = gst_segment_to_running_time (segment, format, cstop); + /* In reverse playback, play from stop to start */ + if (segment->rate < 0.0 && GST_CLOCK_TIME_IS_VALID (rstop)) { + GstClockTime tmp = rstart; + rstart = rstop; + rstop = tmp; + } + if (GST_CLOCK_TIME_IS_VALID (stop)) rnext = rstop; else