mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-27 22:06:58 +08:00
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:
+31
-6
@@ -623,8 +623,15 @@ int ds_fill_buffer(demux_stream_t *ds)
|
|||||||
ds == demux->audio ? "d_audio" : ds == demux->video ? "d_video" :
|
ds == demux->audio ? "d_audio" : ds == demux->video ? "d_video" :
|
||||||
ds == demux->sub ? "d_sub" : "unknown");
|
ds == demux->sub ? "d_sub" : "unknown");
|
||||||
while (1) {
|
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) {
|
if (ds->packs) {
|
||||||
demux_packet_t *p = ds->first;
|
demux_packet_t *p = ds->first;
|
||||||
|
// obviously not yet EOF after all
|
||||||
|
ds->eof = 0;
|
||||||
|
ds->fill_count = 0;
|
||||||
// copy useful data:
|
// copy useful data:
|
||||||
ds->buffer = p->buffer;
|
ds->buffer = p->buffer;
|
||||||
ds->buffer_pos = 0;
|
ds->buffer_pos = 0;
|
||||||
@@ -657,21 +664,30 @@ int ds_fill_buffer(demux_stream_t *ds)
|
|||||||
ds->eof = 0;
|
ds->eof = 0;
|
||||||
return 1;
|
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" \
|
#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")
|
"For AVI files, try to force non-interleaved mode with the --demuxer=avi --avi-ni options.\n")
|
||||||
|
|
||||||
if (demux->audio->packs >= MAX_PACKS
|
if (apacks >= MAX_PACKS || abytes >= MAX_PACK_BYTES) {
|
||||||
|| demux->audio->bytes >= MAX_PACK_BYTES) {
|
|
||||||
mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many audio packets in the buffer: (%d in %d bytes).\n",
|
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);
|
mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (demux->video->packs >= MAX_PACKS
|
if (vpacks >= MAX_PACKS || vbytes >= MAX_PACK_BYTES) {
|
||||||
|| demux->video->bytes >= MAX_PACK_BYTES) {
|
|
||||||
mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many video packets in the buffer: (%d in %d bytes).\n",
|
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);
|
mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -680,6 +696,15 @@ int ds_fill_buffer(demux_stream_t *ds)
|
|||||||
"ds_fill_buffer()->demux_fill_buffer() failed\n");
|
"ds_fill_buffer()->demux_fill_buffer() failed\n");
|
||||||
break; // EOF
|
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_pos = ds->buffer_size = 0;
|
||||||
ds->buffer = NULL;
|
ds->buffer = NULL;
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ typedef struct demux_stream {
|
|||||||
int pack_no; // serial number of packet
|
int pack_no; // serial number of packet
|
||||||
bool keyframe; // keyframe flag of current 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 packs; // number of packets in buffer
|
||||||
int bytes; // total bytes of packets in buffer
|
int bytes; // total bytes of packets in buffer
|
||||||
demux_packet_t *first; // read to current buffer from here
|
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 picture_coding_type=0;
|
||||||
int in_size=0;
|
int in_size=0;
|
||||||
video_codec_t video_codec = find_video_codec(sh_video);
|
video_codec_t video_codec = find_video_codec(sh_video);
|
||||||
|
sh_video->needs_parsing = video_codec != VIDEO_OTHER;
|
||||||
|
|
||||||
*start=NULL;
|
*start=NULL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user