mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
videodecoder: Only drain in KEY_UNITS trick mode after a keyframe in forwards playback mode
For reverse playback the same behaviour was already implemented in flush_parse(). For reverse playback, chain_forward() is only used to gather frames and not for decoding, and it is actually called by the draining logic, causing an infinite recursion.
This commit is contained in:
parent
8bee96c4a2
commit
0c7022d681
1 changed files with 10 additions and 2 deletions
|
@ -2179,6 +2179,9 @@ gst_video_decoder_chain_forward (GstVideoDecoder * decoder,
|
||||||
|
|
||||||
g_return_val_if_fail (priv->packetized || klass->parse, GST_FLOW_ERROR);
|
g_return_val_if_fail (priv->packetized || klass->parse, GST_FLOW_ERROR);
|
||||||
|
|
||||||
|
/* Draining on DISCONT is handled in chain_reverse() for reverse playback,
|
||||||
|
* and this function would only be called to get everything collected GOP
|
||||||
|
* by GOP in the parse_gather list */
|
||||||
if (decoder->input_segment.rate > 0.0 && GST_BUFFER_IS_DISCONT (buf))
|
if (decoder->input_segment.rate > 0.0 && GST_BUFFER_IS_DISCONT (buf))
|
||||||
ret = gst_video_decoder_drain_out (decoder, FALSE);
|
ret = gst_video_decoder_drain_out (decoder, FALSE);
|
||||||
|
|
||||||
|
@ -2207,8 +2210,13 @@ gst_video_decoder_chain_forward (GstVideoDecoder * decoder,
|
||||||
}
|
}
|
||||||
priv->current_frame = NULL;
|
priv->current_frame = NULL;
|
||||||
/* If in trick mode and it was a keyframe, drain decoder to avoid extra
|
/* If in trick mode and it was a keyframe, drain decoder to avoid extra
|
||||||
* latency */
|
* latency. Only do this for forwards playback as reverse playback handles
|
||||||
if (was_keyframe
|
* draining on keyframes in flush_parse(), and would otherwise call back
|
||||||
|
* from drain_out() to here causing an infinite loop.
|
||||||
|
* Also this function is only called for reverse playback to gather frames
|
||||||
|
* GOP by GOP, and does not do any actual decoding. That would be done by
|
||||||
|
* flush_decode() */
|
||||||
|
if (was_keyframe && decoder->output_segment.rate > 0.0
|
||||||
&& (decoder->output_segment.flags & GST_SEEK_FLAG_TRICKMODE_KEY_UNITS))
|
&& (decoder->output_segment.flags & GST_SEEK_FLAG_TRICKMODE_KEY_UNITS))
|
||||||
gst_video_decoder_drain_out (decoder, FALSE);
|
gst_video_decoder_drain_out (decoder, FALSE);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue