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