videorate: Update QoS events taking into account our rate

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>
This commit is contained in:
Thibault Saunier 2020-05-29 16:21:11 -04:00 committed by GStreamer Merge Bot
parent 6499e2afa5
commit 0c75ea0858
15 changed files with 190 additions and 0 deletions

View 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;

View 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()

View file

@ -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

View file

@ -0,0 +1,3 @@
set-globals, rate=(string)"0.5", decoder="!"
include, location="check-rate-prop.meta"

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
set-globals, rate=(string)"2.0", decoder="!"
include, location="check-rate-prop.meta"

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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