codecs: mpeg2decoder: Creating the field based on its arriving time.
authorHe Junyan <junyan.he@intel.com>
Wed, 30 Dec 2020 15:14:01 +0000 (23:14 +0800)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Mon, 4 Jan 2021 13:09:01 +0000 (13:09 +0000)
Spec says:
In a frame picture top_field_first being set to ‘1’ indicates that the
top field of the reconstructed frame is the first field output by the
decoding process. top_field_first being set to ‘0’ indicates that the
bottom field of the reconstructed frame is the first field output by
decoding process.

Here, the "output" should be interpreted just as the output order, not
including the decoding order. The field should be decoded as the order
they comes in the stream. Namely, no matter top_field_first is 0 or 1,
the first coming field is the first one to be decoded.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1929>

gst-libs/gst/codecs/gstmpeg2decoder.c

index 49e88b3..495d684 100644 (file)
@@ -779,11 +779,7 @@ gst_mpeg2_decoder_ensure_current_picture (GstMpeg2Decoder * decoder,
 
     picture->structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME;
   } else {
-    gboolean is_first_field = (priv->pic_ext.picture_structure ==
-        GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD) ^
-        (priv->pic_ext.top_field_first == 0);
-
-    if (is_first_field) {
+    if (!priv->first_field) {
       picture = gst_mpeg2_picture_new ();
       if (klass->new_picture)
         ret = klass->new_picture (decoder, priv->current_frame, picture);
@@ -796,17 +792,8 @@ gst_mpeg2_decoder_ensure_current_picture (GstMpeg2Decoder * decoder,
     } else {
       picture = gst_mpeg2_picture_new ();
 
-      if (priv->first_field == NULL) {
-        GST_WARNING_OBJECT (decoder, "Missing the first field");
-        if (klass->new_picture)
-          ret = klass->new_picture (decoder, priv->current_frame, picture);
-      } else {
-        if (klass->new_field_picture)
-          ret = klass->new_field_picture (decoder, priv->first_field, picture);
-
-        if (ret)
-          picture->first_field = gst_mpeg2_picture_ref (priv->first_field);
-      }
+      if (klass->new_field_picture)
+        ret = klass->new_field_picture (decoder, priv->first_field, picture);
 
       if (!ret) {
         GST_ERROR_OBJECT (decoder,
@@ -815,6 +802,8 @@ gst_mpeg2_decoder_ensure_current_picture (GstMpeg2Decoder * decoder,
         return FALSE;
       }
 
+      picture->first_field = gst_mpeg2_picture_ref (priv->first_field);
+
       /* At this moment, this picture should be interlaced */
       picture->buffer_flags |= GST_VIDEO_BUFFER_FLAG_INTERLACED;
       if (priv->pic_ext.top_field_first)