avvidec: Ensure skipping strategy gets properly reset

When switching playback modes, like from TRICKMODE or TRICKMODE_KEY_UNITS
back to regular playback, we need to make sure we set the skip mode
back to the default setting.

While this field would be properly reset when we *have* feedback from
downstream (i.e. diff != G_MAXINT64), it would not be reset during
the initial phase (i.e. when the decoder hasn't pushed a buffer yet,
and therefore the sink hasn't sent back QoS information).

This avoids dropping plenty of frames when going back to regular playback
This commit is contained in:
Edward Hervey 2016-08-04 10:45:14 +02:00 committed by Edward Hervey
parent 2d79bc3a58
commit 8b374b3f82

View file

@ -1156,29 +1156,36 @@ gst_ffmpegviddec_do_qos (GstFFMpegVidDec * ffmpegdec,
*mode_switch = TRUE;
}
if (*mode_switch == TRUE) {
/* We've already switched mode, we can return straight away
* without any further calculation */
return;
}
diff =
gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (ffmpegdec),
frame);
/* if we don't have timing info, then we don't do QoS */
if (G_UNLIKELY (diff == G_MAXINT64))
if (G_UNLIKELY (diff == G_MAXINT64)) {
/* Ensure the skipping strategy is the default one */
ffmpegdec->context->skip_frame = ffmpegdec->skip_frame;
return;
}
GST_DEBUG_OBJECT (ffmpegdec, "decoding time %" G_GINT64_FORMAT, diff);
if (*mode_switch == FALSE) {
if (diff > 0 && ffmpegdec->context->skip_frame != AVDISCARD_DEFAULT) {
ffmpegdec->context->skip_frame = AVDISCARD_DEFAULT;
*mode_switch = TRUE;
GST_DEBUG_OBJECT (ffmpegdec, "QOS: normal mode");
}
if (diff > 0 && ffmpegdec->context->skip_frame != AVDISCARD_DEFAULT) {
ffmpegdec->context->skip_frame = AVDISCARD_DEFAULT;
*mode_switch = TRUE;
GST_DEBUG_OBJECT (ffmpegdec, "QOS: normal mode");
}
else if (diff <= 0 && ffmpegdec->context->skip_frame != AVDISCARD_NONREF) {
ffmpegdec->context->skip_frame = AVDISCARD_NONREF;
*mode_switch = TRUE;
GST_DEBUG_OBJECT (ffmpegdec,
"QOS: hurry up, diff %" G_GINT64_FORMAT " >= 0", diff);
}
else if (diff <= 0 && ffmpegdec->context->skip_frame != AVDISCARD_NONREF) {
ffmpegdec->context->skip_frame = AVDISCARD_NONREF;
*mode_switch = TRUE;
GST_DEBUG_OBJECT (ffmpegdec,
"QOS: hurry up, diff %" G_GINT64_FORMAT " >= 0", diff);
}
}