mirror of https://github.com/mpv-player/mpv
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:
parent
fdbf437055
commit
4a40eeda94
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue