#define XING_TOC_COUNT 100
-#define SAME_HEADER_MASK \
- (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
typedef struct {
AVClass *class;
int frames, ret;
int framesizes, max_framesizes;
uint32_t header;
- const uint8_t *buf, *buf0, *buf2, *end;
+ const uint8_t *buf, *buf0, *buf2, *buf3, *end;
buf0 = p->buf;
end = p->buf + p->buf_size - sizeof(uint32_t);
buf2 = buf;
for (framesizes = frames = 0; buf2 < end; frames++) {
MPADecodeHeader h;
+ int header_emu = 0;
+ int available;
header = AV_RB32(buf2);
ret = avpriv_mpegaudio_decode_header(&h, header);
if (ret != 0)
break;
- buf2 += h.frame_size;
+
+ available = FFMIN(h.frame_size, end - buf2);
+ for (buf3 = buf2 + 4; buf3 < buf2 + available; buf3++) {
+ uint32_t next_sync = AV_RB32(buf3);
+ header_emu += (next_sync & MP3_MASK) == (header & MP3_MASK);
+ }
+ if (header_emu > 2)
+ break;
framesizes += h.frame_size;
+ if (available < h.frame_size) {
+ frames++;
+ break;
+ }
+ buf2 += h.frame_size;
}
max_frames = FFMAX(max_frames, frames);
max_framesizes = FFMAX(max_framesizes, framesizes);
mp3->start_pad = v>>12;
mp3-> end_pad = v&4095;
- st->start_skip_samples = mp3->start_pad + 528 + 1;
+ st->internal->start_skip_samples = mp3->start_pad + 528 + 1;
if (mp3->frames) {
- st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
- st->last_discard_sample = mp3->frames * (int64_t)spf;
+ st->internal->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
+ st->internal->last_discard_sample = mp3->frames * (int64_t)spf;
}
if (!st->start_time)
- st->start_time = av_rescale_q(st->start_skip_samples,
+ st->start_time = av_rescale_q(st->internal->start_skip_samples,
(AVRational){1, c->sample_rate},
st->time_base);
av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad);
ffio_ensure_seekback(s->pb, i + 1024 + frame_size + 4);
ret = check(s->pb, off + i + frame_size, &header2);
if (ret >= 0 &&
- (header & SAME_HEADER_MASK) == (header2 & SAME_HEADER_MASK))
+ (header & MP3_MASK) == (header2 & MP3_MASK))
{
av_log(s, i > 0 ? AV_LOG_INFO : AV_LOG_VERBOSE, "Skipping %d bytes of junk at %"PRId64".\n", i, off);
ret = avio_seek(s->pb, off + i, SEEK_SET);
}
// the seek index is relative to the end of the xing vbr headers
- for (i = 0; i < st->nb_index_entries; i++)
- st->index_entries[i].pos += avio_tell(s->pb);
+ for (i = 0; i < st->internal->nb_index_entries; i++)
+ st->internal->index_entries[i].pos += avio_tell(s->pb);
/* the parameters will be extracted from the compressed bitstream */
return 0;
if (ret < 0)
return ret;
- ie = &st->index_entries[ret];
+ ie = &st->internal->index_entries[ret];
} else if (fast_seek && st->duration > 0 && filesize > 0) {
if (!mp3->is_cbr)
av_log(s, AV_LOG_WARNING, "Using scaling to seek VBR MP3; may be imprecise.\n");