Commit 3fda8a63 authored by cehoyos's avatar cehoyos

Generalize ID3v2 functions to support ID3v2-like ID headers with a

different magic in the header (mainly targeted to Sony's .oma/.aa3
format).

Patch by Michael Karcher, ffmpeg A mkarcher dialup fu-berlin de


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@23583 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 22cfcb0a
...@@ -43,7 +43,7 @@ static int flac_read_header(AVFormatContext *s, ...@@ -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) ...@@ -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 @@ ...@@ -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' && return buf[0] == magic[0] &&
buf[1] == 'D' && buf[1] == magic[1] &&
buf[2] == '3' && 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) ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment