matroskademux: avoid looping when searching for clusters
authorBranko Subasic <branko@axis.com>
Thu, 16 Jun 2011 12:52:51 +0000 (14:52 +0200)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Fri, 1 Jul 2011 16:19:40 +0000 (17:19 +0100)
Fixes some bugs that results in the demuxer looping when seaching
for clusters in non-finalized files.

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

gst/matroska/ebml-read.c
gst/matroska/matroska-demux.c

index 24780e7..c2dfa52 100644 (file)
@@ -131,7 +131,6 @@ gst_ebml_peek_id_length (guint32 * _id, guint64 * _length, guint * _needed,
     *_length = G_MAXUINT64;
   else
     *_length = total;
-  *_length = total;
 
   *_needed = needed;
 
index a6fb32f..23a88f9 100644 (file)
@@ -1608,6 +1608,10 @@ gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
     GstByteReader reader;
     gint cluster_pos;
 
+    if (buf != NULL) {
+      gst_buffer_unref (buf);
+      buf = NULL;
+    }
     ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
     if (ret != GST_FLOW_OK)
       break;
@@ -1636,13 +1640,15 @@ gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
       demux->common.offset = newpos;
       ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
           GST_ELEMENT_CAST (demux), &id, &length, &needed);
-      if (ret != GST_FLOW_OK)
-        goto resume;
+      if (ret != GST_FLOW_OK) {
+        GST_DEBUG_OBJECT (demux, "need more data -> continue");
+        continue;
+      }
       g_assert (id == GST_MATROSKA_ID_CLUSTER);
       GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
           length, needed);
       /* ok if undefined length or first cluster */
-      if (length == G_MAXUINT64) {
+      if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
         GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
         break;
       }
@@ -1661,8 +1667,6 @@ gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
     } else {
       /* partial cluster id may have been in tail of buffer */
       newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
-      gst_buffer_unref (buf);
-      buf = NULL;
     }
   }
 
@@ -1716,6 +1720,10 @@ gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
   otime = demux->common.segment.last_stop;
   GST_OBJECT_UNLOCK (demux);
 
+  /* avoid division by zero in first estimation below */
+  if (otime == 0)
+    otime = time;
+
 retry:
   GST_LOG_OBJECT (demux,
       "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT, opos,