asfdemux: Handle initial 0 timestamp that should have been -1
authorMatej Knopp <matej.knopp@gmail.com>
Sun, 1 Dec 2013 19:53:03 +0000 (20:53 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 26 May 2014 07:56:11 +0000 (09:56 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=719660

gst/asfdemux/gstasfdemux.c

index 07a6a71..a86a0cb 100644 (file)
@@ -1346,16 +1346,36 @@ gst_asf_demux_check_first_ts (GstASFDemux * demux, gboolean force)
       AsfStream *stream;
       int j;
       GstClockTime stream_min_ts = GST_CLOCK_TIME_NONE;
+      GstClockTime stream_min_ts2 = GST_CLOCK_TIME_NONE;        /* second smallest timestamp */
       stream = &demux->stream[i];
 
       for (j = 0; j < stream->payloads->len; ++j) {
         AsfPayload *payload = &g_array_index (stream->payloads, AsfPayload, j);
         if (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
             (!GST_CLOCK_TIME_IS_VALID (stream_min_ts)
-                || stream_min_ts > payload->ts))
+                || stream_min_ts > payload->ts)) {
           stream_min_ts = payload->ts;
+        }
+        if (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
+            payload->ts > stream_min_ts &&
+            (!GST_CLOCK_TIME_IS_VALID (stream_min_ts2)
+                || stream_min_ts2 > payload->ts)) {
+          stream_min_ts2 = payload->ts;
+        }
       }
 
+      /* there are some DVR ms files where first packet has TS of 0 (instead of -1) while subsequent packets have
+         regular (singificantly larger) timestamps. If we don't deal with it, we may end up with huge gap in timestamps
+         which makes playback stuck. The 0 timestamp may also be valid though, if the second packet timestamp continues 
+         from it. I havent found a better way to distinguish between these two, except to set an arbitrary boundary
+         and disregard the first 0 timestamp if the second timestamp is bigger than the boundary) */
+
+      if (stream_min_ts == 0 && stream_min_ts2 == GST_CLOCK_TIME_NONE && !force)        /* still waiting for the second timestamp */
+        return FALSE;
+
+      if (stream_min_ts == 0 && stream_min_ts2 > GST_SECOND)    /* first timestamp is 0 and second is significantly larger, disregard the 0 */
+        stream_min_ts = stream_min_ts2;
+
       /* if we don't have timestamp for this stream, wait for more data */
       if (!GST_CLOCK_TIME_IS_VALID (stream_min_ts) && !force)
         return FALSE;