qtdemux: fragmented support; handle ismv stbl atoms
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 8 Nov 2010 10:41:21 +0000 (11:41 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 3 Dec 2010 14:52:08 +0000 (15:52 +0100)
... or lack of some thereof, such as mandatory stsz.  Shuffle some code
in _stbl_init to detect this early enough.

gst/qtdemux/qtdemux.c

index a853765..b3d1688 100644 (file)
@@ -5122,6 +5122,23 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
     }
   }
 
+  /* sample size */
+  if (!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stsz, &stream->stsz))
+    goto no_samples;
+
+  /* copy atom data into a new buffer for later use */
+  stream->stsz.data = g_memdup (stream->stsz.data, stream->stsz.size);
+
+  /* skip version + flags */
+  if (!gst_byte_reader_skip (&stream->stsz, 1 + 3) ||
+      !gst_byte_reader_get_uint32_be (&stream->stsz, &stream->sample_size))
+    goto corrupt_file;
+
+  if (!gst_byte_reader_get_uint32_be (&stream->stsz, &stream->n_samples))
+    goto corrupt_file;
+
+  if (!stream->n_samples)
+    goto no_samples;
 
   /* sample-to-chunk atom */
   if (!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stsc, &stream->stsc))
@@ -5145,19 +5162,6 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
     goto corrupt_file;
 
 
-  /* sample size */
-  if (!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stsz, &stream->stsz))
-    goto corrupt_file;
-
-  /* copy atom data into a new buffer for later use */
-  stream->stsz.data = g_memdup (stream->stsz.data, stream->stsz.size);
-
-  /* skip version + flags */
-  if (!gst_byte_reader_skip (&stream->stsz, 1 + 3) ||
-      !gst_byte_reader_get_uint32_be (&stream->stsz, &stream->sample_size))
-    goto corrupt_file;
-
-
   /* chunk offset */
   if (qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stco, &stream->stco))
     stream->co_size = sizeof (guint32);
@@ -5181,9 +5185,6 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
     if (!gst_byte_reader_skip (&stream->stco, 4))
       goto corrupt_file;
 
-    if (!gst_byte_reader_get_uint32_be (&stream->stsz, &stream->n_samples))
-      goto corrupt_file;
-
     /* make sure there are enough data in the stsz atom */
     if (!stream->sample_size) {
       /* different sizes for each sample */
@@ -5196,18 +5197,6 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
       goto corrupt_file;
   }
 
-  if (!stream->n_samples) {
-    gst_qtdemux_stbl_free (stream);
-    if (!qtdemux->fragmented) {
-      /* not quite good */
-      GST_WARNING_OBJECT (qtdemux, "stream has no samples");
-      return FALSE;
-    } else {
-      /* may pick up samples elsewhere */
-      return TRUE;
-    }
-  }
-
   GST_DEBUG_OBJECT (qtdemux,
       "allocating n_samples %u * %" G_GSIZE_FORMAT " = (%u MB)",
       stream->n_samples, sizeof (QtDemuxSample),
@@ -5256,6 +5245,18 @@ corrupt_file:
         (_("This file is corrupt and cannot be played.")), (NULL));
     return FALSE;
   }
+no_samples:
+  {
+    gst_qtdemux_stbl_free (stream);
+    if (!qtdemux->fragmented) {
+      /* not quite good */
+      GST_WARNING_OBJECT (qtdemux, "stream has no samples");
+      return FALSE;
+    } else {
+      /* may pick up samples elsewhere */
+      return TRUE;
+    }
+  }
 }
 
 /* collect samples from the next sample to be parsed up to sample @n for @stream