Cleaned up parse_xing, added support for Info magic, and added a parse_extension_headers function for when LAME tag support is added
git-svn-id: https://svn.musicpd.org/mpd/trunk@4398 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
e7566b9643
commit
6ea0ba392a
@ -402,16 +402,24 @@ static int decodeNextFrame(mp3DecodeData * data) {
|
||||
return DECODE_OK;
|
||||
}
|
||||
|
||||
/* xing stuff stolen from alsaplayer */
|
||||
/* xing stuff stolen from alsaplayer, and heavily modified by jat */
|
||||
#define XI_MAGIC (('X' << 8) | 'i')
|
||||
#define NG_MAGIC (('n' << 8) | 'g')
|
||||
#define IN_MAGIC (('I' << 8) | 'n')
|
||||
#define FO_MAGIC (('f' << 8) | 'o')
|
||||
|
||||
enum xing_magic {
|
||||
XING_MAGIC_XING, /* VBR */
|
||||
XING_MAGIC_INFO, /* CBR */
|
||||
};
|
||||
|
||||
struct xing {
|
||||
long flags; /* valid fields (see below) */
|
||||
unsigned long frames; /* total number of frames */
|
||||
unsigned long bytes; /* total number of bytes */
|
||||
unsigned char toc[100]; /* 100-point seek table */
|
||||
long scale; /* ?? */
|
||||
long scale; /* VBR quality */
|
||||
enum xing_magic magic; /* header magic */
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -421,54 +429,84 @@ enum {
|
||||
XING_SCALE = 0x00000008L
|
||||
};
|
||||
|
||||
static int parse_xing(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
|
||||
static int parse_xing(struct xing *xing, struct mad_bitptr *ptr, int bitlen)
|
||||
{
|
||||
unsigned long bits;
|
||||
int oldbitlen;
|
||||
int bitsleft;
|
||||
int i;
|
||||
|
||||
oldbitlen = bitlen;
|
||||
|
||||
if (bitlen < 16) goto fail;
|
||||
bits = mad_bit_read(&ptr, 16);
|
||||
bits = mad_bit_read(ptr, 16);
|
||||
bitlen -= 16;
|
||||
|
||||
if (bits == XI_MAGIC) {
|
||||
if (bitlen < 16) goto fail;
|
||||
if (mad_bit_read(&ptr, 16) != NG_MAGIC) goto fail;
|
||||
if (mad_bit_read(ptr, 16) != NG_MAGIC) goto fail;
|
||||
bitlen -= 16;
|
||||
xing->magic = XING_MAGIC_XING;
|
||||
} else if (bits == IN_MAGIC) {
|
||||
if (bitlen < 16) goto fail;
|
||||
if (mad_bit_read(ptr, 16) != FO_MAGIC) goto fail;
|
||||
bitlen -= 16;
|
||||
xing->magic = XING_MAGIC_INFO;
|
||||
}
|
||||
else if (bits != NG_MAGIC) goto fail;
|
||||
else if (bits == NG_MAGIC) xing->magic = XING_MAGIC_XING;
|
||||
else if (bits == FO_MAGIC) xing->magic = XING_MAGIC_INFO;
|
||||
else goto fail;
|
||||
|
||||
if (bitlen < 32) goto fail;
|
||||
xing->flags = mad_bit_read(&ptr, 32);
|
||||
xing->flags = mad_bit_read(ptr, 32);
|
||||
bitlen -= 32;
|
||||
|
||||
if (xing->flags & XING_FRAMES) {
|
||||
if (bitlen < 32) goto fail;
|
||||
xing->frames = mad_bit_read(&ptr, 32);
|
||||
xing->frames = mad_bit_read(ptr, 32);
|
||||
bitlen -= 32;
|
||||
}
|
||||
|
||||
if (xing->flags & XING_BYTES) {
|
||||
if (bitlen < 32) goto fail;
|
||||
xing->bytes = mad_bit_read(&ptr, 32);
|
||||
xing->bytes = mad_bit_read(ptr, 32);
|
||||
bitlen -= 32;
|
||||
}
|
||||
|
||||
if (xing->flags & XING_TOC) {
|
||||
int i;
|
||||
if (bitlen < 800) goto fail;
|
||||
for (i = 0; i < 100; ++i) xing->toc[i] = mad_bit_read(&ptr, 8);
|
||||
for (i = 0; i < 100; ++i) xing->toc[i] = mad_bit_read(ptr, 8);
|
||||
bitlen -= 800;
|
||||
}
|
||||
|
||||
if (xing->flags & XING_SCALE) {
|
||||
if (bitlen < 32) goto fail;
|
||||
xing->scale = mad_bit_read(&ptr, 32);
|
||||
xing->scale = mad_bit_read(ptr, 32);
|
||||
bitlen -= 32;
|
||||
}
|
||||
|
||||
return 1;
|
||||
/* Make sure we consume no less than 120 bytes (960 bits) in hopes that
|
||||
* the LAME tag is found there, and not right after the Xing header */
|
||||
bitsleft = 960-(oldbitlen-bitlen);
|
||||
if (bitsleft < 0) goto fail;
|
||||
else if (bitsleft > 0) {
|
||||
mad_bit_read(ptr, bitsleft);
|
||||
bitlen -= bitsleft;
|
||||
}
|
||||
|
||||
return bitlen;
|
||||
fail:
|
||||
xing->flags = 0;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_extension_headers(struct xing *xing, struct mad_bitptr ptr,
|
||||
int bitlen)
|
||||
{
|
||||
bitlen = parse_xing(xing, &ptr, bitlen);
|
||||
if (bitlen < 0) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
|
||||
@ -493,7 +531,8 @@ static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
|
||||
if(!skip && ret==DECODE_OK) break;
|
||||
}
|
||||
|
||||
if(parse_xing(&xing,data->stream.anc_ptr,data->stream.anc_bitlen)) {
|
||||
if(parse_extension_headers(&xing, data->stream.anc_ptr,
|
||||
(int)data->stream.anc_bitlen)) {
|
||||
if(xing.flags & XING_FRAMES) {
|
||||
mad_timer_t duration = data->frame.header.duration;
|
||||
mad_timer_multiply(&duration,xing.frames);
|
||||
|
Loading…
Reference in New Issue
Block a user