codecs: h264decoder: Remove interlaced stream related constraints
authorSeungha Yang <seungha@centricular.com>
Wed, 4 Nov 2020 18:47:35 +0000 (03:47 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 13 Nov 2020 15:25:42 +0000 (15:25 +0000)
... 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>

gst-libs/gst/codecs/gsth264decoder.c
gst-libs/gst/codecs/gsth264decoder.h

index 4ba8ace..315d7c9 100644 (file)
@@ -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;
   }
 
index 5aab317..d2e3948 100644 (file)
@@ -94,6 +94,22 @@ struct _GstH264DecoderClass
                                      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
    * @picture: (transfer none): a #GstH264Picture