[FFmpeg-devel] [PATCH] avformat/oggparseopus: fix segmented timestamps

Mark Harris mark.hsj at gmail.com
Tue Dec 31 20:04:54 CET 2013


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

Also do not read past the end of the buffer when a packet has length 0.
---
 libavformat/oggparseopus.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c
index aafefbb..553ddb0 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;
-- 
1.8.5.2



More information about the ffmpeg-devel mailing list