From 5c2eba666ba0e14142d2584bc7716cd5688dc4e4 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 26 Oct 2022 16:30:31 -0400 Subject: [PATCH] avdec_h265: Fix endless renegoation with alternate interlacing The picture parameter picture->top_field_first is reused in this mode to signal the TOP fields. As a side effect, it will change every frame and current code assumed that if this changes then a renegotiation is needed. Fixed this by ignoring that change whenever we are decoding one field only. Fixes #1523 Part-of: --- subprojects/gst-libav/ext/libav/gstavviddec.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/subprojects/gst-libav/ext/libav/gstavviddec.c b/subprojects/gst-libav/ext/libav/gstavviddec.c index cccbb73..dd8c615 100644 --- a/subprojects/gst-libav/ext/libav/gstavviddec.c +++ b/subprojects/gst-libav/ext/libav/gstavviddec.c @@ -98,7 +98,7 @@ static GstFlowReturn gst_ffmpegviddec_finish (GstVideoDecoder * decoder); static GstFlowReturn gst_ffmpegviddec_drain (GstVideoDecoder * decoder); static gboolean picture_changed (GstFFMpegVidDec * ffmpegdec, - AVFrame * picture); + AVFrame * picture, gboolean one_field); static gboolean context_changed (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context); @@ -1034,11 +1034,14 @@ no_frame: } static gboolean -picture_changed (GstFFMpegVidDec * ffmpegdec, AVFrame * picture) +picture_changed (GstFFMpegVidDec * ffmpegdec, AVFrame * picture, + gboolean one_field) { gint pic_field_order = 0; - if (picture->interlaced_frame) { + if (one_field) { + pic_field_order = ffmpegdec->pic_field_order; + } else if (picture->interlaced_frame) { if (picture->repeat_pict) pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF; if (picture->top_field_first) @@ -1066,7 +1069,7 @@ context_changed (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context) static gboolean update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context, - AVFrame * picture) + AVFrame * picture, gboolean one_field) { gint pic_field_order = 0; @@ -1077,7 +1080,7 @@ update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context, pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF; } - if (!picture_changed (ffmpegdec, picture) + if (!picture_changed (ffmpegdec, picture, one_field) && !context_changed (ffmpegdec, context)) return FALSE; @@ -1303,8 +1306,9 @@ gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec, GstStructure *in_s; GstVideoInterlaceMode interlace_mode; gint caps_height; + gboolean one_field = ! !(flags & GST_VIDEO_BUFFER_FLAG_ONEFIELD); - if (!update_video_context (ffmpegdec, context, picture)) + if (!update_video_context (ffmpegdec, context, picture, one_field)) return TRUE; caps_height = ffmpegdec->pic_height; -- 2.7.4