different magic in the header (mainly targeted to Sony's .oma/.aa3 format). Patch by Michael Karcher, ffmpeg A mkarcher dialup fu-berlin de Originally committed as revision 23583 to svn://svn.ffmpeg.org/ffmpeg/trunktags/n0.8
| @@ -43,7 +43,7 @@ static int flac_read_header(AVFormatContext *s, | |||||
| /* skip ID3v2 header if found */ | /* skip ID3v2 header if found */ | ||||
| ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); | ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); | ||||
| if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf)) { | |||||
| if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) { | |||||
| int len = ff_id3v2_tag_len(buf); | int len = ff_id3v2_tag_len(buf); | ||||
| url_fseek(s->pb, len - ID3v2_HEADER_SIZE, SEEK_CUR); | url_fseek(s->pb, len - ID3v2_HEADER_SIZE, SEEK_CUR); | ||||
| } else { | } else { | ||||
| @@ -130,7 +130,7 @@ static int flac_probe(AVProbeData *p) | |||||
| uint8_t *bufptr = p->buf; | uint8_t *bufptr = p->buf; | ||||
| uint8_t *end = p->buf + p->buf_size; | uint8_t *end = p->buf + p->buf_size; | ||||
| if(ff_id3v2_match(bufptr)) | |||||
| if(ff_id3v2_match(bufptr, ID3v2_DEFAULT_MAGIC)) | |||||
| bufptr += ff_id3v2_tag_len(bufptr); | bufptr += ff_id3v2_tag_len(bufptr); | ||||
| if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0; | if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0; | ||||
| @@ -22,12 +22,13 @@ | |||||
| #include "id3v2.h" | #include "id3v2.h" | ||||
| #include "id3v1.h" | #include "id3v1.h" | ||||
| #include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
| #include "libavutil/intreadwrite.h" | |||||
| int ff_id3v2_match(const uint8_t *buf) | |||||
| int ff_id3v2_match(const uint8_t *buf, const char * magic) | |||||
| { | { | ||||
| return buf[0] == 'I' && | |||||
| buf[1] == 'D' && | |||||
| buf[2] == '3' && | |||||
| return buf[0] == magic[0] && | |||||
| buf[1] == magic[1] && | |||||
| buf[2] == magic[2] && | |||||
| buf[3] != 0xff && | buf[3] != 0xff && | ||||
| buf[4] != 0xff && | buf[4] != 0xff && | ||||
| (buf[6] & 0x80) == 0 && | (buf[6] & 0x80) == 0 && | ||||
| @@ -48,7 +49,7 @@ int ff_id3v2_tag_len(const uint8_t * buf) | |||||
| return len; | return len; | ||||
| } | } | ||||
| void ff_id3v2_read(AVFormatContext *s) | |||||
| void ff_id3v2_read(AVFormatContext *s, const char *magic) | |||||
| { | { | ||||
| int len, ret; | int len, ret; | ||||
| uint8_t buf[ID3v2_HEADER_SIZE]; | uint8_t buf[ID3v2_HEADER_SIZE]; | ||||
| @@ -56,7 +57,7 @@ void ff_id3v2_read(AVFormatContext *s) | |||||
| ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); | ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); | ||||
| if (ret != ID3v2_HEADER_SIZE) | if (ret != ID3v2_HEADER_SIZE) | ||||
| return; | return; | ||||
| if (ff_id3v2_match(buf)) { | |||||
| if (ff_id3v2_match(buf, magic)) { | |||||
| /* parse ID3v2 header */ | /* parse ID3v2 header */ | ||||
| len = ((buf[6] & 0x7f) << 21) | | len = ((buf[6] & 0x7f) << 21) | | ||||
| ((buf[7] & 0x7f) << 14) | | ((buf[7] & 0x7f) << 14) | | ||||
| @@ -28,11 +28,18 @@ | |||||
| #define ID3v2_HEADER_SIZE 10 | #define ID3v2_HEADER_SIZE 10 | ||||
| /** | |||||
| * Default magic bytes for ID3v2 header: "ID3" | |||||
| */ | |||||
| #define ID3v2_DEFAULT_MAGIC "ID3" | |||||
| /** | /** | ||||
| * Detects ID3v2 Header. | * Detects ID3v2 Header. | ||||
| * @buf must be ID3v2_HEADER_SIZE byte long | |||||
| * @buf must be ID3v2_HEADER_SIZE byte long | |||||
| * @magic magic bytes to identify the header, machine byte order. | |||||
| * If in doubt, use ID3v2_DEFAULT_MAGIC. | |||||
| */ | */ | ||||
| int ff_id3v2_match(const uint8_t *buf); | |||||
| int ff_id3v2_match(const uint8_t *buf, const char *magic); | |||||
| /** | /** | ||||
| * Gets the length of an ID3v2 tag. | * Gets the length of an ID3v2 tag. | ||||
| @@ -50,7 +57,7 @@ void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags) | |||||
| /** | /** | ||||
| * Read an ID3v2 tag | * Read an ID3v2 tag | ||||
| */ | */ | ||||
| void ff_id3v2_read(AVFormatContext *s); | |||||
| void ff_id3v2_read(AVFormatContext *s, const char *magic); | |||||
| extern const AVMetadataConv ff_id3v2_metadata_conv[]; | extern const AVMetadataConv ff_id3v2_metadata_conv[]; | ||||
| @@ -42,7 +42,7 @@ static int mp3_read_probe(AVProbeData *p) | |||||
| AVCodecContext avctx; | AVCodecContext avctx; | ||||
| buf0 = p->buf; | buf0 = p->buf; | ||||
| if(ff_id3v2_match(buf0)) { | |||||
| if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC)) { | |||||
| buf0 += ff_id3v2_tag_len(buf0); | buf0 += ff_id3v2_tag_len(buf0); | ||||
| } | } | ||||
| end = p->buf + p->buf_size - sizeof(uint32_t); | end = p->buf + p->buf_size - sizeof(uint32_t); | ||||
| @@ -148,7 +148,7 @@ static int mp3_read_header(AVFormatContext *s, | |||||
| // lcm of all mp3 sample rates | // lcm of all mp3 sample rates | ||||
| av_set_pts_info(st, 64, 1, 14112000); | av_set_pts_info(st, 64, 1, 14112000); | ||||
| ff_id3v2_read(s); | |||||
| ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); | |||||
| off = url_ftell(s->pb); | off = url_ftell(s->pb); | ||||
| if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) | if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) | ||||
| @@ -45,7 +45,7 @@ typedef struct { | |||||
| static int mpc_probe(AVProbeData *p) | static int mpc_probe(AVProbeData *p) | ||||
| { | { | ||||
| const uint8_t *d = p->buf; | const uint8_t *d = p->buf; | ||||
| if (ff_id3v2_match(d)) { | |||||
| if (ff_id3v2_match(d, ID3v2_DEFAULT_MAGIC)) { | |||||
| d += ff_id3v2_tag_len(d); | d += ff_id3v2_tag_len(d); | ||||
| } | } | ||||
| if (d+3 < p->buf+p->buf_size) | if (d+3 < p->buf+p->buf_size) | ||||
| @@ -67,7 +67,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| if (url_fseek(s->pb, pos, SEEK_SET) < 0) | if (url_fseek(s->pb, pos, SEEK_SET) < 0) | ||||
| return -1; | return -1; | ||||
| ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); | ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); | ||||
| if (ret != ID3v2_HEADER_SIZE || !ff_id3v2_match(buf)) { | |||||
| if (ret != ID3v2_HEADER_SIZE || !ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) { | |||||
| av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); | av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -82,7 +82,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| /* read ID3 tags */ | /* read ID3 tags */ | ||||
| if (url_fseek(s->pb, pos, SEEK_SET) < 0) | if (url_fseek(s->pb, pos, SEEK_SET) < 0) | ||||
| return -1; | return -1; | ||||
| ff_id3v2_read(s); | |||||
| ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); | |||||
| get_le24(s->pb); | get_le24(s->pb); | ||||
| } | } | ||||
| c->ver = get_byte(s->pb); | c->ver = get_byte(s->pb); | ||||
| @@ -664,7 +664,7 @@ static int adts_aac_probe(AVProbeData *p) | |||||
| uint8_t *buf; | uint8_t *buf; | ||||
| uint8_t *end = buf0 + p->buf_size - 7; | uint8_t *end = buf0 + p->buf_size - 7; | ||||
| if (ff_id3v2_match(buf0)) { | |||||
| if (ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC)) { | |||||
| buf0 += ff_id3v2_tag_len(buf0); | buf0 += ff_id3v2_tag_len(buf0); | ||||
| } | } | ||||
| buf = buf0; | buf = buf0; | ||||
| @@ -706,7 +706,7 @@ static int adts_aac_read_header(AVFormatContext *s, | |||||
| st->need_parsing = AVSTREAM_PARSE_FULL; | st->need_parsing = AVSTREAM_PARSE_FULL; | ||||
| ff_id3v1_read(s); | ff_id3v1_read(s); | ||||
| ff_id3v2_read(s); | |||||
| ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -32,7 +32,7 @@ static int tta_probe(AVProbeData *p) | |||||
| { | { | ||||
| const uint8_t *d = p->buf; | const uint8_t *d = p->buf; | ||||
| if (ff_id3v2_match(d)) | |||||
| if (ff_id3v2_match(d, ID3v2_DEFAULT_MAGIC)) | |||||
| d += ff_id3v2_tag_len(d); | d += ff_id3v2_tag_len(d); | ||||
| if (d - p->buf >= p->buf_size) | if (d - p->buf >= p->buf_size) | ||||
| @@ -50,7 +50,7 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| int i, channels, bps, samplerate, datalen, framelen; | int i, channels, bps, samplerate, datalen, framelen; | ||||
| uint64_t framepos, start_offset; | uint64_t framepos, start_offset; | ||||
| ff_id3v2_read(s); | |||||
| ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); | |||||
| if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) | if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) | ||||
| ff_id3v1_read(s); | ff_id3v1_read(s); | ||||