add last backwards-compatible version
This commit is contained in:
@@ -3,78 +3,8 @@
|
||||
#include "packet_decoder_aac_common.h"
|
||||
|
||||
#include "../SDK/filesystem_helper.h"
|
||||
#include "bitreader_helper.h"
|
||||
|
||||
size_t packet_decoder_aac_common::skipADTSHeader( const uint8_t * data,size_t size ) {
|
||||
if ( size < 7 ) throw exception_io_data();
|
||||
PFC_ASSERT( bitreader_helper::extract_int(data, 0, 12) == 0xFFF);
|
||||
if (bitreader_helper::extract_bit(data, 12+1+2)) {
|
||||
return 7; // ABSENT flag
|
||||
}
|
||||
if (size < 9) throw exception_io_data();
|
||||
return 9;
|
||||
}
|
||||
|
||||
pfc::array_t<uint8_t> packet_decoder_aac_common::parseDecoderSetup( const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size) {
|
||||
|
||||
if ( p_owner == owner_ADTS ) {
|
||||
pfc::array_t<uint8_t> ret;
|
||||
ret.resize( 2 );
|
||||
ret[0] = 0; ret[1] = 0;
|
||||
// ret:
|
||||
// 5 bits AOT
|
||||
// 4 bits freqindex
|
||||
// 4 bits channelconfig
|
||||
|
||||
// source:
|
||||
// 12 bits 0xFFF
|
||||
// 4 bits disregard
|
||||
// 2 bits AOT-1 @ 16
|
||||
// 4 bits freqindex @ 18
|
||||
// 1 bit disregard
|
||||
// 3 bits channelconfig @ 23
|
||||
// 26 bits total, 4 bytes minimum
|
||||
|
||||
|
||||
if ( p_param2size < 4 ) throw exception_io_data();
|
||||
const uint8_t * source = (const uint8_t*) p_param2;
|
||||
if ( bitreader_helper::extract_int(source, 0, 12) != 0xFFF ) throw exception_io_data();
|
||||
size_t aot = bitreader_helper::extract_int(source, 16, 2) + 1;
|
||||
if ( aot >= 31 ) throw exception_io_data();
|
||||
size_t freqindex = bitreader_helper::extract_int(source, 18, 4);
|
||||
if ( freqindex > 12 ) throw exception_io_data();
|
||||
size_t channelconfig = bitreader_helper::extract_bits( source, 23, 3);
|
||||
|
||||
bitreader_helper::write_int(ret.get_ptr(), 0, 5, aot);
|
||||
bitreader_helper::write_int(ret.get_ptr(), 5, 4, freqindex);
|
||||
bitreader_helper::write_int(ret.get_ptr(), 9, 4, channelconfig);
|
||||
return ret;
|
||||
} else if ( p_owner == owner_ADIF ) {
|
||||
// bah
|
||||
} else if ( p_owner == owner_MP4 )
|
||||
{
|
||||
if ( p_param1 == 0x40 || p_param1 == 0x66 || p_param1 == 0x67 || p_param1 == 0x68 ) {
|
||||
pfc::array_t<uint8_t> ret;
|
||||
ret.set_data_fromptr( (const uint8_t*) p_param2, p_param2size);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if ( p_owner == owner_matroska )
|
||||
{
|
||||
const matroska_setup * setup = ( const matroska_setup * ) p_param2;
|
||||
if ( p_param2size == sizeof(*setup) )
|
||||
{
|
||||
if ( !strcmp(setup->codec_id, "A_AAC") || !strncmp(setup->codec_id, "A_AAC/", 6) ) {
|
||||
pfc::array_t<uint8_t> ret;
|
||||
ret.set_data_fromptr( (const uint8_t*) setup->codec_private, setup->codec_private_size );
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw exception_io_data();
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool packet_decoder_aac_common::parseDecoderSetup(const GUID &p_owner, t_size p_param1, const void *p_param2, t_size p_param2size, const void *&outCodecPrivate, size_t &outCodecPrivateSize) {
|
||||
outCodecPrivate = NULL;
|
||||
outCodecPrivateSize = 0;
|
||||
@@ -103,31 +33,16 @@ bool packet_decoder_aac_common::parseDecoderSetup(const GUID &p_owner, t_size p_
|
||||
return false;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
bool packet_decoder_aac_common::testDecoderSetup( const GUID & p_owner, t_size p_param1, const void * p_param2, t_size p_param2size ) {
|
||||
if ( p_owner == owner_ADTS ) { return true; }
|
||||
else if ( p_owner == owner_ADIF ) { return true; }
|
||||
else if ( p_owner == owner_MP4 )
|
||||
{
|
||||
if ( p_param1 == 0x40 || p_param1 == 0x66 || p_param1 == 0x67 || p_param1 == 0x68 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ( p_owner == owner_matroska )
|
||||
{
|
||||
const matroska_setup * setup = ( const matroska_setup * ) p_param2;
|
||||
if ( p_param2size == sizeof(*setup) )
|
||||
{
|
||||
if ( !strcmp(setup->codec_id, "A_AAC") || !strncmp(setup->codec_id, "A_AAC/", 6) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
const void * dummy1; size_t dummy2;
|
||||
return parseDecoderSetup(p_owner, p_param1, p_param2, p_param2size, dummy1, dummy2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
class esds_maker : public stream_writer_buffer_simple {
|
||||
public:
|
||||
@@ -152,8 +67,8 @@ namespace {
|
||||
|
||||
void packet_decoder_aac_common::make_ESDS( pfc::array_t<uint8_t> & outESDS, const void * inCodecPrivate, size_t inCodecPrivateSize ) {
|
||||
if (inCodecPrivateSize > 1024*1024) throw exception_io_data(); // sanity
|
||||
auto & p_abort = fb2k::noAbort;
|
||||
|
||||
abort_callback_dummy p_abort;
|
||||
|
||||
esds_maker esds4;
|
||||
|
||||
const uint8_t crap[] = {0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x05, 0x34, 0x08, 0x00, 0x02, 0x3D, 0x55};
|
||||
@@ -191,57 +106,3 @@ void packet_decoder_aac_common::make_ESDS( pfc::array_t<uint8_t> & outESDS, cons
|
||||
// For: 12 30 56 E5 00
|
||||
|
||||
}
|
||||
|
||||
const uint32_t aac_sample_rates[] = {
|
||||
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
|
||||
};
|
||||
|
||||
static unsigned readSamplingFreq(bitreader_helper::bitreader_limited& r) {
|
||||
unsigned samplingRateIndex = (unsigned)r.read(4);
|
||||
if (samplingRateIndex == 15) {
|
||||
return (unsigned)r.read(24);
|
||||
} else {
|
||||
if (samplingRateIndex >= PFC_TABSIZE(aac_sample_rates)) throw exception_io_data();
|
||||
return aac_sample_rates[samplingRateIndex];
|
||||
}
|
||||
}
|
||||
|
||||
packet_decoder_aac_common::audioSpecificConfig_t packet_decoder_aac_common::parseASC(const void * p_, size_t s) {
|
||||
// Source: https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio
|
||||
bitreader_helper::bitreader_limited r((const uint8_t*)p_, 0, s * 8);
|
||||
|
||||
audioSpecificConfig_t cfg = {};
|
||||
cfg.m_objectType = (unsigned) r.read(5);
|
||||
if (cfg.m_objectType == 31) {
|
||||
cfg.m_objectType = 32 + (unsigned) r.read(6);
|
||||
}
|
||||
|
||||
cfg.m_sampleRate = readSamplingFreq(r);
|
||||
|
||||
cfg.m_channels = (unsigned) r.read( 4 );
|
||||
|
||||
if (cfg.m_objectType == 5 || cfg.m_objectType == 29) {
|
||||
cfg.m_explicitSBR = true;
|
||||
cfg.m_explicitPS = (cfg.m_objectType == 29);
|
||||
cfg.m_sbrRate = readSamplingFreq(r);
|
||||
cfg.m_objectType = (unsigned)r.read(5);
|
||||
}
|
||||
|
||||
switch (cfg.m_objectType) {
|
||||
case 1: case 2: case 3: case 4: case 17: case 23:
|
||||
cfg.m_shortWindow = (r.read(1) != 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
unsigned packet_decoder_aac_common::get_ASC_object_type(const void * p_, size_t s) {
|
||||
// Source: https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio
|
||||
bitreader_helper::bitreader_limited r((const uint8_t*)p_, 0, s * 8);
|
||||
unsigned objectType = (unsigned) r.read(5);
|
||||
if (objectType == 31) {
|
||||
objectType = 32 + (unsigned) r.read(6);
|
||||
}
|
||||
return objectType;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user