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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8118>
This commit is contained in:
Thibault Saunier 2024-12-09 16:46:12 -03:00 committed by GStreamer Marge Bot
parent 3fc5ee6298
commit 4aa6b35639
2 changed files with 20 additions and 1 deletions

View file

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

View file

@ -93,6 +93,8 @@ struct _GstFFMpegVidDec
gint pool_height;
enum AVPixelFormat pool_format;
GstVideoInfo pool_info;
gboolean needs_renegotation;
};
typedef struct _GstFFMpegVidDecClass GstFFMpegVidDecClass;