mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3289>
This commit is contained in:
parent
5d22503a55
commit
c29bfbe448
1 changed files with 10 additions and 6 deletions
|
@ -98,7 +98,7 @@ static GstFlowReturn gst_ffmpegviddec_finish (GstVideoDecoder * decoder);
|
||||||
static GstFlowReturn gst_ffmpegviddec_drain (GstVideoDecoder * decoder);
|
static GstFlowReturn gst_ffmpegviddec_drain (GstVideoDecoder * decoder);
|
||||||
|
|
||||||
static gboolean picture_changed (GstFFMpegVidDec * ffmpegdec,
|
static gboolean picture_changed (GstFFMpegVidDec * ffmpegdec,
|
||||||
AVFrame * picture);
|
AVFrame * picture, gboolean one_field);
|
||||||
static gboolean context_changed (GstFFMpegVidDec * ffmpegdec,
|
static gboolean context_changed (GstFFMpegVidDec * ffmpegdec,
|
||||||
AVCodecContext * context);
|
AVCodecContext * context);
|
||||||
|
|
||||||
|
@ -1034,11 +1034,14 @@ no_frame:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
picture_changed (GstFFMpegVidDec * ffmpegdec, AVFrame * picture)
|
picture_changed (GstFFMpegVidDec * ffmpegdec, AVFrame * picture,
|
||||||
|
gboolean one_field)
|
||||||
{
|
{
|
||||||
gint pic_field_order = 0;
|
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)
|
if (picture->repeat_pict)
|
||||||
pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF;
|
pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF;
|
||||||
if (picture->top_field_first)
|
if (picture->top_field_first)
|
||||||
|
@ -1066,7 +1069,7 @@ context_changed (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context,
|
update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context,
|
||||||
AVFrame * picture)
|
AVFrame * picture, gboolean one_field)
|
||||||
{
|
{
|
||||||
gint pic_field_order = 0;
|
gint pic_field_order = 0;
|
||||||
|
|
||||||
|
@ -1077,7 +1080,7 @@ update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context,
|
||||||
pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF;
|
pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!picture_changed (ffmpegdec, picture)
|
if (!picture_changed (ffmpegdec, picture, one_field)
|
||||||
&& !context_changed (ffmpegdec, context))
|
&& !context_changed (ffmpegdec, context))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1277,8 +1280,9 @@ gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
|
||||||
GstStructure *in_s;
|
GstStructure *in_s;
|
||||||
GstVideoInterlaceMode interlace_mode;
|
GstVideoInterlaceMode interlace_mode;
|
||||||
gint caps_height;
|
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;
|
return TRUE;
|
||||||
|
|
||||||
caps_height = ffmpegdec->pic_height;
|
caps_height = ffmpegdec->pic_height;
|
||||||
|
|
Loading…
Reference in a new issue