matroska: Handle interlaced field order
authorDoug Nazar <nazard@nazar.ca>
Wed, 7 Aug 2019 14:01:34 +0000 (10:01 -0400)
committerSebastian Dröge <slomo@coaxion.net>
Wed, 7 Aug 2019 14:12:32 +0000 (14:12 +0000)
gst/matroska/matroska-demux.c
gst/matroska/matroska-ids.c
gst/matroska/matroska-ids.h
gst/matroska/matroska-parse.c

index 5878f38..e39965b 100644 (file)
@@ -974,6 +974,44 @@ gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
               break;
             }
 
+              /* interlaced field order */
+            case GST_MATROSKA_ID_VIDEOFIELDORDER:{
+              guint64 num;
+
+              if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
+                break;
+
+              if (videocontext->interlace_mode !=
+                  GST_MATROSKA_INTERLACE_MODE_INTERLACED) {
+                GST_WARNING_OBJECT (demux,
+                    "FieldOrder element when not interlaced - ignoring");
+                break;
+              }
+
+              if (num == 0)
+                /* turns out we're actually progressive */
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
+              else if (num == 2)
+                videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
+              else if (num == 9)
+                videocontext->field_order =
+                    GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
+              else if (num == 14)
+                videocontext->field_order =
+                    GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
+              else {
+                GST_FIXME_OBJECT (demux,
+                    "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT,
+                    num);
+                videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
+              }
+
+              GST_DEBUG_OBJECT (demux, "video track field order: %d",
+                  videocontext->field_order);
+              break;
+            }
+
               /* aspect ratio behaviour */
             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
               guint64 num;
@@ -6437,7 +6475,12 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
           break;
         case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
           gst_structure_set (structure,
-              "interlace-mode", G_TYPE_STRING, "mixed", NULL);
+              "interlace-mode", G_TYPE_STRING, "interleaved", NULL);
+
+          if (videocontext->field_order != GST_VIDEO_FIELD_ORDER_UNKNOWN)
+            gst_structure_set (structure, "field-order", G_TYPE_STRING,
+                gst_video_field_order_to_string (videocontext->field_order),
+                NULL);
           break;
         default:
           break;
index b3c5130..3722822 100644 (file)
@@ -59,6 +59,7 @@ gst_matroska_track_init_video_context (GstMatroskaTrackContext ** p_context)
   video_context->fourcc = 0;
   video_context->default_fps = 0.0;
   video_context->interlace_mode = GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
+  video_context->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
   video_context->earliest_time = GST_CLOCK_TIME_NONE;
   video_context->dirac_unit = NULL;
   video_context->earliest_time = GST_CLOCK_TIME_NONE;
index ab74ed2..429213f 100644 (file)
 #define GST_MATROSKA_ID_VIDEOPIXELCROPLEFT         0x54CC
 #define GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT        0x54DD
 #define GST_MATROSKA_ID_VIDEOFLAGINTERLACED        0x9A
+#define GST_MATROSKA_ID_VIDEOFIELDORDER            0x9D
 /* semi-draft */
 #define GST_MATROSKA_ID_VIDEOSTEREOMODE            0x53B8
 #define GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE       0x54B3
@@ -632,6 +633,7 @@ typedef struct _GstMatroskaTrackVideoContext {
   guint32       fourcc;
 
   GstMatroskaInterlaceMode interlace_mode;
+  GstVideoFieldOrder field_order;
 
   GstVideoMultiviewMode multiview_mode;
   GstVideoMultiviewFlags multiview_flags;
index b34817f..594cd9a 100644 (file)
@@ -557,6 +557,44 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
               break;
             }
 
+              /* interlaced field order */
+            case GST_MATROSKA_ID_VIDEOFIELDORDER:{
+              guint64 num;
+
+              if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
+                break;
+
+              if (videocontext->interlace_mode !=
+                  GST_MATROSKA_INTERLACE_MODE_INTERLACED) {
+                GST_WARNING_OBJECT (parse,
+                    "FieldOrder element when not interlaced - ignoring");
+                break;
+              }
+
+              if (num == 0)
+                /* turns out we're actually progressive */
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
+              else if (num == 2)
+                videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
+              else if (num == 9)
+                videocontext->field_order =
+                    GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
+              else if (num == 14)
+                videocontext->field_order =
+                    GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
+              else {
+                GST_FIXME_OBJECT (parse,
+                    "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT,
+                    num);
+                videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
+              }
+
+              GST_DEBUG_OBJECT (parse, "video track field order: %d",
+                  videocontext->field_order);
+              break;
+            }
+
               /* aspect ratio behaviour */
             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
               guint64 num;