videorate: Update QoS events taking into account our rate
authorThibault Saunier <tsaunier@igalia.com>
Fri, 29 May 2020 20:21:11 +0000 (16:21 -0400)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 1 Jun 2020 07:07:31 +0000 (07:07 +0000)
Otherwise there is a mismatch between the QoS values and what upstream
would expect, leading to too much buffer dropping in video decoders in
case rate < 1.0 or not enough buffer dropping in case rate > 1.0

Adding validate tests with and without decoders.

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

15 files changed:
gst/videorate/gstvideorate.c
tests/validate/meson.build
tests/validate/videorate/check-rate-prop.meta [new file with mode: 0644]
tests/validate/videorate/rate_0_5.validatetest [new file with mode: 0644]
tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-sink-expected [new file with mode: 0644]
tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-src-expected [new file with mode: 0644]
tests/validate/videorate/rate_0_5_with_decoder.validatetest [new file with mode: 0644]
tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-sink-expected [new file with mode: 0644]
tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-src-expected [new file with mode: 0644]
tests/validate/videorate/rate_2_0.validatetest [new file with mode: 0644]
tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-sink-expected [new file with mode: 0644]
tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-src-expected [new file with mode: 0644]
tests/validate/videorate/rate_2_0_with_decoder.validatetest [new file with mode: 0644]
tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-sink-expected [new file with mode: 0644]
tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-src-expected [new file with mode: 0644]

index e21497e..567b6c0 100644 (file)
@@ -981,6 +981,43 @@ gst_video_rate_src_event (GstBaseTransform * trans, GstEvent * event)
       res = gst_pad_push_event (sinkpad, event);
       break;
     }
+    case GST_EVENT_QOS:
+    {
+      GstQOSType type;
+      gdouble proportion;
+      GstClockTimeDiff diff;
+      GstClockTime timestamp;
+
+      gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
+
+      if (GST_CLOCK_TIME_IS_VALID (timestamp) && videorate->rate != 1.0) {
+        GST_OBJECT_LOCK (trans);
+        GST_DEBUG_OBJECT (trans, "Rescaling QoS event taking our rate into"
+            "account. Timestamp:  %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT
+            " - diff %" G_GINT64_FORMAT "-> %" G_GINT64_FORMAT,
+            GST_TIME_ARGS (timestamp),
+            GST_TIME_ARGS (videorate->base_ts + ((timestamp -
+                        videorate->base_ts) * videorate->rate)), diff,
+            (GstClockTimeDiff) (diff * videorate->rate));
+
+        if (videorate->segment.rate < 0.0)
+          timestamp =
+              (videorate->segment.stop - videorate->base_ts) -
+              ((videorate->segment.stop - videorate->base_ts -
+                  timestamp) * videorate->rate);
+        else
+          timestamp =
+              videorate->base_ts + ((timestamp -
+                  videorate->base_ts) * videorate->rate);
+
+        diff *= videorate->rate;
+        GST_OBJECT_UNLOCK (trans);
+
+        gst_event_unref (event);
+        event = gst_event_new_qos (type, proportion, diff, timestamp);
+      }
+      /* Fallthrough */
+    }
     default:
       res = gst_pad_push_event (sinkpad, event);
       break;
index d258210..6e89aed 100644 (file)
@@ -17,6 +17,10 @@ tests = [
     'videorate/reverse.variable_to_10fps',
     'videorate/change_rate_while_playing',
     'videorate/change_rate_reverse_playback',
+    'videorate/rate_0_5',
+    'videorate/rate_0_5_with_decoder',
+    'videorate/rate_2_0',
+    'videorate/rate_2_0_with_decoder',
 ]
 
 env = environment()
diff --git a/tests/validate/videorate/check-rate-prop.meta b/tests/validate/videorate/check-rate-prop.meta
new file mode 100644 (file)
index 0000000..7a96680
--- /dev/null
@@ -0,0 +1,22 @@
+# Common metadatas to check the videorate element behavior with different
+# framerate specified by previously setting variables with:
+# ```
+# set-global, rate=<test-rate>, decoder=<decoder>
+# ```
+# and then `include, location="check-rate-prop.meta" to setup the test with this
+# file
+
+meta,
+    args = {
+        "videotestsrc pattern=ball animation-mode=frames ! video/x-raw,framerate=30/1,width=320,height=240 $(decoder) videorate name=videorate rate=$(rate) ! fakesink sync=true qos=true",
+    },
+    configs = {
+       "$(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-clock, expected-time=0.0
+crank-clock, repeat=9
+wait, on-clock=true
+check-position, expected-position=300000000
+stop
\ No newline at end of file
diff --git a/tests/validate/videorate/rate_0_5.validatetest b/tests/validate/videorate/rate_0_5.validatetest
new file mode 100644 (file)
index 0000000..9d076d4
--- /dev/null
@@ -0,0 +1,3 @@
+set-globals, rate=(string)"0.5", decoder="!"
+
+include, location="check-rate-prop.meta"
diff --git a/tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-sink-expected b/tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-sink-expected
new file mode 100644 (file)
index 0000000..ff2a359
--- /dev/null
@@ -0,0 +1,10 @@
+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)30/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.033333333, flags=discont
+buffer: content-id=1, pts=0:00:00.033333333, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=3, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=4, pts=0:00:00.133333333, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.166666666, dur=0:00:00.033333334
+buffer: content-id=6, pts=0:00:00.200000000, dur=0:00:00.033333333
diff --git a/tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-src-expected b/tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-src-expected
new file mode 100644 (file)
index 0000000..8632e99
--- /dev/null
@@ -0,0 +1,14 @@
+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)30/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.033333333, flags=discont
+buffer: content-id=0, pts=0:00:00.033333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=1, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=2, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.133333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=2, pts=0:00:00.166666666, dur=0:00:00.033333334, flags=gap
+buffer: content-id=3, pts=0:00:00.200000000, dur=0:00:00.033333333
+buffer: content-id=3, pts=0:00:00.233333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=4, pts=0:00:00.266666666, dur=0:00:00.033333334
+buffer: content-id=5, pts=0:00:00.300000000, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.333333333, dur=0:00:00.033333333, flags=gap
diff --git a/tests/validate/videorate/rate_0_5_with_decoder.validatetest b/tests/validate/videorate/rate_0_5_with_decoder.validatetest
new file mode 100644 (file)
index 0000000..a0d9f0b
--- /dev/null
@@ -0,0 +1,5 @@
+# Using an encoder/decoder to test QoS handling
+# FIXME: Use a fakevideodec once merged!
+set-globals, rate=(string)"0.5", decoder="! theoraenc ! theoradec !"
+
+include, location="check-rate-prop.meta"
\ No newline at end of file
diff --git a/tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-sink-expected b/tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-sink-expected
new file mode 100644 (file)
index 0000000..75fed70
--- /dev/null
@@ -0,0 +1,10 @@
+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, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)1/1, chroma-site=(string)jpeg, colorimetry=(string)2:4:5:0, framerate=(fraction)30/1;
+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.033333333, flags=discont
+buffer: content-id=1, pts=0:00:00.033333333, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=3, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=4, pts=0:00:00.133333333, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.166666666, dur=0:00:00.033333334
+buffer: content-id=6, pts=0:00:00.200000000, dur=0:00:00.033333333
diff --git a/tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-src-expected b/tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-src-expected
new file mode 100644 (file)
index 0000000..3808aad
--- /dev/null
@@ -0,0 +1,14 @@
+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, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)1/1, chroma-site=(string)jpeg, colorimetry=(string)2:4:5:0, framerate=(fraction)30/1;
+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.033333333, flags=discont
+buffer: content-id=0, pts=0:00:00.033333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=1, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=2, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.133333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=2, pts=0:00:00.166666666, dur=0:00:00.033333334, flags=gap
+buffer: content-id=3, pts=0:00:00.200000000, dur=0:00:00.033333333
+buffer: content-id=3, pts=0:00:00.233333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=4, pts=0:00:00.266666666, dur=0:00:00.033333334
+buffer: content-id=5, pts=0:00:00.300000000, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.333333333, dur=0:00:00.033333333, flags=gap
diff --git a/tests/validate/videorate/rate_2_0.validatetest b/tests/validate/videorate/rate_2_0.validatetest
new file mode 100644 (file)
index 0000000..9f0965a
--- /dev/null
@@ -0,0 +1,3 @@
+set-globals, rate=(string)"2.0", decoder="!"
+
+include, location="check-rate-prop.meta"
\ No newline at end of file
diff --git a/tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-sink-expected b/tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-sink-expected
new file mode 100644 (file)
index 0000000..2d38a5e
--- /dev/null
@@ -0,0 +1,25 @@
+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)30/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.033333333, flags=discont
+buffer: content-id=1, pts=0:00:00.033333333, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=3, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=4, pts=0:00:00.133333333, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.166666666, dur=0:00:00.033333334
+buffer: content-id=6, pts=0:00:00.200000000, dur=0:00:00.033333333
+buffer: content-id=7, pts=0:00:00.233333333, dur=0:00:00.033333333
+buffer: content-id=8, pts=0:00:00.266666666, dur=0:00:00.033333334
+buffer: content-id=9, pts=0:00:00.300000000, dur=0:00:00.033333333
+buffer: content-id=10, pts=0:00:00.333333333, dur=0:00:00.033333333
+buffer: content-id=11, pts=0:00:00.366666666, dur=0:00:00.033333334
+buffer: content-id=12, pts=0:00:00.400000000, dur=0:00:00.033333333
+buffer: content-id=13, pts=0:00:00.433333333, dur=0:00:00.033333333
+buffer: content-id=14, pts=0:00:00.466666666, dur=0:00:00.033333334
+buffer: content-id=15, pts=0:00:00.500000000, dur=0:00:00.033333333
+buffer: content-id=16, pts=0:00:00.533333333, dur=0:00:00.033333333
+buffer: content-id=17, pts=0:00:00.566666666, dur=0:00:00.033333334
+buffer: content-id=18, pts=0:00:00.600000000, dur=0:00:00.033333333
+buffer: content-id=19, pts=0:00:00.633333333, dur=0:00:00.033333333
+buffer: content-id=20, pts=0:00:00.666666666, dur=0:00:00.033333334
+buffer: content-id=21, pts=0:00:00.700000000, dur=0:00:00.033333333
diff --git a/tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-src-expected b/tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-src-expected
new file mode 100644 (file)
index 0000000..3c3079b
--- /dev/null
@@ -0,0 +1,14 @@
+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)30/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.033333333, flags=discont
+buffer: content-id=2, pts=0:00:00.033333333, dur=0:00:00.033333333
+buffer: content-id=4, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=6, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=8, pts=0:00:00.133333333, dur=0:00:00.033333333
+buffer: content-id=10, pts=0:00:00.166666666, dur=0:00:00.033333334
+buffer: content-id=12, pts=0:00:00.200000000, dur=0:00:00.033333333
+buffer: content-id=14, pts=0:00:00.233333333, dur=0:00:00.033333333
+buffer: content-id=16, pts=0:00:00.266666666, dur=0:00:00.033333334
+buffer: content-id=18, pts=0:00:00.300000000, dur=0:00:00.033333333
+buffer: content-id=20, pts=0:00:00.333333333, dur=0:00:00.033333333
diff --git a/tests/validate/videorate/rate_2_0_with_decoder.validatetest b/tests/validate/videorate/rate_2_0_with_decoder.validatetest
new file mode 100644 (file)
index 0000000..a0d9f0b
--- /dev/null
@@ -0,0 +1,5 @@
+# Using an encoder/decoder to test QoS handling
+# FIXME: Use a fakevideodec once merged!
+set-globals, rate=(string)"0.5", decoder="! theoraenc ! theoradec !"
+
+include, location="check-rate-prop.meta"
\ No newline at end of file
diff --git a/tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-sink-expected b/tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-sink-expected
new file mode 100644 (file)
index 0000000..75fed70
--- /dev/null
@@ -0,0 +1,10 @@
+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, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)1/1, chroma-site=(string)jpeg, colorimetry=(string)2:4:5:0, framerate=(fraction)30/1;
+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.033333333, flags=discont
+buffer: content-id=1, pts=0:00:00.033333333, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=3, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=4, pts=0:00:00.133333333, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.166666666, dur=0:00:00.033333334
+buffer: content-id=6, pts=0:00:00.200000000, dur=0:00:00.033333333
diff --git a/tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-src-expected b/tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-src-expected
new file mode 100644 (file)
index 0000000..3808aad
--- /dev/null
@@ -0,0 +1,14 @@
+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, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)1/1, chroma-site=(string)jpeg, colorimetry=(string)2:4:5:0, framerate=(fraction)30/1;
+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.033333333, flags=discont
+buffer: content-id=0, pts=0:00:00.033333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=1, pts=0:00:00.066666666, dur=0:00:00.033333334
+buffer: content-id=2, pts=0:00:00.100000000, dur=0:00:00.033333333
+buffer: content-id=2, pts=0:00:00.133333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=2, pts=0:00:00.166666666, dur=0:00:00.033333334, flags=gap
+buffer: content-id=3, pts=0:00:00.200000000, dur=0:00:00.033333333
+buffer: content-id=3, pts=0:00:00.233333333, dur=0:00:00.033333333, flags=gap
+buffer: content-id=4, pts=0:00:00.266666666, dur=0:00:00.033333334
+buffer: content-id=5, pts=0:00:00.300000000, dur=0:00:00.033333333
+buffer: content-id=5, pts=0:00:00.333333333, dur=0:00:00.033333333, flags=gap