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 Originally committed as revision 23583 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
1c1697117d
commit
3a1350e8d9
@ -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' &&
|
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)
|
|||||||
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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user