diff libmpdemux/demuxer.c @ 35405:d6305a78a11e

Fix code that detects streams temporarily lacking data to work properly with e.g. DVDs.
author reimar
date Wed, 28 Nov 2012 19:15:34 +0000
parents 092c40fbd33d
children f4828b517f4a
line wrap: on
line diff
--- a/libmpdemux/demuxer.c	Wed Nov 28 19:13:39 2012 +0000
+++ b/libmpdemux/demuxer.c	Wed Nov 28 19:15:34 2012 +0000
@@ -659,6 +659,10 @@
                    "ds_fill_buffer(unknown 0x%X) called\n", (unsigned int) ds);
     }
     while (1) {
+        int apacks = demux->audio ? demux->audio->packs : 0;
+        int abytes = demux->audio ? demux->audio->bytes : 0;
+        int vpacks = demux->video ? demux->video->packs : 0;
+        int vbytes = demux->video ? demux->video->bytes : 0;
         if (ds->packs) {
             demux_packet_t *p = ds->first;
             // obviously not yet EOF after all
@@ -701,22 +705,20 @@
         // avoid buffering too far ahead in e.g. badly interleaved files
         // or when one stream is shorter, without breaking large audio
         // delay with well interleaved files.
-        if (ds->fill_count++ > 20)
+        if (ds->fill_count > 20)
             break;
         // avoid printing the "too many ..." message over and over
         if (ds->eof)
             break;
-        if (demux->audio->packs >= MAX_PACKS
-            || demux->audio->bytes >= MAX_PACK_BYTES) {
+        if (apacks >= MAX_PACKS || abytes >= MAX_PACK_BYTES) {
             mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_TooManyAudioInBuffer,
-                   demux->audio->packs, demux->audio->bytes);
+                   apacks, abytes);
             mp_msg(MSGT_DEMUXER, MSGL_HINT, MSGTR_MaybeNI);
             break;
         }
-        if (demux->video->packs >= MAX_PACKS
-            || demux->video->bytes >= MAX_PACK_BYTES) {
+        if (vpacks >= MAX_PACKS || vbytes >= MAX_PACK_BYTES) {
             mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_TooManyVideoInBuffer,
-                   demux->video->packs, demux->video->bytes);
+                   vpacks, vbytes);
             mp_msg(MSGT_DEMUXER, MSGL_HINT, MSGTR_MaybeNI);
             break;
         }
@@ -738,6 +740,15 @@
                    "ds_fill_buffer()->demux_fill_buffer() failed\n");
             break; // EOF
         }
+        if (demux->audio)
+            ds->fill_count += demux->audio->packs - apacks;
+        if (demux->video && demux->video->packs > vpacks &&
+            // Empty packets or "skip" packets in e.g. AVI can cause issues.
+            demux->video->bytes > vbytes + 100 &&
+            // when video needs parsing we will have lots of video packets
+            // in-between audio packets, so ignore them in that case.
+            demux->video->sh && !((sh_video_t *)demux->video->sh)->needs_parsing)
+            ds->fill_count++;
     }
     ds->buffer_pos = ds->buffer_size = 0;
     ds->buffer = NULL;