From caa5eb65d1225d55de16a71accff363460b29e85 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 15 Nov 2020 00:55:09 +0900 Subject: [PATCH] codecs: h264decoder: Split frame picture into field pictures if needed In case of interlaced stream, frame pictures need to be splitted into field for reference marking process. Part-of: --- gst-libs/gst/codecs/gsth264decoder.c | 52 +++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/codecs/gsth264decoder.c b/gst-libs/gst/codecs/gsth264decoder.c index 9cd8328..4427b14 100644 --- a/gst-libs/gst/codecs/gsth264decoder.c +++ b/gst-libs/gst/codecs/gsth264decoder.c @@ -787,9 +787,6 @@ gst_h264_decoder_new_field_picture (GstH264Decoder * self, GstH264DecoderClass *klass = GST_H264_DECODER_GET_CLASS (self); GstH264Picture *new_picture; - /* Should not happen */ - g_assert (picture->field != GST_H264_PICTURE_FIELD_FRAME); - if (!klass->new_field_picture) { GST_WARNING_OBJECT (self, "Subclass does not support interlaced stream"); return NULL; @@ -805,8 +802,6 @@ gst_h264_decoder_new_field_picture (GstH264Decoder * self, new_picture->other_field = picture; new_picture->second_field = TRUE; - new_picture->field = picture->field == GST_H264_PICTURE_FIELD_TOP_FIELD ? - GST_H264_PICTURE_FIELD_BOTTOM_FIELD : GST_H264_PICTURE_FIELD_TOP_FIELD; return new_picture; } @@ -1671,7 +1666,52 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self, gst_video_decoder_release_frame (decoder, frame); } - gst_h264_dpb_add (priv->dpb, picture); + /* Split frame into top/bottom field pictures for reference picture marking + * process. Even if current picture has field_pic_flag equal to zero, + * if next picture is a field picture, complementary field pair of reference + * frame should have individual pic_num and long_term_pic_num. + */ + if (gst_h264_dpb_get_interlaced (priv->dpb) && + GST_H264_PICTURE_IS_FRAME (picture)) { + GstH264Picture *other_field = + gst_h264_decoder_new_field_picture (self, picture); + + if (!other_field) { + GST_WARNING_OBJECT (self, + "Couldn't split frame into complementary field pair"); + + /* Keep decoding anyway... */ + gst_h264_dpb_add (priv->dpb, picture); + } else { + GST_LOG_OBJECT (self, "Split picture %p, poc %d, frame num %d", + picture, picture->pic_order_cnt, picture->frame_num); + + /* FIXME: enhance TFF decision by using picture timing SEI */ + if (picture->top_field_order_cnt < picture->bottom_field_order_cnt) { + picture->field = GST_H264_PICTURE_FIELD_TOP_FIELD; + picture->pic_order_cnt = picture->top_field_order_cnt; + + other_field->field = GST_H264_PICTURE_FIELD_BOTTOM_FIELD; + other_field->pic_order_cnt = picture->bottom_field_order_cnt; + } else { + picture->field = GST_H264_PICTURE_FIELD_BOTTOM_FIELD; + picture->pic_order_cnt = picture->bottom_field_order_cnt; + + other_field->field = GST_H264_PICTURE_FIELD_TOP_FIELD; + other_field->pic_order_cnt = picture->top_field_order_cnt; + } + + other_field->top_field_order_cnt = picture->top_field_order_cnt; + other_field->bottom_field_order_cnt = picture->bottom_field_order_cnt; + other_field->frame_num = picture->frame_num; + other_field->ref = picture->ref; + + gst_h264_dpb_add (priv->dpb, picture); + gst_h264_dpb_add (priv->dpb, other_field); + } + } else { + gst_h264_dpb_add (priv->dpb, picture); + } GST_LOG_OBJECT (self, "Finishing picture %p (frame_num %d, poc %d), entries in DPB %d", -- 2.7.4