diff options
author | wm4 <nfxjfg@googlemail.com> | 2014-09-21 12:51:41 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-09-21 14:57:12 +0200 |
commit | 6c7f1155bb648eced8e5aa08b1fd490df2f8b325 (patch) | |
tree | 607abb626c790b71c3a55e0597fe501b21499240 /libavformat/utils.c | |
parent | 36bf549b2706bd10014556a84a33ed6daf5d5373 (diff) | |
download | ffmpeg-6c7f1155bb648eced8e5aa08b1fd490df2f8b325.tar.gz |
avformat/mp3dec: avoid early EOF with concatenated gapless mp3s
Consider a file created with something like:
cat file1.mp3 file2.mp3 > result.mp3
Then if file2.mp3 has gapless information, result.mp3 would stop playing
something in the middle. This happens because the gapless info directs
the decoder to discard all samples after a certain position. To make
matters worse, the gapless info of file2.mp3 will be used when playing
the file1.mp3 part, because the gapless info is located at the end of
the file.
While handling concatenated gapless files correctly would be insane and
a lot of effort (especially without scanning the whole file on opening),
it's easy to prevent at least early EOF. Playback will happen to work,
even if it's slightly broken.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index 58533f88e9..e0e78a78f1 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1358,13 +1358,14 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (ret >= 0) { AVStream *st = s->streams[pkt->stream_index]; int discard_padding = 0; - if (st->end_discard_sample && pkt->pts != AV_NOPTS_VALUE) { + if (st->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) { int64_t pts = pkt->pts - (is_relative(pkt->pts) ? RELATIVE_TS_BASE : 0); int64_t sample = ts_to_samples(st, pts); int duration = ts_to_samples(st, pkt->duration); int64_t end_sample = sample + duration; - if (duration > 0 && end_sample >= st->end_discard_sample) - discard_padding = FFMIN(end_sample - st->end_discard_sample, duration); + if (duration > 0 && end_sample >= st->first_discard_sample && + sample < st->last_discard_sample) + discard_padding = FFMIN(end_sample - st->first_discard_sample, duration); } if (st->skip_samples || discard_padding) { uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); |