avidemux: avoid invalid H264 bytestream codec_data
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 28 Aug 2012 16:56:19 +0000 (18:56 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 28 Aug 2012 17:01:11 +0000 (19:01 +0200)
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=681369

gst/avi/gstavidemux.c

index 7858b6f..f73ba66 100644 (file)
@@ -1895,6 +1895,50 @@ gst_avi_demux_roundup_list (GstAviDemux * avi, GstBuffer ** buf)
   }
 }
 
+static GstCaps *
+gst_avi_demux_check_caps (GstAviDemux * avi, GstCaps * caps)
+{
+  GstStructure *s;
+  const GValue *val;
+  GstBuffer *buf;
+
+  s = gst_caps_get_structure (caps, 0);
+  if (!gst_structure_has_name (s, "video/x-h264"))
+    return caps;
+
+  GST_DEBUG_OBJECT (avi, "checking caps %" GST_PTR_FORMAT, caps);
+
+  /* some muxers put invalid bytestream stuff in h264 extra data */
+  val = gst_structure_get_value (s, "codec_data");
+  if (val && (buf = gst_value_get_buffer (val))) {
+    guint8 *data;
+    gint size;
+    GstMapInfo map;
+
+    gst_buffer_map (buf, &map, GST_MAP_READ);
+    data = map.data;
+    size = map.size;
+    if (size >= 4) {
+      guint32 h = GST_READ_UINT32_BE (data);
+      gst_buffer_unmap (buf, &map);
+      if (h == 0x01) {
+        /* can hardly be valid AVC codec data */
+        GST_DEBUG_OBJECT (avi,
+            "discarding invalid codec_data containing byte-stream");
+        /* so do not pretend to downstream that it is packetized avc */
+        gst_structure_remove_field (s, "codec_data");
+        /* ... but rather properly parsed bytestream */
+        gst_structure_set (s, "stream-format", G_TYPE_STRING, "byte-stream",
+            "alignment", G_TYPE_STRING, "au", NULL);
+      }
+    } else {
+      gst_buffer_unmap (buf, &map);
+    }
+  }
+
+  return caps;
+}
+
 /*
  * gst_avi_demux_parse_stream:
  * @avi: calling element (used for debugging/errors).
@@ -2199,6 +2243,7 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
         g_free (vprp);
         vprp = NULL;
       }
+      caps = gst_avi_demux_check_caps (avi, caps);
       tag_name = GST_TAG_VIDEO_CODEC;
       avi->num_v_streams++;
       break;