summaryrefslogtreecommitdiff
path: root/libavformat/oggparseopus.c
diff options
context:
space:
mode:
authorMark Harris <mark.hsj@gmail.com>2013-12-31 11:04:54 -0800
committerMichael Niedermayer <michaelni@gmx.at>2014-01-04 22:39:07 +0100
commit262451878bab87670fba06fa6c9d798a81d39646 (patch)
tree8c969044c50b10c9109cb6d457caa39bffe71763 /libavformat/oggparseopus.c
parent5e0c7eab2a9d43e6e3be967ec1a6b04a3e0328da (diff)
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>
Diffstat (limited to 'libavformat/oggparseopus.c')
-rw-r--r--libavformat/oggparseopus.c15
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;