diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 61405f71b7..2b8aa37dad 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -31,6 +31,8 @@ typedef struct { int64_t filesize; + int start_pad; + int end_pad; } MP3Context; /* mp3 read */ @@ -82,6 +84,7 @@ static int mp3_read_probe(AVProbeData *p) */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { + MP3Context *mp3 = s->priv_data; uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ @@ -107,6 +110,20 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) frames = avio_rb32(s->pb); if(v & 0x2) size = avio_rb32(s->pb); + if(v & 4) + avio_skip(s->pb, 100); + if(v & 8) + avio_skip(s->pb, 4); + + v = avio_rb32(s->pb); + if(v == MKBETAG('L', 'A', 'M', 'E')) { + avio_skip(s->pb, 21-4); + v= avio_rb24(s->pb); + mp3->start_pad = v>>12; + mp3-> end_pad = v&4095; + st->skip_samples = mp3->start_pad + 528 + 1; + av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); + } } /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ @@ -206,6 +223,16 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; } +static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +{ + MP3Context *mp3 = s->priv_data; + AVStream *st = s->streams[stream_index]; + + st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; + + return -1; +} + AVInputFormat ff_mp3_demuxer = { .name = "mp3", .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"), @@ -213,6 +240,7 @@ AVInputFormat ff_mp3_demuxer = { .read_probe = mp3_read_probe, .read_header = mp3_read_header, .read_packet = mp3_read_packet, + .read_seek = read_seek, .flags = AVFMT_GENERIC_INDEX, .extensions = "mp2,mp3,m2a", /* XXX: use probe */ };