typedef struct {
int64_t filesize;
+ int start_pad;
+ int end_pad;
} MP3Context;
/* mp3 read */
*/
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 */
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') || v == MKBETAG('L', 'a', 'v', 'f')) {
+ 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) */
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = CODEC_ID_MP3;
- st->need_parsing = AVSTREAM_PARSE_FULL;
+ st->codec->codec_id = AV_CODEC_ID_MP3;
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
st->start_time = 0;
// lcm of all mp3 sample rates
MP3Context *mp3 = s->priv_data;
int ret, size;
int64_t pos;
- // AVStream *st = s->streams[0];
size= MP3_PACKET_SIZE;
pos = avio_tell(s->pb);
size= FFMIN(size, mp3->filesize - pos);
ret= av_get_packet(s->pb, pkt, size);
-
- pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
- pkt->stream_index = 0;
if (ret <= 0) {
if(ret<0)
return ret;
return AVERROR_EOF;
}
+ pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
+ pkt->stream_index = 0;
+
if (ret >= ID3v1_TAG_SIZE &&
memcmp(&pkt->data[ret - ID3v1_TAG_SIZE], "TAG", 3) == 0)
ret -= ID3v1_TAG_SIZE;
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"),
+ .long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"),
.priv_data_size = sizeof(MP3Context),
.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 */
};