HX_RESULT HXAudioConfiguratorAAC::ExtractDecoderInfo(UINT32 cfgType, const void* config, UINT32 nBytes, CAudioSpecificConfig* pASConfig) { HX_RESULT result = HXR_OK; struct BITSTREAM *pBitStream = NULL; if(cfgType != eAACConfigAudioSpecificCfg) { result = HXR_INVALID_PARAMETER; } if(SUCCEEDED(result)) { // allocate bit stream if(newBitstream(&pBitStream, 8*nBytes)) { result = HXR_OUTOFMEMORY; } } if(SUCCEEDED(result)) { // decode bit stream into configuration structure feedBitstream(pBitStream, (unsigned char*)config, 8*nBytes) ; setAtBitstream(pBitStream, 0, 1); result = pASConfig->Read(*pBitStream); } if(pBitStream) { // deallocate bit stream deleteBitstream(pBitStream); } return result; }
/* * aac_decode_init */ HX_RESULT aac_decode_init(void* pInitParams, UINT32 ulInitParamsSize, ra_format_info* pStreamInfo, void** pDecode, void* pUserMem, rm_malloc_func_ptr fpMalloc, rm_free_func_ptr fpFree) { HX_RESULT result = HXR_OK; aac_decode* pDec; AACFrameInfo *frameInfo; ga_config_data configData; UCHAR *pData; UCHAR *inBuf; INT16 *temp; UINT32 numBytes, numBits; UINT32 cfgType; /* for MP4 bitstream parsing */ struct BITSTREAM *pBs = 0; /* allocate the aac_decode struct */ pDec = (aac_decode*) fpMalloc(pUserMem, sizeof(aac_decode)); if (pDec == HXNULL) { return HXR_OUTOFMEMORY; } memset(pDec, 0, sizeof(aac_decode)); *pDecode = (void *)pDec; /* allocate the frame info struct */ pDec->pFrameInfo = fpMalloc(pUserMem, sizeof(AACFrameInfo)); frameInfo = (AACFrameInfo *) pDec->pFrameInfo; /* allocate the decoder backend instance */ pDec->pDecoder = AACInitDecoder(1); if (pDec->pFrameInfo == HXNULL || pDec->pDecoder == HXNULL) { return HXR_OUTOFMEMORY; } /* save the stream info and init data we'll need later */ pDec->ulNumChannels = (UINT32)pStreamInfo->usNumChannels; pDec->ulBlockSize = pStreamInfo->ulGranularity; pDec->ulFrameSize = pStreamInfo->ulBitsPerFrame; pDec->ulFramesPerBlock = pDec->ulBlockSize / pDec->ulFrameSize; /* output frame size is doubled for safety in case of implicit SBR */ pDec->ulSamplesPerFrame = 1024*pStreamInfo->usNumChannels*2; pDec->ulSampleRateCore = pStreamInfo->ulSampleRate; pDec->ulSampleRateOut = pStreamInfo->ulActualRate; if (pStreamInfo->ulOpaqueDataSize < 1) { return HXR_FAIL; /* insufficient config data */ } /* get the config data */ pData = (UCHAR *)pStreamInfo->pOpaqueData; cfgType = pData[0]; inBuf = pData + 1; numBytes = pStreamInfo->ulOpaqueDataSize - 1; if (cfgType == 1) /* ADTS Frame */ { /* allocate temp buffer for decoding first ADTS frame */ temp = (INT16 *)fpMalloc(pUserMem, sizeof(INT16) * pDec->ulSamplesPerFrame); if (temp == HXNULL) { return HXR_OUTOFMEMORY; } else { /* decode ADTS frame from opaque data to get config data */ result = AACDecode(pDec->pDecoder, &inBuf, (INT32*)&numBytes, temp); /* free the temp buffer */ fpFree(pUserMem, temp); } if (result == HXR_OK) { /* get the config data struct from the decoder */ AACGetLastFrameInfo(pDec->pDecoder, frameInfo); pDec->ulNumChannels = frameInfo->nChans; pDec->ulSamplesPerFrame = frameInfo->outputSamps; pDec->ulSampleRateCore = frameInfo->sampRateCore; pDec->ulSampleRateOut = frameInfo->sampRateOut; pDec->bSBR = (pDec->ulSampleRateCore != pDec->ulSampleRateOut); } } else if (cfgType == 2) /* MP4 Audio Specific Config Data */ { numBits = numBytes*8; if (newBitstream(&pBs, numBits, pUserMem, fpMalloc)) { return HXR_FAIL; } feedBitstream(pBs, (const UCHAR *)inBuf, numBits); setAtBitstream(pBs, 0, 1); result = ga_config_get_data(pBs, &configData); deleteBitstream(pBs, pUserMem, fpFree); if (result != HXR_OK) /* config data error */ { return HXR_FAIL; } pDec->ulNumChannels = configData.numChannels; pDec->ulSampleRateCore = configData.samplingFrequency; pDec->ulSampleRateOut = configData.extensionSamplingFrequency; pDec->bSBR = configData.bSBR; /* ulSamplesPerFrame is set to the maximum possible output length. * The config data has the initial output length, which might * be doubled once the first frame is handed in (if AAC+ is * signalled implicitly). */ pDec->ulSamplesPerFrame = 2*configData.frameLength*configData.numChannels; /* setup decoder to handle raw data blocks */ frameInfo->nChans = pDec->ulNumChannels; frameInfo->sampRateCore = pDec->ulSampleRateCore; /* see MPEG4 spec for index of each object type */ if (configData.audioObjectType == 2) frameInfo->profile = AAC_PROFILE_LC; else if (configData.audioObjectType == 1) frameInfo->profile = AAC_PROFILE_MP; else if (configData.audioObjectType == 3) frameInfo->profile = AAC_PROFILE_SSR; else frameInfo->profile = AAC_PROFILE_LC; /* don't know - assume LC */ frameInfo->audio_send_by_frame=0; } else /* unsupported config type */ { return HXR_FAIL; } /* make certain that all the channels can be handled */ if (pDec->ulNumChannels > AAC_MAX_NCHANS) { return HXR_UNSUPPORTED_AUDIO; } /* set the channel mask - custom maps not supported */ switch (pDec->ulNumChannels) { case 1: pDec->ulChannelMask = 0x00004; /* FC */ case 2: pDec->ulChannelMask = 0x00003; /* FL,FR */ case 3: pDec->ulChannelMask = 0x00007; /* FL,FR,FC */ case 4: pDec->ulChannelMask = 0x00107; /* FL,FR,FC,BC */ case 5: pDec->ulChannelMask = 0x00037; /* FL,FR,FC,BL,BR */ case 6: pDec->ulChannelMask = 0x0003F; /* FL,FR,FC,LF,BL,BR */ default: pDec->ulChannelMask = 0xFFFFF; /* Unknown */ } /* set the delay samples */ pDec->ulDelayRemaining = pDec->ulSamplesPerFrame; /* set decoder to handle raw data blocks */ AACSetRawBlockParams(pDec->pDecoder, 0, frameInfo); return HXR_OK; }