mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-18 01:51:40 +00:00
Check for ID3 tags in MPG123Decoder::open
This commit is contained in:
parent
77b1febd0e
commit
73d51a4446
2 changed files with 64 additions and 69 deletions
|
@ -69,32 +69,68 @@ bool MPG123Decoder::open(const char *data, size_t length)
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemData = data;
|
// Check for ID3 tags and skip them
|
||||||
MemPos = 0;
|
if(length > 10 && memcmp(data, "ID3", 3) == 0 &&
|
||||||
MemLength = length;
|
(BYTE)data[3] <= 4 && (BYTE)data[4] != 0xff &&
|
||||||
|
(data[5]&0x0f) == 0 && (data[6]&0x80) == 0 &&
|
||||||
MPG123 = mpg123_new(NULL, NULL);
|
(data[7]&0x80) == 0 && (data[8]&0x80) == 0 &&
|
||||||
if(mpg123_replace_reader_handle(MPG123, mem_read, mem_lseek, NULL) == MPG123_OK &&
|
(data[9]&0x80) == 0)
|
||||||
mpg123_open_handle(MPG123, this) == MPG123_OK)
|
|
||||||
{
|
{
|
||||||
int enc, channels;
|
// ID3v2
|
||||||
long srate;
|
int start_offset;
|
||||||
|
start_offset = (data[6]<<21) | (data[7]<<14) |
|
||||||
if(mpg123_getformat(MPG123, &srate, &channels, &enc) == MPG123_OK)
|
(data[8]<< 7) | (data[9] );
|
||||||
{
|
start_offset += ((data[5]&0x10) ? 20 : 10);
|
||||||
if((channels == 1 || channels == 2) && srate > 0 &&
|
length -= start_offset;
|
||||||
mpg123_format_none(MPG123) == MPG123_OK &&
|
data += start_offset;
|
||||||
mpg123_format(MPG123, srate, channels, MPG123_ENC_SIGNED_16) == MPG123_OK)
|
}
|
||||||
{
|
|
||||||
// All OK
|
if(length > 128 && memcmp(data+length-128, "TAG", 3) == 0) // ID3v1
|
||||||
Done = false;
|
length -= 128;
|
||||||
return true;
|
|
||||||
}
|
// Check for a frame header
|
||||||
}
|
bool frame_ok = false;
|
||||||
mpg123_close(MPG123);
|
if(length > 3)
|
||||||
|
{
|
||||||
|
if((BYTE)data[0] == 0xff &&
|
||||||
|
((data[1]&0xfe) == 0xfa/*MPEG-1*/ || (data[1]&0xfe) == 0xf2/*MPEG-2*/))
|
||||||
|
{
|
||||||
|
int brate_idx = (data[2]>>4) & 0x0f;
|
||||||
|
int srate_idx = (data[2]>>2) & 0x03;
|
||||||
|
if(brate_idx != 0 && brate_idx != 15 && srate_idx != 3)
|
||||||
|
frame_ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(frame_ok)
|
||||||
|
{
|
||||||
|
MemData = data;
|
||||||
|
MemPos = 0;
|
||||||
|
MemLength = length;
|
||||||
|
|
||||||
|
MPG123 = mpg123_new(NULL, NULL);
|
||||||
|
if(mpg123_replace_reader_handle(MPG123, mem_read, mem_lseek, NULL) == MPG123_OK &&
|
||||||
|
mpg123_open_handle(MPG123, this) == MPG123_OK)
|
||||||
|
{
|
||||||
|
int enc, channels;
|
||||||
|
long srate;
|
||||||
|
|
||||||
|
if(mpg123_getformat(MPG123, &srate, &channels, &enc) == MPG123_OK)
|
||||||
|
{
|
||||||
|
if((channels == 1 || channels == 2) && srate > 0 &&
|
||||||
|
mpg123_format_none(MPG123) == MPG123_OK &&
|
||||||
|
mpg123_format(MPG123, srate, channels, MPG123_ENC_SIGNED_16) == MPG123_OK)
|
||||||
|
{
|
||||||
|
// All OK
|
||||||
|
Done = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mpg123_close(MPG123);
|
||||||
|
}
|
||||||
|
mpg123_delete(MPG123);
|
||||||
|
MPG123 = 0;
|
||||||
}
|
}
|
||||||
mpg123_delete(MPG123);
|
|
||||||
MPG123 = 0;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -525,52 +525,11 @@ SoundDecoder *SoundRenderer::CreateDecoder(const BYTE *sfxdata, int length)
|
||||||
{
|
{
|
||||||
SoundDecoder *decoder = NULL;
|
SoundDecoder *decoder = NULL;
|
||||||
#ifdef HAVE_MPG123
|
#ifdef HAVE_MPG123
|
||||||
int mpg_start = -1;
|
decoder = new MPG123Decoder;
|
||||||
int mpg_len = -1;
|
if(!decoder->open((const char*)sfxdata, length))
|
||||||
|
|
||||||
// Check for an ID3 tag to identify an mp3 (and skip the tag)
|
|
||||||
if(length > 10 && memcmp(sfxdata, "ID3", 3) == 0 &&
|
|
||||||
sfxdata[3] <= 4 && sfxdata[4] != 0xff &&
|
|
||||||
(sfxdata[5]&0x0f) == 0 && (sfxdata[6]&0x80) == 0 &&
|
|
||||||
(sfxdata[7]&0x80) == 0 && (sfxdata[8]&0x80) == 0 &&
|
|
||||||
(sfxdata[9]&0x80) == 0)
|
|
||||||
{
|
{
|
||||||
// ID3v2
|
delete decoder;
|
||||||
mpg_start = (sfxdata[6]<<21) | (sfxdata[7]<<14) |
|
decoder = NULL;
|
||||||
(sfxdata[8]<< 7) | (sfxdata[9] );
|
|
||||||
mpg_start += ((sfxdata[5]&0x10) ? 20 : 10);
|
|
||||||
mpg_len = length - mpg_start;
|
|
||||||
}
|
|
||||||
else if(length > 128 && memcmp(sfxdata+length-128, "TAG", 3) == 0)
|
|
||||||
{
|
|
||||||
// ID3v1
|
|
||||||
mpg_start = 0;
|
|
||||||
mpg_len = length - 128;
|
|
||||||
}
|
|
||||||
else if(length > 3)
|
|
||||||
{
|
|
||||||
// No ID3 tag. Check for a frame header
|
|
||||||
if((sfxdata[0] == 0xff && sfxdata[1]>>1 == 0x7d) || // MPEG-1
|
|
||||||
(sfxdata[0] == 0xff && sfxdata[1]>>1 == 0x79)) // MPEG-2
|
|
||||||
{
|
|
||||||
int brate_idx = (sfxdata[2]>>4) & 0x0f;
|
|
||||||
int srate_idx = (sfxdata[2]>>2) & 0x03;
|
|
||||||
if(brate_idx != 0 && brate_idx != 15 && srate_idx != 3)
|
|
||||||
{
|
|
||||||
mpg_start = 0;
|
|
||||||
mpg_len = length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mpg_start >= 0 && mpg_len > 0 && mpg_start < length && mpg_len <= length-mpg_start)
|
|
||||||
{
|
|
||||||
decoder = new MPG123Decoder;
|
|
||||||
if(!decoder->open((const char*)sfxdata+mpg_start, mpg_len))
|
|
||||||
{
|
|
||||||
delete decoder;
|
|
||||||
decoder = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SNDFILE
|
#ifdef HAVE_SNDFILE
|
||||||
|
|
Loading…
Reference in a new issue