From 4a40eeda941717b1a3d60d22c0c1020ea9c2038d Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 27 Jan 2011 20:37:51 +0000 Subject: 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 --- demux/demux.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'demux/demux.c') 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; -- cgit v1.2.3