MP3 frames may not be aligned to aa chunk boundaries. After seeking,
scan for the next valid frame header. Then truncate the packet, and
also adjust timestamp information accordingly.
---
 libavformat/aadec.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/libavformat/aadec.c b/libavformat/aadec.c
index b009c9deca..3bb8cd0768 100644
--- a/libavformat/aadec.c
+++ b/libavformat/aadec.c
@@ -50,6 +50,7 @@ typedef struct AADemuxContext {
     int64_t current_chapter_size;
     int64_t content_start;
     int64_t content_end;
+    int did_seek;
 } AADemuxContext;
 
 static int get_second_size(char *codec_name)
@@ -205,6 +206,7 @@ static int aa_read_header(AVFormatContext *s)
     }
     start = TOC[largest_idx].offset;
     avio_seek(pb, start, SEEK_SET);
+    c->did_seek = 0;
 
     // extract chapter positions. since all formats have constant bit rate, 
use it
     // as time base in bytes/s, for easy stream position <-> timestamp 
conversion
@@ -242,7 +244,7 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
     int trailing_bytes;
     int blocks;
     uint8_t buf[MAX_CODEC_SECOND_SIZE * 2];
-    int written = 0;
+    int written = 0, offset = 0;
     int ret;
     AADemuxContext *c = s->priv_data;
     uint64_t pos = avio_tell(s->pb);
@@ -295,10 +297,32 @@ static int aa_read_packet(AVFormatContext *s, AVPacket 
*pkt)
     if (c->current_chapter_size <= 0)
         c->current_chapter_size = 0;
 
-    ret = av_new_packet(pkt, written);
+    // re-init timestamps after seeking
+    if (c->did_seek) {
+        c->did_seek = 0;
+
+        if (s->streams[0]->codecpar->codec_id == AV_CODEC_ID_MP3) {
+            for (; offset < written - 2; ++offset) {
+                // find mp3 header: sync, v2, layer3, 32kbps, non-reserved 
sample rate
+                if ((buf[offset + 0] & 0xff) == 0xff &&
+                    (buf[offset + 1] & 0xfe) == 0xf2 &&
+                    (buf[offset + 2] & 0xf0) == 0x40 &&
+                    (buf[offset + 2] & 0x0c) != 0x0c)
+                        break;
+            }
+            if (offset == written - 2)
+                offset = 0; // not found, e.g. chapter end chunk; just use as 
is
+        }
+        ff_update_cur_dts(s, s->streams[0],
+            (pos + offset - c->content_start - CHAPTER_HEADER_SIZE * 
(c->chapter_idx - 1))
+            * TIMEPREC);
+    }
+
+    // create packet
+    ret = av_new_packet(pkt, written - offset);
     if (ret < 0)
         return ret;
-    memcpy(pkt->data, buf, written);
+    memcpy(pkt->data, buf + offset, written - offset);
     pkt->pos = pos;
 
     return 0;
@@ -343,8 +367,7 @@ static int aa_read_seek(AVFormatContext *s,
     c->current_codec_second_size = c->codec_second_size;
     c->current_chapter_size = chapter_size - chapter_pos;
     c->chapter_idx = 1 + chapter_idx;
-
-    ff_update_cur_dts(s, s->streams[0], ch->start + chapter_pos * TIMEPREC);
+    c->did_seek = 1;
 
     return 1;
 }
-- 
2.14.3 (Apple Git-98)

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to