123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #include "NSVAACDecoder.h"
- #include <assert.h>
- #include "api.h"
- #include "../nsv/nsvlib.h"
- #include "api.h"
- #include "../nsv/nsvlib.h"
- #include "../nsv/dec_if.h"
- #include <string.h>
- #include <bfc/platform/export.h>
- #include "NSVAACDecoder.h"
- #include <bfc/error.h>
- #ifndef MIN
- #define MIN(a,b) (((a) < (b)) ? (a) : (b))
- #endif
- NSVAACDecoder *NSVAACDecoder::CreateDecoder()
- {
- CAccessUnitPtr access_unit = CAccessUnit_Create(0, 0);
- if (!access_unit)
- return 0;
- NSVAACDecoder *decoder=0;
- WASABI_API_MEMMGR->New(&decoder);
- if (!decoder)
- {
- CAccessUnit_Destroy(&access_unit);
- return 0;
- }
- decoder->Initialize(access_unit);
- return decoder;
- }
- NSVAACDecoder::NSVAACDecoder()
- {
- access_unit = 0;
- composition_unit = 0;
- decoder = 0;
- source_position=0;
- out_left=0;
- in_position=0;
- }
- NSVAACDecoder::~NSVAACDecoder()
- {
- mp4AudioDecoder_Destroy(&decoder);
- CAccessUnit_Destroy(&access_unit);
- CCompositionUnit_Destroy(&composition_unit);
- }
- void NSVAACDecoder::Initialize(CAccessUnitPtr _access_unit)
- {
- access_unit = _access_unit;
- }
- void NSVAACDecoder::flush()
- {
- if (decoder)
- mp4AudioDecoder_Reset(decoder, MP4AUDIODECPARAM_DEFAULT, 0);
- }
- static void ConfigureADTS(CSAudioSpecificConfig* asc, nsaac_adts_header_t header)
- {
- asc->m_aot = (AUDIO_OBJECT_TYPE)(header->profile + 1);
- asc->m_channelConfiguration = header->channel_configuration;
- asc->m_channels = nsaac_adts_get_channel_count(header);
- asc->m_nrOfStreams = 1;
- asc->m_samplesPerFrame = 1024;
- asc->m_samplingFrequencyIndex = header->sample_rate_index;
- asc->m_samplingFrequency = nsaac_adts_get_samplerate(header);
- asc->m_avgBitRate = 0; /* only needed for tvq */
- asc->m_mpsPresentFlag = -1;
- asc->m_saocPresentFlag = -1;
- asc->m_ldmpsPresentFlag = -1;
- }
- // returns -1 on error, 0 on success (done with data in 'in'), 1 on success
- // but to pass 'in' again next time around.
- int NSVAACDecoder::decode(void *in, int in_len, void *out, int *out_len, unsigned int out_fmt[8])
- {
- if (out_left)
- {
- unsigned int channels;
- unsigned int sample_rate;
- if (CCompositionUnit_GetChannels(composition_unit, &channels) != MP4AUDIODEC_OK
- || CCompositionUnit_GetSamplingRate(composition_unit, &sample_rate) != MP4AUDIODEC_OK)
- return -1;
- out_fmt[0] = NSV_MAKETYPE('P', 'C', 'M', ' ');
- out_fmt[1] = sample_rate;
- out_fmt[2] = channels;
- out_fmt[3] = 16;
- const uint8_t *audio_output=0;
- CCompositionUnit_GetPcmPtr(composition_unit, &audio_output);
- size_t copy_size = min(out_left, *out_len);
- memcpy(out, audio_output + source_position, copy_size);
- *out_len = copy_size;
- out_left -= copy_size;
- source_position += copy_size;
- return 1;
- ;
- }
- in = (uint8_t *)in + in_position;
- in_len -= in_position;
- if (in_len > 7)
- {
- ADTSHeader header;
- if (nsaac_adts_parse(&header, (const uint8_t *)in) == NErr_Success)
- {
- if (!decoder)
- {
- CSAudioSpecificConfig asc;
- memset(&asc, 0, sizeof(asc));
- ConfigureADTS(&asc, &header);
- CSAudioSpecificConfig *asc_array = &asc;
- decoder = mp4AudioDecoder_Create(&asc_array, 1);
- if (decoder)
- {
- mp4AudioDecoder_SetParam(decoder, TDL_MODE, SWITCH_ON);
- mp4AudioDecoder_SetParam(decoder, CONCEALMENT_ENERGYINTERPOLATION, SWITCH_OFF);
- composition_unit = CCompositionUnit_Create(max(asc.m_channels, 8), asc.m_samplesPerFrame * 2, asc.m_samplingFrequency, 6144, CUBUFFER_PCMTYPE_INT16);
- }
- if (!decoder || !composition_unit)
- {
- in_position=0;
- return -1;
- }
- }
- if (header.frame_length > in_len)
- {
- in_position=0;
- return -1;
- }
- if (header.frame_length != in_len)
- {
- in_position+=header.frame_length;
- }
- else
- {
- in_position=0;
- }
-
- CAccessUnit_Reset(access_unit);
- CAccessUnit_Assign(access_unit, (const uint8_t *)in + 7, header.frame_length-7);
- CCompositionUnit_Reset(composition_unit);
- MP4_RESULT result = mp4AudioDecoder_DecodeFrame(decoder, &access_unit, composition_unit);
- if (result == MP4AUDIODEC_OK)
- {
- unsigned int channels;
- unsigned int samples_per_channel;
- unsigned int sample_rate;
- if (CCompositionUnit_GetSamplesPerChannel(composition_unit, &samples_per_channel) != MP4AUDIODEC_OK
- || CCompositionUnit_GetChannels(composition_unit, &channels) != MP4AUDIODEC_OK
- || CCompositionUnit_GetSamplingRate(composition_unit, &sample_rate) != MP4AUDIODEC_OK)
- return -1;
- size_t num_samples = samples_per_channel * channels;
- size_t output_size = num_samples * 2 /* 16 bits */;
- const uint16_t *audio_output=0;
- CCompositionUnit_GetPcmPtr(composition_unit, &audio_output);
- size_t copy_size = min(output_size, *out_len);
- memcpy(out, audio_output, copy_size);
- *out_len = copy_size;
- out_left = output_size - copy_size;
- source_position = copy_size;
- out_fmt[0] = NSV_MAKETYPE('P', 'C', 'M', ' ');
- out_fmt[1] = sample_rate;
- out_fmt[2] = channels;
- out_fmt[3] = 16;
- int br;
- CCompositionUnit_GetProperty(composition_unit, CUBUFFER_AVGBITRATE, &br);
- out_fmt[4] =br/1000;
- if (in_position)
- return 1;
- return 0;
- }
- else
- {
- return -1;
- }
-
- }
- else
- {
- in_position=0;
- return -1;
- }
- }
- *out_len = 0;
- in_position=0;
- return 0;
- }
- IAudioDecoder *NSVDecoder::CreateAudioDecoder(FOURCC format, IAudioOutput **output)
- {
- switch (format)
- {
- case NSV_MAKETYPE('A', 'A', 'C', ' ') :
- case NSV_MAKETYPE('A', 'A', 'C', 'P'):
- case NSV_MAKETYPE('A', 'P', 'L', ' '):
- {
- NSVAACDecoder *dec = NSVAACDecoder::CreateDecoder();
- return dec;
- }
- default:
- return 0;
- }
- }
- #define CBCLASS NSVDecoder
- START_DISPATCH;
- CB(SVC_NSVFACTORY_CREATEAUDIODECODER, CreateAudioDecoder)
- END_DISPATCH;
- #undef CBCLASS
|