summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
diff options
context:
space:
mode:
Diffstat (limited to 'demux/demux.c')
-rw-r--r--demux/demux.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 23b01b22f4..af710131b9 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -623,8 +623,15 @@ int ds_fill_buffer(demux_stream_t *ds)
ds == demux->audio ? "d_audio" : ds == demux->video ? "d_video" :
ds == demux->sub ? "d_sub" : "unknown");
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
+ ds->eof = 0;
+ ds->fill_count = 0;
// copy useful data:
ds->buffer = p->buffer;
ds->buffer_pos = 0;
@@ -657,21 +664,30 @@ int ds_fill_buffer(demux_stream_t *ds)
ds->eof = 0;
return 1;
}
+ // 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.
+ // This needs to be enough for at least 1 second of packets
+ // since libavformat mov demuxer does not try to interleave
+ // with more than 1s precision.
+ if (ds->fill_count > 80)
+ break;
+ // avoid printing the "too many ..." message over and over
+ if (ds->eof)
+ break;
#define MaybeNI _("Maybe you are playing a non-interleaved stream/file or the codec failed?\n" \
"For AVI files, try to force non-interleaved mode with the --demuxer=avi --avi-ni options.\n")
- if (demux->audio->packs >= MAX_PACKS
- || demux->audio->bytes >= MAX_PACK_BYTES) {
+ if (apacks >= MAX_PACKS || abytes >= MAX_PACK_BYTES) {
mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many audio packets in the buffer: (%d in %d bytes).\n",
- demux->audio->packs, demux->audio->bytes);
+ apacks, abytes);
mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI);
break;
}
- if (demux->video->packs >= MAX_PACKS
- || demux->video->bytes >= MAX_PACK_BYTES) {
+ if (vpacks >= MAX_PACKS || vbytes >= MAX_PACK_BYTES) {
mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many video packets in the buffer: (%d in %d bytes).\n",
- demux->video->packs, demux->video->bytes);
+ vpacks, vbytes);
mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI);
break;
}
@@ -680,6 +696,15 @@ int ds_fill_buffer(demux_stream_t *ds)
"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;