From 9ebe338d80c25a64489f0790123bc6be23fc520e Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 26 Oct 2022 10:44:01 -0400 Subject: [PATCH] avviddec: Avoid flushing on framerate changes A framerate change does not require flushing the decoder and causes issues with some specific fragmented files if the two fragments have different framerate. Fixes #1522 Part-of: --- subprojects/gst-libav/ext/libav/gstavviddec.c | 38 +++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-libav/ext/libav/gstavviddec.c b/subprojects/gst-libav/ext/libav/gstavviddec.c index 61edfd2..cccbb73 100644 --- a/subprojects/gst-libav/ext/libav/gstavviddec.c +++ b/subprojects/gst-libav/ext/libav/gstavviddec.c @@ -456,6 +456,33 @@ gst_ffmpegviddec_get_palette (GstFFMpegVidDec * ffmpegdec, } } +static gboolean +gst_ffmpegviddec_needs_reset (GstFFMpegVidDec * ffmpegdec, + GstVideoCodecState * state) +{ + GstCaps *last_caps, *new_caps; + gboolean needs_reset; + + if (ffmpegdec->last_caps == NULL) + return TRUE; + + last_caps = gst_caps_copy (ffmpegdec->last_caps); + new_caps = gst_caps_copy (state->caps); + + /* Simply ignore framerate for now, this could easily be evolved per CODEC if + * future issue are found.*/ + gst_structure_remove_field (gst_caps_get_structure (last_caps, 0), + "framerate"); + gst_structure_remove_field (gst_caps_get_structure (new_caps, 0), + "framerate"); + + needs_reset = !gst_caps_is_equal (last_caps, new_caps); + + gst_caps_unref (last_caps); + gst_caps_unref (new_caps); + + return needs_reset; +} static gboolean gst_ffmpegviddec_set_format (GstVideoDecoder * decoder, @@ -469,15 +496,15 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder, ffmpegdec = (GstFFMpegVidDec *) decoder; oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec)); - if (ffmpegdec->last_caps != NULL && - gst_caps_is_equal (ffmpegdec->last_caps, state->caps)) { - return TRUE; - } - GST_DEBUG_OBJECT (ffmpegdec, "setcaps called"); GST_OBJECT_LOCK (ffmpegdec); + if (!gst_ffmpegviddec_needs_reset (ffmpegdec, state)) { + gst_caps_replace (&ffmpegdec->last_caps, state->caps); + goto update_state; + } + /* close old session */ if (ffmpegdec->opened) { GST_OBJECT_UNLOCK (ffmpegdec); @@ -600,6 +627,7 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder, if (!gst_ffmpegviddec_open (ffmpegdec)) goto open_failed; +update_state: if (ffmpegdec->input_state) gst_video_codec_state_unref (ffmpegdec->input_state); ffmpegdec->input_state = gst_video_codec_state_ref (state); -- 2.7.4