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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1534>
This commit is contained in:
Seungha Yang 2020-11-05 03:47:35 +09:00 committed by GStreamer Merge Bot
parent 5585314b56
commit 9bd6b5f0b4
2 changed files with 29 additions and 12 deletions

View file

@ -567,7 +567,8 @@ gst_h264_decoder_preprocess_slice (GstH264Decoder * self, GstH264Slice * slice)
} }
static void 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; GstH264DecoderPrivate *priv = self->priv;
GArray *dpb = gst_h264_dpb_get_pictures_all (priv->dpb); 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++) { for (i = 0; i < dpb->len; i++) {
GstH264Picture *picture = g_array_index (dpb, GstH264Picture *, 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)) if (!GST_H264_PICTURE_IS_REF (picture))
continue; continue;
@ -651,7 +647,8 @@ gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
unused_short_term_frame_num)) unused_short_term_frame_num))
return FALSE; 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 */ /* C.2.1 */
if (!gst_h264_decoder_sliding_window_picture_marking (self)) { 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) if (priv->process_ref_pic_lists)
gst_h264_decoder_prepare_ref_pic_lists (self); gst_h264_decoder_prepare_ref_pic_lists (self);
@ -1000,6 +997,7 @@ static gboolean
gst_h264_decoder_fill_picture_from_slice (GstH264Decoder * self, gst_h264_decoder_fill_picture_from_slice (GstH264Decoder * self,
const GstH264Slice * slice, GstH264Picture * picture) const GstH264Slice * slice, GstH264Picture * picture)
{ {
GstH264DecoderClass *klass = GST_H264_DECODER_GET_CLASS (self);
const GstH264SliceHdr *slice_hdr = &slice->header; const GstH264SliceHdr *slice_hdr = &slice->header;
const GstH264PPS *pps; const GstH264PPS *pps;
const GstH264SPS *sps; const GstH264SPS *sps;
@ -1028,8 +1026,9 @@ gst_h264_decoder_fill_picture_from_slice (GstH264Decoder * self,
else else
picture->field = GST_H264_PICTURE_FIELD_FRAME; picture->field = GST_H264_PICTURE_FIELD_FRAME;
if (picture->field != GST_H264_PICTURE_FIELD_FRAME) { if (picture->field != GST_H264_PICTURE_FIELD_FRAME &&
GST_FIXME ("Interlace video not supported"); !klass->new_field_picture) {
GST_FIXME_OBJECT (self, "Subclass doesn't support interlace stream");
return FALSE; return FALSE;
} }
@ -1726,6 +1725,7 @@ gst_h264_decoder_set_latency (GstH264Decoder * self, const GstH264SPS * sps,
static gboolean static gboolean
gst_h264_decoder_process_sps (GstH264Decoder * self, GstH264SPS * sps) gst_h264_decoder_process_sps (GstH264Decoder * self, GstH264SPS * sps)
{ {
GstH264DecoderClass *klass = GST_H264_DECODER_GET_CLASS (self);
GstH264DecoderPrivate *priv = self->priv; GstH264DecoderPrivate *priv = self->priv;
guint8 level; guint8 level;
gint max_dpb_mbs; gint max_dpb_mbs;
@ -1734,8 +1734,9 @@ gst_h264_decoder_process_sps (GstH264Decoder * self, GstH264SPS * sps)
gint max_dpb_size; gint max_dpb_size;
gint prev_max_dpb_size; gint prev_max_dpb_size;
if (sps->frame_mbs_only_flag == 0) { if (sps->frame_mbs_only_flag == 0 && !klass->new_field_picture) {
GST_FIXME_OBJECT (self, "frame_mbs_only_flag != 1 not supported"); GST_FIXME_OBJECT (self,
"frame_mbs_only_flag != 1 not supported by subclass");
return FALSE; return FALSE;
} }

View file

@ -93,6 +93,22 @@ struct _GstH264DecoderClass
GstVideoCodecFrame * frame, GstVideoCodecFrame * frame,
GstH264Picture * picture); 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: * GstH264DecoderClass::start_picture:
* @decoder: a #GstH264Decoder * @decoder: a #GstH264Decoder