summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2011-01-27 20:37:51 +0000
committerwm4 <wm4@nowhere>2012-12-11 00:37:55 +0100
commit4a40eeda941717b1a3d60d22c0c1020ea9c2038d (patch)
tree968a4d34572a9ae449b1805d380668c71d417b56 /demux/demux.c
parentfdbf43705581ee676d3e1d22210def3e21ce8fb3 (diff)
downloadmpv-4a40eeda941717b1a3d60d22c0c1020ea9c2038d.tar.bz2
mpv-4a40eeda941717b1a3d60d22c0c1020ea9c2038d.tar.xz
demux: fix behavior with files that have sparse video packets
Improve EOF handling in ds_fill_buffer for the case where one stream ends much earlier than the others, in particular make sure the "too many ..." message is not printed over and over. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32823 b3059339-0415-0410-9bf9-f77b7e298cf2 Conflicts: libmpdemux/demuxer.c Try to improve seeking in files with only few video packets, in particular files with cover art. This might cause issues with badly interleaved files, particularly together with -audio-delay, even though I did not see issues in my very limited testing. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@35486 b3059339-0415-0410-9bf9-f77b7e298cf2 Conflicts: libmpdemux/demuxer.c libmpdemux/demuxer.h Fix code that detects streams temporarily lacking data to work properly with e.g. DVDs. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@35499 b3059339-0415-0410-9bf9-f77b7e298cf2 Conflicts: libmpdemux/demuxer.c Make stream eof detection less sensitive. Fixes bug #2111. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@35543 b3059339-0415-0410-9bf9-f77b7e298cf2 Conflicts: libmpdemux/demuxer.c
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;