From 4aa6b356392408b8ec7b30eb3b899764e0c574de Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 9 Dec 2024 16:46:12 -0300 Subject: [PATCH] avviddec: Renegotiate srcpad caps on framerate change We avoid resetting the internal FFmpeg decoder on framerate changes, but in turn this means we were not updating the framerate on the srcpad, which was clearly incorrect. This change keeps the optimization but ensures that we renegotiate downstream when framerate changes occur. Part-of: --- subprojects/gst-libav/ext/libav/gstavviddec.c | 19 ++++++++++++++++++- subprojects/gst-libav/ext/libav/gstavviddec.h | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-libav/ext/libav/gstavviddec.c b/subprojects/gst-libav/ext/libav/gstavviddec.c index 8c2fa458f8..bba4151e0e 100644 --- a/subprojects/gst-libav/ext/libav/gstavviddec.c +++ b/subprojects/gst-libav/ext/libav/gstavviddec.c @@ -560,6 +560,19 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder, GST_OBJECT_LOCK (ffmpegdec); if (!gst_ffmpegviddec_needs_reset (ffmpegdec, state)) { + if (ffmpegdec->last_caps) { + gint last_fps_n, last_fps_d, fps_n, fps_d; + + if (gst_structure_get (gst_caps_get_structure (ffmpegdec->last_caps, 0), + "framerate", GST_TYPE_FRACTION, &last_fps_n, &last_fps_d, NULL) && + gst_structure_get (gst_caps_get_structure (state->caps, 0), + "framerate", GST_TYPE_FRACTION, &fps_n, &fps_d, NULL)) { + + ffmpegdec->needs_renegotation = (last_fps_d != fps_d + || last_fps_n != fps_n); + } + + } gst_caps_replace (&ffmpegdec->last_caps, state->caps); goto update_state; } @@ -1482,9 +1495,12 @@ gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec, gint caps_height; gboolean one_field = !!(flags & GST_VIDEO_BUFFER_FLAG_ONEFIELD); - if (!update_video_context (ffmpegdec, context, picture, one_field)) + if (!update_video_context (ffmpegdec, context, picture, one_field) + && !ffmpegdec->needs_renegotation) { return TRUE; + } + ffmpegdec->needs_renegotation = FALSE; caps_height = ffmpegdec->pic_height; fmt = gst_ffmpeg_pixfmt_to_videoformat (ffmpegdec->pic_pix_fmt); @@ -2425,6 +2441,7 @@ gst_ffmpegviddec_stop (GstVideoDecoder * decoder) ffmpegdec->pool_width = 0; ffmpegdec->pool_height = 0; ffmpegdec->pool_format = 0; + ffmpegdec->needs_renegotation = FALSE; return TRUE; } diff --git a/subprojects/gst-libav/ext/libav/gstavviddec.h b/subprojects/gst-libav/ext/libav/gstavviddec.h index 14d5a9aff3..b209fea43e 100644 --- a/subprojects/gst-libav/ext/libav/gstavviddec.h +++ b/subprojects/gst-libav/ext/libav/gstavviddec.h @@ -93,6 +93,8 @@ struct _GstFFMpegVidDec gint pool_height; enum AVPixelFormat pool_format; GstVideoInfo pool_info; + + gboolean needs_renegotation; }; typedef struct _GstFFMpegVidDecClass GstFFMpegVidDecClass;