/*** * Init the audio codec module and return codec handle * \param phCodec [OUT] Return the video codec handle * \param vType [IN] The codec type if the module support multi codec. * \param pUserData [IN] The init param. It is memory operator or alloced memory * \retval VO_ERR_NONE Succeeded. */ VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA *pUserData) { AAC_ENCODER*hAacEnc; AACENC_CONFIG config; int error; #ifdef USE_DEAULT_MEM VO_MEM_OPERATOR voMemoprator; #endif VO_MEM_OPERATOR *pMemOP; int interMem; interMem = 0; error = 0; /** init the memory operator */ if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL ) { #ifdef USE_DEAULT_MEM voMemoprator.Alloc = cmnMemAlloc; voMemoprator.Copy = cmnMemCopy; voMemoprator.Free = cmnMemFree; voMemoprator.Set = cmnMemSet; voMemoprator.Check = cmnMemCheck; interMem = 1; pMemOP = &voMemoprator; #else *phCodec = NULL; return VO_ERR_INVALID_ARG; #endif } else { pMemOP = (VO_MEM_OPERATOR *)pUserData->memData; } /** init the aac encoder handle */ hAacEnc = (AAC_ENCODER*)mem_malloc(pMemOP, sizeof(AAC_ENCODER), 32, VO_INDEX_ENC_AAC); if(NULL == hAacEnc) { error = 1; } if(!error) { /** init the aac encoder intra memory */ hAacEnc->intbuf = (short *)mem_malloc(pMemOP, AACENC_BLOCKSIZE*MAX_CHANNELS*sizeof(short), 32, VO_INDEX_ENC_AAC); if(NULL == hAacEnc->intbuf) { error = 1; } } if (!error) { /** init the aac encoder psychoacoustic */ error = (PsyNew(&hAacEnc->psyKernel, MAX_CHANNELS, pMemOP) || PsyOutNew(&hAacEnc->psyOut, pMemOP)); } if (!error) { /** init the aac encoder quantization elements */ error = QCOutNew(&hAacEnc->qcOut,MAX_CHANNELS, pMemOP); } if (!error) { /** init the aac encoder quantization state */ error = QCNew(&hAacEnc->qcKernel, pMemOP); } /** uninit the aac encoder if error is nozero */ if(error) { AacEncClose(hAacEnc, pMemOP); if(hAacEnc) { mem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC); hAacEnc = NULL; } *phCodec = NULL; return VO_ERR_OUTOF_MEMORY; } /** init the aac encoder memory operator */ #ifdef USE_DEAULT_MEM if(interMem) { hAacEnc->voMemoprator.Alloc = cmnMemAlloc; hAacEnc->voMemoprator.Copy = cmnMemCopy; hAacEnc->voMemoprator.Free = cmnMemFree; hAacEnc->voMemoprator.Set = cmnMemSet; hAacEnc->voMemoprator.Check = cmnMemCheck; pMemOP = &hAacEnc->voMemoprator; } #endif /** init the aac encoder default parameter */ if(hAacEnc->initOK == 0) { AACENC_CONFIG config; config.adtsUsed = 1; config.bitRate = 128000; config.nChannelsIn = 2; config.nChannelsOut = 2; config.sampleRate = 44100; config.bandWidth = 20000; AacEncOpen(hAacEnc, config); } hAacEnc->voMemop = pMemOP; *phCodec = hAacEnc; return VO_ERR_NONE; }
int AacEncOpen ( struct AAC_ENCODER** phAacEnc, /* pointer to an encoder handle, initialized on return */ const AACENC_CONFIG config /* pre-initialized config struct */ ) { int error = 0; int profile = 1; ELEMENT_INFO* elInfo = NULL; struct AAC_ENCODER *hAacEnc ; COUNT_sub_start("AacEncOpen"); MOVE(2); /* counting previous operations */ PTR_INIT(1); hAacEnc = &aacEncoder; BRANCH(1); if (phAacEnc==0) { MOVE(1); error=1; } BRANCH(1); if (!error) { /* sanity checks on config structure */ PTR_INIT(1); ADD(7); LOGIC(9); DIV(1); error = (/* &config == 0 || */ phAacEnc == 0 || config.nChannelsIn < 1 || config.nChannelsIn > MAX_CHANNELS || config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut || (config.bitRate!=0 && (config.bitRate / config.nChannelsOut < 8000 || config.bitRate / config.nChannelsOut > 160000))); } /* check sample rate */ BRANCH(1); if (!error) { BRANCH(2); switch (config.sampleRate) { case 8000: case 11025: case 12000: case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: break; default: MOVE(1); error = 1; break; } } /* check if bit rate is not too high for sample rate */ BRANCH(1); if (!error) { MULT(2); ADD(1); BRANCH(1); if (config.bitRate > ((float)(MAX_CHANNEL_BITS-744)/FRAME_LEN_LONG* config.sampleRate*config.nChannelsOut)) { MOVE(1); error=1; } } BRANCH(1); if (!error) { INDIRECT(1); MOVE(1); hAacEnc->config = config; } BRANCH(1); if (!error) { INDIRECT(2); PTR_INIT(1); FUNC(2); error = InitElementInfo (config.nChannelsOut, &hAacEnc->elInfo); } BRANCH(1); if (!error) { INDIRECT(1); PTR_INIT(1); elInfo = &hAacEnc->elInfo; } /* allocate the Psy aud Psy Out structure */ BRANCH(1); if (!error) { INDIRECT(3); PTR_INIT(2); FUNC(2); FUNC(1); LOGIC(1); error = (PsyNew(&hAacEnc->psyKernel, elInfo->nChannelsInEl) || PsyOutNew(&hAacEnc->psyOut)); } BRANCH(1); if (!error) { int tnsMask=3; MOVE(1); /* counting previous operation */ INDIRECT(2); MOVE(1); hAacEnc->bandwidth90dB = (int)hAacEnc->config.bandWidth; INDIRECT(4); PTR_INIT(1); FUNC(6); error = psyMainInit(&hAacEnc->psyKernel, config.sampleRate, config.bitRate, elInfo->nChannelsInEl, tnsMask, hAacEnc->bandwidth90dB); } /* allocate the Q&C Out structure */ BRANCH(1); if (!error) { INDIRECT(2); PTR_INIT(1); FUNC(2); error = QCOutNew(&hAacEnc->qcOut, elInfo->nChannelsInEl); } /* allocate the Q&C kernel */ BRANCH(1); if (!error) { INDIRECT(1); PTR_INIT(1); FUNC(1); error = QCNew(&hAacEnc->qcKernel); } BRANCH(1); if (!error) { struct QC_INIT qcInit; INDIRECT(1); PTR_INIT(1); MOVE(1); qcInit.elInfo = &hAacEnc->elInfo; INDIRECT(1); MULT(1); STORE(1); qcInit.maxBits = MAX_CHANNEL_BITS * elInfo->nChannelsInEl; MOVE(1); qcInit.bitRes = qcInit.maxBits; MULT(1); DIV(1); STORE(1); qcInit.averageBits = (config.bitRate * FRAME_LEN_LONG) / config.sampleRate; MOVE(1); qcInit.padding.paddingRest = config.sampleRate; INDIRECT(1); MULT(2); DIV(1); qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config.sampleRate/2.0f); MULT(1); DIV(1); BRANCH(1); STORE(1); qcInit.maxBitFac = (float)((MAX_CHANNEL_BITS-744)*elInfo->nChannelsInEl) / (float)(qcInit.averageBits?qcInit.averageBits:1); MOVE(1); qcInit.bitrate = config.bitRate; INDIRECT(1); PTR_INIT(2); FUNC(2); error = QCInit(&hAacEnc->qcKernel, &qcInit); } /* init bitstream encoder */ BRANCH(1); if (!error) { INDIRECT(5); MOVE(4); hAacEnc->bseInit.nChannels = elInfo->nChannelsInEl; hAacEnc->bseInit.bitrate = config.bitRate; hAacEnc->bseInit.sampleRate = config.sampleRate; hAacEnc->bseInit.profile = profile; } /* common things */ BRANCH(1); if (!error) { INDIRECT(1); ADD(2); LOGIC(1); STORE(1); hAacEnc->downmix = (config.nChannelsIn==2 && config.nChannelsOut==1); INDIRECT(1); BRANCH(1); MOVE(1); hAacEnc->downmixFac = (hAacEnc->downmix) ? config.nChannelsIn : 1; } BRANCH(1); if(!error) { /* decide if stereo preprocessing should be activated */ ADD(3); DIV(1); MULT(1); LOGIC(2); BRANCH(1); if ( elInfo->elType == ID_CPE && (config.sampleRate <= 24000 && (config.bitRate/elInfo->nChannelsInEl*2) < 60000) ) { float scfUsedRatio = (float) hAacEnc->psyKernel.psyConfLong.sfbActive / hAacEnc->psyKernel.psyConfLong.sfbCnt ; DIV(1); /* counting previous operation */ FUNC(5); error = InitStereoPreProcessing(&(hAacEnc->stereoPrePro), elInfo->nChannelsInEl, config.bitRate, config.sampleRate, scfUsedRatio); } } BRANCH(1); if (error) { FUNC(1); AacEncClose(hAacEnc); MOVE(1); hAacEnc=0; } MOVE(1); *phAacEnc = hAacEnc; COUNT_sub_end(); return error; }