diff options
author | Mark Harris <mark.hsj@gmail.com> | 2013-12-31 11:04:54 -0800 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-01-04 22:39:07 +0100 |
commit | 262451878bab87670fba06fa6c9d798a81d39646 (patch) | |
tree | 8c969044c50b10c9109cb6d457caa39bffe71763 | |
parent | 5e0c7eab2a9d43e6e3be967ec1a6b04a3e0328da (diff) | |
download | ffmpeg-262451878bab87670fba06fa6c9d798a81d39646.tar.gz |
avformat/oggparseopus: fix segmented timestamps
Fix timestamp calculation for code 3 Ogg Opus packets with less than
2 bytes in the last segment (e.g. packet length 255 or 256).
A sample that would seek incorrectly in ffplay can be created with:
ffmpeg -i in.wav -b:a 34k -vbr off -frame_duration 60 out.opus
and libopus 1.1
Also do not read past the end of the buffer when a packet has length 0.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavformat/oggparseopus.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c index aafefbbe65..553ddb0b03 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -130,16 +130,13 @@ static int opus_packet(AVFormatContext *avf, int idx) duration += d; last_pkt = next_pkt = next_pkt + os->psize; for (; seg < os->nsegs; seg++) { - if (os->segments[seg] < 255) { - int d = opus_duration(last_pkt, os->segments[seg]); - if (d < 0) { - duration = os->granule; - break; - } - duration += d; - last_pkt = next_pkt + os->segments[seg]; - } next_pkt += os->segments[seg]; + if (os->segments[seg] < 255 && next_pkt != last_pkt) { + int d = opus_duration(last_pkt, next_pkt - last_pkt); + if (d > 0) + duration += d; + last_pkt = next_pkt; + } } os->lastpts = os->lastdts = os->granule - duration; |