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
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel