diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index e21497ebfb..567b6c00b1 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -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, ×tamp); + + 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; diff --git a/tests/validate/meson.build b/tests/validate/meson.build index d25821044c..6e89aedc55 100644 --- a/tests/validate/meson.build +++ b/tests/validate/meson.build @@ -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 index 0000000000..7a96680aaa --- /dev/null +++ b/tests/validate/videorate/check-rate-prop.meta @@ -0,0 +1,22 @@ +# Common metadatas to check the videorate element behavior with different +# framerate specified by previously setting variables with: +# ``` +# set-global, rate=, 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 index 0000000000..9d076d41b8 --- /dev/null +++ b/tests/validate/videorate/rate_0_5.validatetest @@ -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 index 0000000000..ff2a359484 --- /dev/null +++ b/tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-sink-expected @@ -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 index 0000000000..8632e997d3 --- /dev/null +++ b/tests/validate/videorate/rate_0_5/flow-expectations/log-videorate-src-expected @@ -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 index 0000000000..a0d9f0b900 --- /dev/null +++ b/tests/validate/videorate/rate_0_5_with_decoder.validatetest @@ -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 index 0000000000..75fed7040f --- /dev/null +++ b/tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-sink-expected @@ -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 index 0000000000..3808aad3e8 --- /dev/null +++ b/tests/validate/videorate/rate_0_5_with_decoder/flow-expectations/log-videorate-src-expected @@ -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 index 0000000000..9f0965a154 --- /dev/null +++ b/tests/validate/videorate/rate_2_0.validatetest @@ -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 index 0000000000..2d38a5e1a0 --- /dev/null +++ b/tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-sink-expected @@ -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 index 0000000000..3c3079bdf4 --- /dev/null +++ b/tests/validate/videorate/rate_2_0/flow-expectations/log-videorate-src-expected @@ -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 index 0000000000..a0d9f0b900 --- /dev/null +++ b/tests/validate/videorate/rate_2_0_with_decoder.validatetest @@ -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 index 0000000000..75fed7040f --- /dev/null +++ b/tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-sink-expected @@ -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 index 0000000000..3808aad3e8 --- /dev/null +++ b/tests/validate/videorate/rate_2_0_with_decoder/flow-expectations/log-videorate-src-expected @@ -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