From 9bd6b5f0b4648ccf3d64d3c7b8ea54c20b7a8d2e Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 5 Nov 2020 03:47:35 +0900 Subject: [PATCH] codecs: h264decoder: Remove interlaced stream related constraints ... and add new_field_picture() vfunc so that ensure interlaced decoding support by subclass. The method will be used later with interlaced stream support. Part-of: --- gst-libs/gst/codecs/gsth264decoder.c | 25 +++++++++++++------------ gst-libs/gst/codecs/gsth264decoder.h | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/codecs/gsth264decoder.c b/gst-libs/gst/codecs/gsth264decoder.c index 4ba8acef75..315d7c9c23 100644 --- a/gst-libs/gst/codecs/gsth264decoder.c +++ b/gst-libs/gst/codecs/gsth264decoder.c @@ -567,7 +567,8 @@ gst_h264_decoder_preprocess_slice (GstH264Decoder * self, GstH264Slice * slice) } static void -gst_h264_decoder_update_pic_nums (GstH264Decoder * self, gint frame_num) +gst_h264_decoder_update_pic_nums (GstH264Decoder * self, + GstH264Picture * current_picture, gint frame_num) { GstH264DecoderPrivate *priv = self->priv; GArray *dpb = gst_h264_dpb_get_pictures_all (priv->dpb); @@ -576,11 +577,6 @@ gst_h264_decoder_update_pic_nums (GstH264Decoder * self, gint frame_num) for (i = 0; i < dpb->len; i++) { GstH264Picture *picture = g_array_index (dpb, GstH264Picture *, i); - if (picture->field != GST_H264_PICTURE_FIELD_FRAME) { - GST_FIXME_OBJECT (self, "Interlaced video not supported"); - continue; - } - if (!GST_H264_PICTURE_IS_REF (picture)) continue; @@ -651,7 +647,8 @@ gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num) unused_short_term_frame_num)) return FALSE; - gst_h264_decoder_update_pic_nums (self, unused_short_term_frame_num); + gst_h264_decoder_update_pic_nums (self, picture, + unused_short_term_frame_num); /* C.2.1 */ if (!gst_h264_decoder_sliding_window_picture_marking (self)) { @@ -754,7 +751,7 @@ gst_h264_decoder_start_current_picture (GstH264Decoder * self) } } - gst_h264_decoder_update_pic_nums (self, frame_num); + gst_h264_decoder_update_pic_nums (self, current_picture, frame_num); if (priv->process_ref_pic_lists) gst_h264_decoder_prepare_ref_pic_lists (self); @@ -1000,6 +997,7 @@ static gboolean gst_h264_decoder_fill_picture_from_slice (GstH264Decoder * self, const GstH264Slice * slice, GstH264Picture * picture) { + GstH264DecoderClass *klass = GST_H264_DECODER_GET_CLASS (self); const GstH264SliceHdr *slice_hdr = &slice->header; const GstH264PPS *pps; const GstH264SPS *sps; @@ -1028,8 +1026,9 @@ gst_h264_decoder_fill_picture_from_slice (GstH264Decoder * self, else picture->field = GST_H264_PICTURE_FIELD_FRAME; - if (picture->field != GST_H264_PICTURE_FIELD_FRAME) { - GST_FIXME ("Interlace video not supported"); + if (picture->field != GST_H264_PICTURE_FIELD_FRAME && + !klass->new_field_picture) { + GST_FIXME_OBJECT (self, "Subclass doesn't support interlace stream"); return FALSE; } @@ -1726,6 +1725,7 @@ gst_h264_decoder_set_latency (GstH264Decoder * self, const GstH264SPS * sps, static gboolean gst_h264_decoder_process_sps (GstH264Decoder * self, GstH264SPS * sps) { + GstH264DecoderClass *klass = GST_H264_DECODER_GET_CLASS (self); GstH264DecoderPrivate *priv = self->priv; guint8 level; gint max_dpb_mbs; @@ -1734,8 +1734,9 @@ gst_h264_decoder_process_sps (GstH264Decoder * self, GstH264SPS * sps) gint max_dpb_size; gint prev_max_dpb_size; - if (sps->frame_mbs_only_flag == 0) { - GST_FIXME_OBJECT (self, "frame_mbs_only_flag != 1 not supported"); + if (sps->frame_mbs_only_flag == 0 && !klass->new_field_picture) { + GST_FIXME_OBJECT (self, + "frame_mbs_only_flag != 1 not supported by subclass"); return FALSE; } diff --git a/gst-libs/gst/codecs/gsth264decoder.h b/gst-libs/gst/codecs/gsth264decoder.h index 5aab317381..d2e3948c26 100644 --- a/gst-libs/gst/codecs/gsth264decoder.h +++ b/gst-libs/gst/codecs/gsth264decoder.h @@ -93,6 +93,22 @@ struct _GstH264DecoderClass GstVideoCodecFrame * frame, GstH264Picture * picture); + /** + * GstH264DecoderClass::new_field_picture: + * @decoder: a #GstH264Decoder + * @first_field: (transfer none): the first field #GstH264Picture already decoded + * @second_field: (transfer none): a #GstH264Picture for the second field + * + * Called when a new field picture is created for interlaced field picture. + * Subclass can attach implementation specific user data on @second_field via + * gst_h264_picture_set_user_data() + * + * Since: 1.20 + */ + gboolean (*new_field_picture) (GstH264Decoder * decoder, + const GstH264Picture * first_field, + GstH264Picture * second_field); + /** * GstH264DecoderClass::start_picture: * @decoder: a #GstH264Decoder