matroska: fix handling of FlagInterlaced
authorTim-Philipp Müller <tim@centricular.com>
Thu, 23 Aug 2018 20:57:35 +0000 (22:57 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Thu, 23 Aug 2018 21:32:06 +0000 (23:32 +0200)
This is an enum not a boolean, and a value of 2 signals
that the video is progressive, but we would mistakenly set
interlace-mode=mixed on the output caps.

https://bugzilla.gnome.org/show_bug.cgi?id=787206

gst/matroska/matroska-demux.c
gst/matroska/matroska-ids.h
gst/matroska/matroska-mux.c
gst/matroska/matroska-parse.c

index e305e5c..fb78329 100644 (file)
@@ -862,13 +862,18 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
                 break;
 
-              if (num)
-                context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
+              if (num == 1)
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_INTERLACED;
+              else if (num == 2)
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
               else
-                context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
-              GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
-                  (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
-                  0);
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
+
+              GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
+                  videocontext->interlace_mode);
               break;
             }
 
@@ -5750,9 +5755,18 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
             0, 1, NULL);
       }
 
-      if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
-        gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
-            "mixed", NULL);
+      switch (videocontext->interlace_mode) {
+        case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
+          gst_structure_set (structure,
+              "interlace-mode", G_TYPE_STRING, "progressive", NULL);
+          break;
+        case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
+          gst_structure_set (structure,
+              "interlace-mode", G_TYPE_STRING, "mixed", NULL);
+          break;
+        default:
+          break;
+      }
     }
     if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
       if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
index 9a88010..c2e41e5 100644 (file)
@@ -500,8 +500,10 @@ typedef enum {
 } GstMatroskaTrackFlags;
 
 typedef enum {
-  GST_MATROSKA_VIDEOTRACK_INTERLACED = (GST_MATROSKA_TRACK_SHIFT<<0)
-} GstMatroskaVideoTrackFlags;
+  GST_MATROSKA_INTERLACE_MODE_UNKNOWN = 0,
+  GST_MATROSKA_INTERLACE_MODE_INTERLACED = 1,
+  GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE = 2,
+} GstMatroskaInterlaceMode;
 
 typedef enum {
   GST_MATROSKA_STEREO_MODE_SBS_LR      = 0x1,
@@ -596,6 +598,8 @@ typedef struct _GstMatroskaTrackVideoContext {
   GstMatroskaAspectRatioMode asr_mode;
   guint32       fourcc;
 
+  GstMatroskaInterlaceMode interlace_mode;
+
   GstVideoMultiviewMode multiview_mode;
   GstVideoMultiviewFlags multiview_flags;
 
index 2fd6c2c..d487a82 100644 (file)
@@ -1005,8 +1005,14 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
   mimetype = gst_structure_get_name (structure);
 
   interlace_mode = gst_structure_get_string (structure, "interlace-mode");
-  if (interlace_mode != NULL && strcmp (interlace_mode, "progressive") != 0)
-    context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
+  if (interlace_mode != NULL) {
+    if (strcmp (interlace_mode, "progressive") == 0)
+      videocontext->interlace_mode = GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
+    else
+      videocontext->interlace_mode = GST_MATROSKA_INTERLACE_MODE_INTERLACED;
+  } else {
+    videocontext->interlace_mode = GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
+  }
 
   if (!strcmp (mimetype, "video/x-theora")) {
     /* we'll extract the details later from the theora identification header */
@@ -2693,8 +2699,17 @@ gst_matroska_mux_track_header (GstMatroskaMux * mux,
         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYHEIGHT,
             videocontext->display_height);
       }
-      if (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
-        gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
+      switch (videocontext->interlace_mode) {
+        case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
+          gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
+          break;
+        case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
+          gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 2);
+          break;
+        default:
+          break;
+      }
+
       if (videocontext->fourcc) {
         guint32 fcc_le = GUINT32_TO_LE (videocontext->fourcc);
 
index 006a46d..069f581 100644 (file)
@@ -542,13 +542,18 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
                 break;
 
-              if (num)
-                context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
+              if (num == 1)
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_INTERLACED;
+              else if (num == 2)
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
               else
-                context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
-              GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
-                  (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
-                  0);
+                videocontext->interlace_mode =
+                    GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
+
+              GST_DEBUG_OBJECT (parse, "video track interlacing mode: %d",
+                  videocontext->interlace_mode);
               break;
             }