videorate: Fix changing `rate` property during playback
authorThibault Saunier <tsaunier@igalia.com>
Sun, 31 May 2020 04:27:14 +0000 (00:27 -0400)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 1 Jun 2020 07:07:31 +0000 (07:07 +0000)
We need to take into account the base_ts to compute next_ts and it needs
to be updated on rate change.

This introduces `pending_rate` so that change rate is properly handled
in the streaming thread in a safe way.

Added tests

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

gst/videorate/gstvideorate.c
gst/videorate/gstvideorate.h
tests/validate/meson.build
tests/validate/videorate/change_rate_reverse_playback.validatetest [new file with mode: 0644]
tests/validate/videorate/change_rate_reverse_playback/flow-expectations/log-videorate-sink-expected [new file with mode: 0644]
tests/validate/videorate/change_rate_reverse_playback/flow-expectations/log-videorate-src-expected [new file with mode: 0644]
tests/validate/videorate/change_rate_while_playing.validatetest [new file with mode: 0644]
tests/validate/videorate/change_rate_while_playing/flow-expectations/log-videorate-sink-expected [new file with mode: 0644]
tests/validate/videorate/change_rate_while_playing/flow-expectations/log-videorate-src-expected [new file with mode: 0644]

index c67bc4b..e21497e 100644 (file)
@@ -633,6 +633,7 @@ gst_video_rate_init (GstVideoRate * videorate)
   videorate->average_period_set = DEFAULT_AVERAGE_PERIOD;
   videorate->max_rate = DEFAULT_MAX_RATE;
   videorate->rate = DEFAULT_RATE;
+  videorate->pending_rate = DEFAULT_RATE;
   videorate->max_duplication_time = DEFAULT_MAX_DUPLICATION_TIME;
 
   videorate->from_rate_numerator = 0;
@@ -1071,7 +1072,7 @@ gst_video_rate_query (GstBaseTransform * trans, GstPadDirection direction,
         break;
 
       GST_OBJECT_LOCK (videorate);
-      rate = videorate->rate;
+      rate = videorate->pending_rate;
       GST_OBJECT_UNLOCK (videorate);
 
       if (rate == 1.0)
@@ -1390,6 +1391,28 @@ gst_video_rate_do_max_duplicate (GstVideoRate * videorate, GstBuffer * buffer,
   return TRUE;
 }
 
+static gboolean
+gst_video_rate_apply_pending_rate (GstVideoRate * videorate)
+{
+  gboolean ret = FALSE;
+
+  GST_OBJECT_LOCK (videorate);
+  if (videorate->pending_rate == videorate->rate)
+    goto done;
+
+  ret = TRUE;
+  videorate->base_ts += gst_util_uint64_scale (videorate->out_frame_count,
+      videorate->to_rate_denominator * GST_SECOND,
+      videorate->to_rate_numerator);
+  videorate->rate = videorate->pending_rate;
+  videorate->out_frame_count = 0;
+
+done:
+  GST_OBJECT_UNLOCK (videorate);
+
+  return ret;
+}
+
 static GstFlowReturn
 gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
 {
@@ -1415,6 +1438,7 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
   if (videorate->average_period > 0)
     return gst_video_rate_trans_ip_max_avg (videorate, buffer);
 
+  gst_video_rate_apply_pending_rate (videorate);
   in_ts = GST_BUFFER_TIMESTAMP (buffer);
   in_dur = GST_BUFFER_DURATION (buffer);
 
@@ -1553,6 +1577,9 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
     do {
       GstClockTime next_ts;
 
+      if (gst_video_rate_apply_pending_rate (videorate))
+        goto done;
+
       if (videorate->segment.rate < 0.0) {
         /* Make sure that we have a duration for this buffer. The previous
          * buffer already has a duration given by either exactly this code,
@@ -1576,7 +1603,7 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
       if (videorate->segment.rate < 0.0) {
         GstClockTime next_end_ts;
         GstClockTime prev_endtime;
-        GstClockTime in_endtime;
+        GstClockTime in_endtime, base_ts_in_segment;
 
         next_ts = videorate->next_ts;
 
@@ -1597,8 +1624,12 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
         } else {
           next_end_ts = next_ts + GST_BUFFER_DURATION (videorate->prevbuf);
         }
-        next_ts *= videorate->rate;
-        next_end_ts *= videorate->rate;
+
+        base_ts_in_segment = videorate->segment.stop - videorate->base_ts;
+        next_ts = base_ts_in_segment - (
+            (base_ts_in_segment - next_ts) * videorate->rate);
+        next_end_ts = base_ts_in_segment - (MAX (0,
+                (base_ts_in_segment - next_end_ts)) * videorate->rate);
 
         diff1 = ABSDIFF (prev_endtime, next_end_ts);
         diff2 = ABSDIFF (in_endtime, next_end_ts);
@@ -1609,7 +1640,9 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
             GST_TIME_ARGS (diff1), GST_TIME_ARGS (diff2),
             GST_TIME_ARGS (next_end_ts));
       } else {
-        next_ts = videorate->next_ts * videorate->rate;
+        next_ts =
+            videorate->base_ts + ((videorate->next_ts -
+                videorate->base_ts) * videorate->rate);
 
         diff1 = ABSDIFF (prevtime, next_ts);
         diff2 = ABSDIFF (intime, next_ts);
@@ -1743,7 +1776,7 @@ gst_video_rate_set_property (GObject * object,
       g_atomic_int_set (&videorate->max_rate, g_value_get_int (value));
       goto reconfigure;
     case PROP_RATE:
-      videorate->rate = g_value_get_double (value);
+      videorate->pending_rate = g_value_get_double (value);
       GST_OBJECT_UNLOCK (videorate);
 
       gst_videorate_update_duration (videorate);
@@ -1808,7 +1841,7 @@ gst_video_rate_get_property (GObject * object,
       g_value_set_int (value, g_atomic_int_get (&videorate->max_rate));
       break;
     case PROP_RATE:
-      g_value_set_double (value, videorate->rate);
+      g_value_set_double (value, videorate->pending_rate);
       break;
     case PROP_MAX_DUPLICATION_TIME:
       g_value_set_uint64 (value, videorate->max_duplication_time);
index 18f9d98..cafff0d 100644 (file)
@@ -72,6 +72,7 @@ struct _GstVideoRate
 
   volatile int max_rate;
   gdouble rate;
+  gdouble pending_rate;
 };
 
 G_END_DECLS
index 44934c8..d258210 100644 (file)
@@ -15,6 +15,8 @@ tests = [
     'videorate/reverse.1_to_10fps',
     'videorate/reverse.30fps',
     'videorate/reverse.variable_to_10fps',
+    'videorate/change_rate_while_playing',
+    'videorate/change_rate_reverse_playback',
 ]
 
 env = environment()
diff --git a/tests/validate/videorate/change_rate_reverse_playback.validatetest b/tests/validate/videorate/change_rate_reverse_playback.validatetest
new file mode 100644 (file)
index 0000000..9230d6d
--- /dev/null
@@ -0,0 +1,50 @@
+meta,
+    # Handle EOS ourself
+    ignore-eos=true,
+    args = {
+        # We just want each frame to be different, and we just check their content by 'id'
+        "videotestsrc ! video/x-raw,framerate=10/1,width=320,height=240 ! videorate name=videorate ! fakesink sync=true qos=true",
+    },
+    configs = {
+        # Check dataflow on both videorate pads
+        "$(validateflow), pad=videorate:sink, buffers-checksum=as-id, ignored-event-types={ tag }",
+        "$(validateflow), pad=videorate:src, buffers-checksum=as-id, ignored-event-types={ tag }",
+    }
+
+seek, start=0.0, stop=5.0, flags=accurate+flush, rate=-1.0
+
+# Crank the 5 first buffers and check position is `seek.stop - (5*(1/10fps)) = 4.5s`
+crank-clock, expected-time=0.0
+crank-clock, repeat=4, expected-elapsed-time=0.1
+crank-clock, expected-time=0.5
+
+# Ensure next buffer flows for expectations stability
+wait, on-clock=true
+
+# Set videorate.rate = 0.5 and add that info to the expecation files for better readability
+checkpoint, text="Setting videorate.rate=0.5"
+set-property, playback-time=99.0, target-element-name=videorate, property-name=rate, property-value="0.5" # playback-time=99.0 so that the action is executed asap but no on element addition
+
+# Cranking 5 times, and let following buffer through
+crank-clock, repeat=5, expected-elapsed-time=0.1
+wait, on-clock=true
+check-position, expected-position=4.0 # seek.stop - (10*(1/10fps)) = 4.0s
+
+set-vars, rate=(string)0.1
+checkpoint, text="Setting videorate.rate=0.1"
+set-property, playback-time=99.0, target-element-name=videorate, property-name=rate, property-value="0.1"
+crank-clock, repeat=20
+wait, on-clock=true
+check-position, expected-position=2.0 # seek.stop - (20*(1/10fps)) = 2.0s
+
+# Now setting rate=2.0
+checkpoint, text="Setting videorate.rate=2.0"
+set-property, playback-time=-1, target-element-name=videorate, property-name=rate, property-value="2.0"
+crank-clock, repeat=10
+wait, on-clock=true
+
+# Source is now EOS, videorate is filling up the segment with last buffer
+checkpoint, text="Filling up segment with last buffer"
+crank-clock, repeat=10
+
+stop, on-message=eos
diff --git a/tests/validate/videorate/change_rate_reverse_playback/flow-expectations/log-videorate-sink-expected b/tests/validate/videorate/change_rate_reverse_playback/flow-expectations/log-videorate-sink-expected
new file mode 100644 (file)
index 0000000..942956c
--- /dev/null
@@ -0,0 +1,72 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=1, pts=0:00:00.100000000, dur=0:00:00.100000000
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:05.000000000, rate=-1.000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:05.000000000
+buffer: content-id=2, pts=0:00:05.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=3, pts=0:00:04.900000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=4, pts=0:00:04.800000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=5, pts=0:00:04.700000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=6, pts=0:00:04.600000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=7, pts=0:00:04.500000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=8, pts=0:00:04.400000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=9, pts=0:00:04.300000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=10, pts=0:00:04.200000000, dur=0:00:00.100000000, flags=discont
+
+CHECKPOINT: Setting videorate.rate=0.5
+
+buffer: content-id=11, pts=0:00:04.100000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=12, pts=0:00:04.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=13, pts=0:00:03.900000000, dur=0:00:00.100000000, flags=discont
+
+CHECKPOINT: Setting videorate.rate=0.1
+
+buffer: content-id=14, pts=0:00:03.800000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=15, pts=0:00:03.700000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=16, pts=0:00:03.600000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=17, pts=0:00:03.500000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=18, pts=0:00:03.400000000, dur=0:00:00.100000000, flags=discont
+
+CHECKPOINT: Setting videorate.rate=2.0
+
+buffer: content-id=19, pts=0:00:03.300000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=20, pts=0:00:03.200000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=21, pts=0:00:03.100000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=22, pts=0:00:03.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=23, pts=0:00:02.900000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=24, pts=0:00:02.800000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=25, pts=0:00:02.700000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=26, pts=0:00:02.600000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=27, pts=0:00:02.500000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=28, pts=0:00:02.400000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=29, pts=0:00:02.300000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=30, pts=0:00:02.200000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=31, pts=0:00:02.100000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=32, pts=0:00:02.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=33, pts=0:00:01.900000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=34, pts=0:00:01.800000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=35, pts=0:00:01.700000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=36, pts=0:00:01.600000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=37, pts=0:00:01.500000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=38, pts=0:00:01.400000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=39, pts=0:00:01.300000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=40, pts=0:00:01.200000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=41, pts=0:00:01.100000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=42, pts=0:00:01.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=43, pts=0:00:00.900000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=44, pts=0:00:00.800000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=45, pts=0:00:00.700000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=46, pts=0:00:00.600000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=47, pts=0:00:00.500000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=48, pts=0:00:00.400000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=49, pts=0:00:00.300000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=50, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=51, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=52, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont
+event eos: (no structure)
+
+CHECKPOINT: Filling up segment with last buffer
+
diff --git a/tests/validate/videorate/change_rate_reverse_playback/flow-expectations/log-videorate-src-expected b/tests/validate/videorate/change_rate_reverse_playback/flow-expectations/log-videorate-src-expected
new file mode 100644 (file)
index 0000000..aa01bb1
--- /dev/null
@@ -0,0 +1,70 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:05.000000000, rate=-1.000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:05.000000000
+buffer: content-id=3, pts=0:00:04.900000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=4, pts=0:00:04.800000000, dur=0:00:00.100000000
+buffer: content-id=5, pts=0:00:04.700000000, dur=0:00:00.100000000
+buffer: content-id=6, pts=0:00:04.600000000, dur=0:00:00.100000000
+buffer: content-id=7, pts=0:00:04.500000000, dur=0:00:00.100000000
+buffer: content-id=8, pts=0:00:04.400000000, dur=0:00:00.100000000
+buffer: content-id=9, pts=0:00:04.300000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=0.5
+
+buffer: content-id=9, pts=0:00:04.200000000, dur=0:00:00.100000000
+buffer: content-id=11, pts=0:00:04.100000000, dur=0:00:00.100000000
+buffer: content-id=11, pts=0:00:04.000000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=11, pts=0:00:03.900000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=12, pts=0:00:03.800000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=0.1
+
+buffer: content-id=15, pts=0:00:03.700000000, dur=0:00:00.100000000
+buffer: content-id=15, pts=0:00:03.600000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=15, pts=0:00:03.500000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=15, pts=0:00:03.400000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=15, pts=0:00:03.300000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=15, pts=0:00:03.200000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:03.100000000, dur=0:00:00.100000000
+buffer: content-id=16, pts=0:00:03.000000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.900000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.800000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.700000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.600000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.500000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.400000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.300000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=16, pts=0:00:02.200000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=17, pts=0:00:02.100000000, dur=0:00:00.100000000
+buffer: content-id=17, pts=0:00:02.000000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=17, pts=0:00:01.900000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=17, pts=0:00:01.800000000, dur=0:00:00.100000000, flags=gap
+
+CHECKPOINT: Setting videorate.rate=2.0
+
+buffer: content-id=35, pts=0:00:01.700000000, dur=0:00:00.100000000
+buffer: content-id=37, pts=0:00:01.600000000, dur=0:00:00.100000000
+buffer: content-id=39, pts=0:00:01.500000000, dur=0:00:00.100000000
+buffer: content-id=41, pts=0:00:01.400000000, dur=0:00:00.100000000
+buffer: content-id=43, pts=0:00:01.300000000, dur=0:00:00.100000000
+buffer: content-id=45, pts=0:00:01.200000000, dur=0:00:00.100000000
+buffer: content-id=47, pts=0:00:01.100000000, dur=0:00:00.100000000
+buffer: content-id=49, pts=0:00:01.000000000, dur=0:00:00.100000000
+buffer: content-id=51, pts=0:00:00.900000000, dur=0:00:00.100000000
+buffer: content-id=52, pts=0:00:00.800000000, dur=0:00:00.100000000
+
+CHECKPOINT: Filling up segment with last buffer
+
+buffer: content-id=52, pts=0:00:00.700000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.600000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.500000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.400000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.300000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=52, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=gap
+event eos: (no structure)
diff --git a/tests/validate/videorate/change_rate_while_playing.validatetest b/tests/validate/videorate/change_rate_while_playing.validatetest
new file mode 100644 (file)
index 0000000..125153e
--- /dev/null
@@ -0,0 +1,40 @@
+meta,
+    args = {
+        # We just want each frame to be different, and we just check their content by 'id'
+        "videotestsrc ! video/x-raw,framerate=10/1,width=320,height=240 ! videorate name=videorate ! fakesink sync=true qos=true",
+    },
+    configs = {
+        # Check dataflow on both videorate pads
+        "$(validateflow), pad=videorate:sink, buffers-checksum=as-id, ignored-event-types={ tag }",
+        "$(validateflow), pad=videorate:src, buffers-checksum=as-id, ignored-event-types={ tag }",
+    }
+
+# Crank the 5 first buffers and check position is `5*(1/10fps)) = 0.5s`
+crank-clock, expected-time=0.0
+crank-clock, repeat=5
+check-position, expected-position=0.5
+
+# Ensure next buffer flows for expectations stability
+wait, on-clock=true
+
+checkpoint, text="Setting videorate.rate=0.5"
+set-property, playback-time=0.5, target-element-name=videorate, property-name=rate, property-value="0.5"
+crank-clock, repeat=5
+check-position, expected-position=1.0
+
+wait, on-clock=true
+
+checkpoint, text="Setting videorate.rate=0.1"
+set-property, playback-time=1.0, target-element-name=videorate, property-name=rate, property-value="0.1"
+crank-clock, repeat=20
+check-position, expected-position=3.0
+
+wait, on-clock=true
+
+checkpoint, text="Setting videorate.rate=2.0"
+set-property, playback-time=2.0, target-element-name=videorate, property-name=rate, property-value="2.0"
+crank-clock, repeat=10
+check-position, expected-position=4.0
+
+wait, on-clock=true
+stop
\ No newline at end of file
diff --git a/tests/validate/videorate/change_rate_while_playing/flow-expectations/log-videorate-sink-expected b/tests/validate/videorate/change_rate_while_playing/flow-expectations/log-videorate-sink-expected
new file mode 100644 (file)
index 0000000..281c0bc
--- /dev/null
@@ -0,0 +1,64 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=1, pts=0:00:00.100000000, dur=0:00:00.100000000
+buffer: content-id=2, pts=0:00:00.200000000, dur=0:00:00.100000000
+buffer: content-id=3, pts=0:00:00.300000000, dur=0:00:00.100000000
+buffer: content-id=4, pts=0:00:00.400000000, dur=0:00:00.100000000
+buffer: content-id=5, pts=0:00:00.500000000, dur=0:00:00.100000000
+buffer: content-id=6, pts=0:00:00.600000000, dur=0:00:00.100000000
+buffer: content-id=7, pts=0:00:00.700000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=0.5
+
+buffer: content-id=8, pts=0:00:00.800000000, dur=0:00:00.100000000
+buffer: content-id=9, pts=0:00:00.900000000, dur=0:00:00.100000000
+buffer: content-id=10, pts=0:00:01.000000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=0.1
+
+buffer: content-id=11, pts=0:00:01.100000000, dur=0:00:00.100000000
+buffer: content-id=12, pts=0:00:01.200000000, dur=0:00:00.100000000
+buffer: content-id=13, pts=0:00:01.300000000, dur=0:00:00.100000000
+buffer: content-id=14, pts=0:00:01.400000000, dur=0:00:00.100000000
+buffer: content-id=15, pts=0:00:01.500000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=2.0
+
+buffer: content-id=16, pts=0:00:01.600000000, dur=0:00:00.100000000
+buffer: content-id=17, pts=0:00:01.700000000, dur=0:00:00.100000000
+buffer: content-id=18, pts=0:00:01.800000000, dur=0:00:00.100000000
+buffer: content-id=19, pts=0:00:01.900000000, dur=0:00:00.100000000
+buffer: content-id=20, pts=0:00:02.000000000, dur=0:00:00.100000000
+buffer: content-id=21, pts=0:00:02.100000000, dur=0:00:00.100000000
+buffer: content-id=22, pts=0:00:02.200000000, dur=0:00:00.100000000
+buffer: content-id=23, pts=0:00:02.300000000, dur=0:00:00.100000000
+buffer: content-id=24, pts=0:00:02.400000000, dur=0:00:00.100000000
+buffer: content-id=25, pts=0:00:02.500000000, dur=0:00:00.100000000
+buffer: content-id=26, pts=0:00:02.600000000, dur=0:00:00.100000000
+buffer: content-id=27, pts=0:00:02.700000000, dur=0:00:00.100000000
+buffer: content-id=28, pts=0:00:02.800000000, dur=0:00:00.100000000
+buffer: content-id=29, pts=0:00:02.900000000, dur=0:00:00.100000000
+buffer: content-id=30, pts=0:00:03.000000000, dur=0:00:00.100000000
+buffer: content-id=31, pts=0:00:03.100000000, dur=0:00:00.100000000
+buffer: content-id=32, pts=0:00:03.200000000, dur=0:00:00.100000000
+buffer: content-id=33, pts=0:00:03.300000000, dur=0:00:00.100000000
+buffer: content-id=34, pts=0:00:03.400000000, dur=0:00:00.100000000
+buffer: content-id=35, pts=0:00:03.500000000, dur=0:00:00.100000000
+buffer: content-id=36, pts=0:00:03.600000000, dur=0:00:00.100000000
+buffer: content-id=37, pts=0:00:03.700000000, dur=0:00:00.100000000
+buffer: content-id=38, pts=0:00:03.800000000, dur=0:00:00.100000000
+buffer: content-id=39, pts=0:00:03.900000000, dur=0:00:00.100000000
+buffer: content-id=40, pts=0:00:04.000000000, dur=0:00:00.100000000
+buffer: content-id=41, pts=0:00:04.100000000, dur=0:00:00.100000000
+buffer: content-id=42, pts=0:00:04.200000000, dur=0:00:00.100000000
+buffer: content-id=43, pts=0:00:04.300000000, dur=0:00:00.100000000
+buffer: content-id=44, pts=0:00:04.400000000, dur=0:00:00.100000000
+buffer: content-id=45, pts=0:00:04.500000000, dur=0:00:00.100000000
+buffer: content-id=46, pts=0:00:04.600000000, dur=0:00:00.100000000
+buffer: content-id=47, pts=0:00:04.700000000, dur=0:00:00.100000000
+buffer: content-id=48, pts=0:00:04.800000000, dur=0:00:00.100000000
+buffer: content-id=49, pts=0:00:04.900000000, dur=0:00:00.100000000
+buffer: content-id=50, pts=0:00:05.000000000, dur=0:00:00.100000000
+buffer: content-id=51, pts=0:00:05.100000000, dur=0:00:00.100000000
diff --git a/tests/validate/videorate/change_rate_while_playing/flow-expectations/log-videorate-src-expected b/tests/validate/videorate/change_rate_while_playing/flow-expectations/log-videorate-src-expected
new file mode 100644 (file)
index 0000000..3124182
--- /dev/null
@@ -0,0 +1,54 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont
+buffer: content-id=1, pts=0:00:00.100000000, dur=0:00:00.100000000
+buffer: content-id=2, pts=0:00:00.200000000, dur=0:00:00.100000000
+buffer: content-id=3, pts=0:00:00.300000000, dur=0:00:00.100000000
+buffer: content-id=4, pts=0:00:00.400000000, dur=0:00:00.100000000
+buffer: content-id=5, pts=0:00:00.500000000, dur=0:00:00.100000000
+buffer: content-id=6, pts=0:00:00.600000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=0.5
+
+buffer: content-id=6, pts=0:00:00.700000000, dur=0:00:00.100000000
+buffer: content-id=8, pts=0:00:00.800000000, dur=0:00:00.100000000
+buffer: content-id=8, pts=0:00:00.900000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=8, pts=0:00:01.000000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=9, pts=0:00:01.100000000, dur=0:00:00.100000000
+
+CHECKPOINT: Setting videorate.rate=0.1
+
+buffer: content-id=12, pts=0:00:01.200000000, dur=0:00:00.100000000
+buffer: content-id=12, pts=0:00:01.300000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=12, pts=0:00:01.400000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=12, pts=0:00:01.500000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=12, pts=0:00:01.600000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=12, pts=0:00:01.700000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:01.800000000, dur=0:00:00.100000000
+buffer: content-id=13, pts=0:00:01.900000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.000000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.100000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.200000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.300000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.400000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.500000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.600000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=13, pts=0:00:02.700000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=14, pts=0:00:02.800000000, dur=0:00:00.100000000
+buffer: content-id=14, pts=0:00:02.900000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=14, pts=0:00:03.000000000, dur=0:00:00.100000000, flags=gap
+buffer: content-id=14, pts=0:00:03.100000000, dur=0:00:00.100000000, flags=gap
+
+CHECKPOINT: Setting videorate.rate=2.0
+
+buffer: content-id=32, pts=0:00:03.200000000, dur=0:00:00.100000000
+buffer: content-id=34, pts=0:00:03.300000000, dur=0:00:00.100000000
+buffer: content-id=36, pts=0:00:03.400000000, dur=0:00:00.100000000
+buffer: content-id=38, pts=0:00:03.500000000, dur=0:00:00.100000000
+buffer: content-id=40, pts=0:00:03.600000000, dur=0:00:00.100000000
+buffer: content-id=42, pts=0:00:03.700000000, dur=0:00:00.100000000
+buffer: content-id=44, pts=0:00:03.800000000, dur=0:00:00.100000000
+buffer: content-id=46, pts=0:00:03.900000000, dur=0:00:00.100000000
+buffer: content-id=48, pts=0:00:04.000000000, dur=0:00:00.100000000
+buffer: content-id=50, pts=0:00:04.100000000, dur=0:00:00.100000000