X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmp3dec.c;h=53f803ef55101b1f05ac4bd4c8b0eae2509a1f0e;hb=131f2c2712479a44332866b442526abe97e0c316;hp=ef884934e16062240fba7a49bae73d90897dc77f;hpb=c6892f59eb0e9f2a9ec1f55b21a5841a60540e1f;p=ffmpeg diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index ef884934e16..53f803ef551 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -42,8 +42,6 @@ #define XING_TOC_COUNT 100 -#define SAME_HEADER_MASK \ - (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) typedef struct { AVClass *class; @@ -66,39 +64,53 @@ static int check(AVIOContext *pb, int64_t pos, uint32_t *header); /* mp3 read */ -static int mp3_read_probe(AVProbeData *p) +static int mp3_read_probe(const AVProbeData *p) { int max_frames, first_frames = 0; int whole_used = 0; 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); - while(buf0 < end && !*buf0) + while (buf0 < end && !*buf0) buf0++; max_frames = 0; max_framesizes = 0; buf = buf0; - for(; buf < end; buf= buf2+1) { + for (; buf < end; buf = buf2+1) { buf2 = buf; - for(framesizes = frames = 0; buf2 < end; frames++) { + 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); - if(buf == buf0) { + if (buf == buf0) { first_frames= frames; if (buf2 == end + sizeof(uint32_t)) whole_used = 1; @@ -107,14 +119,14 @@ static int mp3_read_probe(AVProbeData *p) // keep this in sync with ac3 probe, both need to avoid // issues with MPEG-files! if (first_frames>=7) return AVPROBE_SCORE_EXTENSION + 1; - else if(max_frames>200 && p->buf_size < 2*max_framesizes)return AVPROBE_SCORE_EXTENSION; - else if(max_frames>=4 && p->buf_size < 2*max_framesizes) return AVPROBE_SCORE_EXTENSION / 2; - else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size) + else if (max_frames>200 && p->buf_size < 2*max_framesizes)return AVPROBE_SCORE_EXTENSION; + else if (max_frames>=4 && p->buf_size < 2*max_framesizes) return AVPROBE_SCORE_EXTENSION / 2; + else if (ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size) return p->buf_size < PROBE_BUF_MAX ? AVPROBE_SCORE_EXTENSION / 4 : AVPROBE_SCORE_EXTENSION - 2; - else if(first_frames > 1 && whole_used) return 5; - else if(max_frames>=1 && p->buf_size < 10*max_framesizes) return 1; + else if (first_frames > 1 && whole_used) return 5; + else if (max_frames>=1 && p->buf_size < 10*max_framesizes) return 1; else return 0; -//mpegps_mp3_unrecognized_format.mpg has max_frames=3 + //mpegps_mp3_unrecognized_format.mpg has max_frames=3 } static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration) @@ -235,21 +247,21 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, avio_r8(s->pb); /* Encoder delays */ - v= avio_rb24(s->pb); - if(AV_RB32(version) == MKBETAG('L', 'A', 'M', 'E') + v = avio_rb24(s->pb); + if (AV_RB32(version) == MKBETAG('L', 'A', 'M', 'E') || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'f') || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'c') ) { 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); @@ -319,7 +331,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) return ret; else if (ret == 0) vbrtag_size = c.frame_size; - if(c.layer != 3) + if (c.layer != 3) return -1; spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ @@ -374,7 +386,7 @@ static int mp3_read_header(AVFormatContext *s) if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); - if(s->pb->seekable & AVIO_SEEKABLE_NORMAL) + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) mp3->filesize = avio_size(s->pb); if (mp3_parse_vbr_tags(s, st, off) < 0) @@ -398,7 +410,7 @@ static int mp3_read_header(AVFormatContext *s) 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); @@ -419,8 +431,8 @@ static int mp3_read_header(AVFormatContext *s) } // 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; @@ -434,12 +446,12 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) int ret, size; int64_t pos; - size= MP3_PACKET_SIZE; + size = MP3_PACKET_SIZE; pos = avio_tell(s->pb); - if(mp3->filesize > ID3v1_TAG_SIZE && pos < mp3->filesize) + if (mp3->filesize > ID3v1_TAG_SIZE && pos < mp3->filesize) size= FFMIN(size, mp3->filesize - pos); - ret= av_get_packet(s->pb, pkt, size); + ret = av_get_packet(s->pb, pkt, size); if (ret <= 0) { if(ret<0) return ret; @@ -494,7 +506,7 @@ static int64_t mp3_sync(AVFormatContext *s, int64_t target_pos, int flags) #define MIN_VALID 3 best_pos = target_pos; best_score = 999; - for(i=0; i 0 ? i - SEEK_WINDOW/4 : -i); int64_t candidate = -1; int score = 999; @@ -502,9 +514,9 @@ static int64_t mp3_sync(AVFormatContext *s, int64_t target_pos, int flags) if (pos < 0) continue; - for(j=0; jpb, pos, NULL); - if(ret < 0) { + if (ret < 0) { if (ret == CHECK_WRONG_HEADER) { break; } else if (ret == CHECK_SEEK_FAILED) { @@ -555,7 +567,7 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, 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");