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
This commit is contained in:
reimar 2011-01-27 20:37:51 +00:00 committed by wm4
parent fdbf437055
commit 4a40eeda94
3 changed files with 33 additions and 6 deletions

View File

@ -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;

View File

@ -120,6 +120,7 @@ typedef struct demux_stream {
int pack_no; // serial number of packet
bool keyframe; // keyframe flag of current packet
//---------------
int fill_count; // number of unsuccessful tries to get a packet
int packs; // number of packets in buffer
int bytes; // total bytes of packets in buffer
demux_packet_t *first; // read to current buffer from here

View File

@ -422,6 +422,7 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
int picture_coding_type=0;
int in_size=0;
video_codec_t video_codec = find_video_codec(sh_video);
sh_video->needs_parsing = video_codec != VIDEO_OTHER;
*start=NULL;