videorate: Fix buffer timestamp underflow in reverse playback
authorThibault Saunier <tsaunier@igalia.com>
Mon, 27 Apr 2020 13:57:30 +0000 (09:57 -0400)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 6 May 2020 16:50:01 +0000 (16:50 +0000)
And fix reverse playback buffer duration computation as in reverse
playback, buffer duration is prev_buffer.pts - buffer.pts not pts -
next_pts (buffers are displayed from buffer.pts + buffer.duration for
a duration of buffers.duration).

This is now tested with the `validate.test.clock_sync.videorate.*`
tests in the default integration testsuite where we check the exact
data flow and the synchronization on the clock behaviour with a
TestClock.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/646>

gst/videorate/gstvideorate.c

index 3a1945e..b2510e6 100644 (file)
@@ -673,14 +673,22 @@ gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
   if (videorate->segment.rate < 0.0) {
     if (videorate->to_rate_numerator) {
       /* interpolate next expected timestamp in the segment */
-      videorate->next_ts =
+      GstClockTimeDiff next_ts =
           videorate->segment.base + videorate->segment.stop -
           videorate->base_ts -
           gst_util_uint64_scale (videorate->out_frame_count + 1,
           videorate->to_rate_denominator * GST_SECOND,
           videorate->to_rate_numerator);
 
-      GST_BUFFER_DURATION (outbuf) = push_ts - videorate->next_ts;
+      videorate->next_ts = next_ts < 0 ? GST_CLOCK_TIME_NONE : next_ts;
+
+      GST_BUFFER_DURATION (outbuf) =
+          gst_util_uint64_scale (videorate->out_frame_count,
+          videorate->to_rate_denominator * GST_SECOND,
+          videorate->to_rate_numerator) -
+          gst_util_uint64_scale (videorate->out_frame_count - 1,
+          videorate->to_rate_denominator * GST_SECOND,
+          videorate->to_rate_numerator);
     } else if (next_intime != GST_CLOCK_TIME_NONE) {
       videorate->next_ts = next_intime;
     } else {