Home | History | Annotate | Download | only in src
      1 /*
      2  ** Copyright 2003-2010, VisualOn, Inc.
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 /*******************************************************************************
     17 	File:		aacenc.c
     18 
     19 	Content:	aac encoder interface functions
     20 
     21 *******************************************************************************/
     22 
     23 #include "voAAC.h"
     24 #include "typedef.h"
     25 #include "aacenc_core.h"
     26 #include "aac_rom.h"
     27 #include "cmnMemory.h"
     28 #include "memalign.h"
     29 
     30 /**
     31 * Init the audio codec module and return codec handle
     32 * \param phCodec [OUT] Return the video codec handle
     33 * \param vType	[IN] The codec type if the module support multi codec.
     34 * \param pUserData	[IN] The init param. It is memory operator or alloced memory
     35 * \retval VO_ERR_NONE Succeeded.
     36 */
     37 VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA *pUserData)
     38 {
     39 	AAC_ENCODER*hAacEnc;
     40 	AACENC_CONFIG config;
     41 	int error;
     42 
     43 #ifdef USE_DEAULT_MEM
     44 	VO_MEM_OPERATOR voMemoprator;
     45 #endif
     46 	VO_MEM_OPERATOR *pMemOP;
     47 	int interMem;
     48 
     49 	interMem = 0;
     50 	error = 0;
     51 
     52 	/* init the memory operator */
     53 	if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
     54 	{
     55 #ifdef USE_DEAULT_MEM
     56 		voMemoprator.Alloc = cmnMemAlloc;
     57 		voMemoprator.Copy = cmnMemCopy;
     58 		voMemoprator.Free = cmnMemFree;
     59 		voMemoprator.Set = cmnMemSet;
     60 		voMemoprator.Check = cmnMemCheck;
     61 
     62 		interMem = 1;
     63 
     64 		pMemOP = &voMemoprator;
     65 #else
     66 		*phCodec = NULL;
     67 		return VO_ERR_INVALID_ARG;
     68 #endif
     69 	}
     70 	else
     71 	{
     72 		pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
     73 	}
     74 
     75 	/* init the aac encoder handle */
     76 	hAacEnc = (AAC_ENCODER*)mem_malloc(pMemOP, sizeof(AAC_ENCODER), 32, VO_INDEX_ENC_AAC);
     77 	if(NULL == hAacEnc)
     78 	{
     79 		error = 1;
     80 	}
     81 
     82 	if(!error)
     83 	{
     84 		/* init the aac encoder intra memory */
     85 		hAacEnc->intbuf = (short *)mem_malloc(pMemOP, AACENC_BLOCKSIZE*MAX_CHANNELS*sizeof(short), 32, VO_INDEX_ENC_AAC);
     86 		if(NULL == hAacEnc->intbuf)
     87 		{
     88 			error = 1;
     89 		}
     90 	}
     91 
     92 	if (!error) {
     93 		/* init the aac encoder psychoacoustic */
     94 		error = (PsyNew(&hAacEnc->psyKernel, MAX_CHANNELS, pMemOP) ||
     95 			PsyOutNew(&hAacEnc->psyOut, pMemOP));
     96 	}
     97 
     98 	if (!error) {
     99 		/* init the aac encoder quantization elements */
    100 		error = QCOutNew(&hAacEnc->qcOut,MAX_CHANNELS, pMemOP);
    101 	}
    102 
    103 	if (!error) {
    104 		/* init the aac encoder quantization state */
    105 		error = QCNew(&hAacEnc->qcKernel, pMemOP);
    106 	}
    107 
    108 	/* uninit the aac encoder if error is nozero */
    109 	if(error)
    110 	{
    111 		AacEncClose(hAacEnc, pMemOP);
    112 		if(hAacEnc)
    113 		{
    114 			mem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC);
    115 			hAacEnc = NULL;
    116 		}
    117 		*phCodec = NULL;
    118 		return VO_ERR_OUTOF_MEMORY;
    119 	}
    120 
    121 	/* init the aac encoder memory operator  */
    122 #ifdef USE_DEAULT_MEM
    123 	if(interMem)
    124 	{
    125 		hAacEnc->voMemoprator.Alloc = cmnMemAlloc;
    126 		hAacEnc->voMemoprator.Copy = cmnMemCopy;
    127 		hAacEnc->voMemoprator.Free = cmnMemFree;
    128 		hAacEnc->voMemoprator.Set = cmnMemSet;
    129 		hAacEnc->voMemoprator.Check = cmnMemCheck;
    130 
    131 		pMemOP = &hAacEnc->voMemoprator;
    132 	}
    133 #endif
    134 	/* init the aac encoder default parameter  */
    135 	if(hAacEnc->initOK == 0)
    136 	{
    137 		 AACENC_CONFIG config;
    138 		 config.adtsUsed = 1;
    139 		 config.bitRate = 128000;
    140 		 config.nChannelsIn = 2;
    141 		 config.nChannelsOut = 2;
    142 		 config.sampleRate = 44100;
    143 		 config.bandWidth = 20000;
    144 
    145 		 AacEncOpen(hAacEnc, config);
    146 	}
    147 
    148 	hAacEnc->voMemop = pMemOP;
    149 
    150 	*phCodec = hAacEnc;
    151 
    152 	return VO_ERR_NONE;
    153 }
    154 
    155 /**
    156 * Set input audio data.
    157 * \param hCodec [IN]] The Codec Handle which was created by Init function.
    158 * \param pInput [IN] The input buffer param.
    159 * \param pOutBuffer [OUT] The output buffer info.
    160 * \retval VO_ERR_NONE Succeeded.
    161 */
    162 VO_U32 VO_API voAACEncSetInputData(VO_HANDLE hCodec, VO_CODECBUFFER * pInput)
    163 {
    164 	AAC_ENCODER *hAacEnc;
    165 	int  length;
    166 
    167 	if(NULL == hCodec || NULL == pInput || NULL == pInput->Buffer)
    168 	{
    169 		return VO_ERR_INVALID_ARG;
    170 	}
    171 
    172 	hAacEnc = (AAC_ENCODER *)hCodec;
    173 
    174 	/* init input pcm buffer and length*/
    175 	hAacEnc->inbuf = (short *)pInput->Buffer;
    176 	hAacEnc->inlen = pInput->Length / sizeof(short);
    177 	hAacEnc->uselength = 0;
    178 
    179 	hAacEnc->encbuf = hAacEnc->inbuf;
    180 	hAacEnc->enclen = hAacEnc->inlen;
    181 
    182 	/* rebuild intra pcm buffer and length*/
    183 	if(hAacEnc->intlen)
    184 	{
    185 		length = min(hAacEnc->config.nChannelsIn*AACENC_BLOCKSIZE - hAacEnc->intlen, hAacEnc->inlen);
    186 		hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen,
    187 			hAacEnc->inbuf, length*sizeof(short));
    188 
    189 		hAacEnc->encbuf = hAacEnc->intbuf;
    190 		hAacEnc->enclen = hAacEnc->intlen + length;
    191 
    192 		hAacEnc->inbuf += length;
    193 		hAacEnc->inlen -= length;
    194 	}
    195 
    196 	return VO_ERR_NONE;
    197 }
    198 
    199 /**
    200 * Get the outut audio data
    201 * \param hCodec [IN]] The Codec Handle which was created by Init function.
    202 * \param pOutBuffer [OUT] The output audio data
    203 * \param pOutInfo [OUT] The dec module filled audio format and used the input size.
    204 *						 pOutInfo->InputUsed is total used the input size.
    205 * \retval  VO_ERR_NONE Succeeded.
    206 *			VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought.
    207 */
    208 VO_U32 VO_API voAACEncGetOutputData(VO_HANDLE hCodec, VO_CODECBUFFER * pOutput, VO_AUDIO_OUTPUTINFO * pOutInfo)
    209 {
    210 	AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
    211 	Word16 numAncDataBytes=0;
    212 	Word32  inbuflen;
    213 	int ret, length;
    214 	if(NULL == hAacEnc)
    215 		return VO_ERR_INVALID_ARG;
    216 
    217 	 inbuflen = AACENC_BLOCKSIZE*hAacEnc->config.nChannelsIn;
    218 
    219 	 /* check the input pcm buffer and length*/
    220 	 if(NULL == hAacEnc->encbuf || hAacEnc->enclen < inbuflen)
    221 	 {
    222 		length = hAacEnc->enclen;
    223 		if(hAacEnc->intlen == 0)
    224 		{
    225 			hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf,
    226 				hAacEnc->encbuf, length*sizeof(short));
    227 			hAacEnc->uselength += length*sizeof(short);
    228 		}
    229 		else
    230 		{
    231 			hAacEnc->uselength += (length - hAacEnc->intlen)*sizeof(short);
    232 		}
    233 
    234 		hAacEnc->intlen = length;
    235 
    236 		pOutput->Length = 0;
    237 		if(pOutInfo)
    238 			pOutInfo->InputUsed = hAacEnc->uselength;
    239 		return VO_ERR_INPUT_BUFFER_SMALL;
    240 	 }
    241 
    242 	 /* check the output aac buffer and length*/
    243 	 if(NULL == pOutput || NULL == pOutput->Buffer || pOutput->Length < (6144/8)*hAacEnc->config.nChannelsOut/(sizeof(Word32)))
    244 		 return VO_ERR_OUTPUT_BUFFER_SMALL;
    245 
    246 	 /* aac encoder core function */
    247 	 AacEncEncode( hAacEnc,
    248 			(Word16*)hAacEnc->encbuf,
    249 			NULL,
    250 			&numAncDataBytes,
    251 			pOutput->Buffer,
    252 			&pOutput->Length);
    253 
    254 	 /* update the input pcm buffer and length*/
    255 	 if(hAacEnc->intlen)
    256 	 {
    257 		length = inbuflen - hAacEnc->intlen;
    258 		hAacEnc->encbuf = hAacEnc->inbuf;
    259 		hAacEnc->enclen = hAacEnc->inlen;
    260 		hAacEnc->uselength += length*sizeof(short);
    261 		hAacEnc->intlen = 0;
    262 	 }
    263 	 else
    264 	 {
    265 		 hAacEnc->encbuf = hAacEnc->encbuf + inbuflen;
    266 		 hAacEnc->enclen = hAacEnc->enclen - inbuflen;
    267 		 hAacEnc->uselength += inbuflen*sizeof(short);
    268 	 }
    269 
    270 	 /* update the output aac information */
    271 	if(pOutInfo)
    272 	{
    273 		pOutInfo->Format.Channels = hAacEnc->config.nChannelsOut;
    274 		pOutInfo->Format.SampleRate = hAacEnc->config.sampleRate;
    275 		pOutInfo->Format.SampleBits = 16;
    276 		pOutInfo->InputUsed = hAacEnc->uselength;
    277 	}
    278 
    279 	 return VO_ERR_NONE;
    280 }
    281 
    282 /**
    283 * Uninit the Codec.
    284 * \param hCodec [IN]] The Codec Handle which was created by Init function.
    285 * \retval VO_ERR_NONE Succeeded.
    286 */
    287 VO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec)
    288 {
    289 	AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
    290 
    291 	if(NULL != hAacEnc)
    292 	{
    293 		/* close the aac encoder */
    294 		AacEncClose(hAacEnc, hAacEnc->voMemop);
    295 
    296 		/* free the aac encoder handle*/
    297 		mem_free(hAacEnc->voMemop, hAacEnc, VO_INDEX_ENC_AAC);
    298 		hAacEnc = NULL;
    299 	}
    300 
    301 	return VO_ERR_NONE;
    302 }
    303 
    304 /**
    305 * Set the param for special target.
    306 * \param hCodec [IN]] The Codec Handle which was created by Init function.
    307 * \param uParamID [IN] The param ID.
    308 * \param pData [IN] The param value depend on the ID>
    309 * \retval VO_ERR_NONE Succeeded.
    310 */
    311 VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
    312 {
    313 	AACENC_CONFIG config;
    314 	AACENC_PARAM* pAAC_param;
    315 	VO_AUDIO_FORMAT *pWAV_Format;
    316 	AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
    317 	int ret, i, bitrate, tmp;
    318 	int SampleRateIdx;
    319 
    320 	if(NULL == hAacEnc)
    321 		return VO_ERR_INVALID_ARG;
    322 
    323 	switch(uParamID)
    324 	{
    325 	case VO_PID_AAC_ENCPARAM:  /* init aac encoder parameter*/
    326 		AacInitDefaultConfig(&config);
    327 		if(pData == NULL)
    328 			return VO_ERR_INVALID_ARG;
    329 		pAAC_param = (AACENC_PARAM*)pData;
    330 		config.adtsUsed = pAAC_param->adtsUsed;
    331 		config.bitRate = pAAC_param->bitRate;
    332 		config.nChannelsIn = pAAC_param->nChannels;
    333 		config.nChannelsOut = pAAC_param->nChannels;
    334 		config.sampleRate = pAAC_param->sampleRate;
    335 
    336 		/* check the channel */
    337 		if(config.nChannelsIn< 1  || config.nChannelsIn > MAX_CHANNELS  ||
    338              config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
    339 			 return VO_ERR_AUDIO_UNSCHANNEL;
    340 
    341 		/* check the samplerate */
    342 		ret = -1;
    343 		for(i = 0; i < NUM_SAMPLE_RATES; i++)
    344 		{
    345 			if(config.sampleRate == sampRateTab[i])
    346 			{
    347 				ret = 0;
    348 				break;
    349 			}
    350 		}
    351 		if(ret < 0)
    352 			return VO_ERR_AUDIO_UNSSAMPLERATE;
    353 
    354 		SampleRateIdx = i;
    355 
    356 		tmp = 441;
    357 		if(config.sampleRate%8000 == 0)
    358 			tmp =480;
    359 		/* check the bitrate */
    360 		if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) ||
    361            (config.bitRate/config.nChannelsOut > 160000) ||
    362 		   (config.bitRate > config.sampleRate*6*config.nChannelsOut))
    363 		{
    364 			config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
    365 
    366 			if(config.bitRate/config.nChannelsOut < 4000)
    367 				config.bitRate = 4000 * config.nChannelsOut;
    368 			else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
    369 				config.bitRate = config.sampleRate*6*config.nChannelsOut;
    370 			else if(config.bitRate/config.nChannelsOut > 160000)
    371 				config.bitRate = config.nChannelsOut*160000;
    372 		}
    373 
    374 		/* check the bandwidth */
    375 		bitrate = config.bitRate / config.nChannelsOut;
    376 		bitrate = bitrate * tmp / config.sampleRate;
    377 
    378 		for (i = 0; rates[i]; i++)
    379 		{
    380 			if (rates[i] >= bitrate)
    381 				break;
    382 		}
    383 
    384 		config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
    385 
    386 		/* init aac encoder core */
    387 		ret = AacEncOpen(hAacEnc, config);
    388 		if(ret)
    389 			return VO_ERR_AUDIO_UNSFEATURE;
    390 		break;
    391 	case VO_PID_AUDIO_FORMAT:	/* init pcm channel and samplerate*/
    392 		AacInitDefaultConfig(&config);
    393 		if(pData == NULL)
    394 			return VO_ERR_INVALID_ARG;
    395 		pWAV_Format = (VO_AUDIO_FORMAT*)pData;
    396 		config.adtsUsed = 1;
    397 		config.nChannelsIn = pWAV_Format->Channels;
    398 		config.nChannelsOut = pWAV_Format->Channels;
    399 		config.sampleRate = pWAV_Format->SampleRate;
    400 
    401 		/* check the channel */
    402 		if(config.nChannelsIn< 1  || config.nChannelsIn > MAX_CHANNELS  ||
    403              config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
    404 			 return VO_ERR_AUDIO_UNSCHANNEL;
    405 
    406 		/* check the samplebits */
    407 		if(pWAV_Format->SampleBits != 16)
    408 		{
    409 			return VO_ERR_AUDIO_UNSFEATURE;
    410 		}
    411 
    412 		/* check the samplerate */
    413 		ret = -1;
    414 		for(i = 0; i < NUM_SAMPLE_RATES; i++)
    415 		{
    416 			if(config.sampleRate == sampRateTab[i])
    417 			{
    418 				ret = 0;
    419 				break;
    420 			}
    421 		}
    422 		if(ret < 0)
    423 			return VO_ERR_AUDIO_UNSSAMPLERATE;
    424 
    425 		SampleRateIdx = i;
    426 
    427 		/* update the bitrates */
    428 		tmp = 441;
    429 		if(config.sampleRate%8000 == 0)
    430 			tmp =480;
    431 
    432 		config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
    433 
    434 		if(config.bitRate/config.nChannelsOut < 4000)
    435 			config.bitRate = 4000 * config.nChannelsOut;
    436 		else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
    437 			config.bitRate = config.sampleRate*6*config.nChannelsOut;
    438 		else if(config.bitRate/config.nChannelsOut > 160000)
    439 			config.bitRate = config.nChannelsOut*160000;
    440 
    441 		/* check the bandwidth */
    442 		bitrate = config.bitRate / config.nChannelsOut;
    443 		bitrate = bitrate * tmp / config.sampleRate;
    444 
    445 		for (i = 0; rates[i]; i++)
    446 		{
    447 			if (rates[i] >= bitrate)
    448 				break;
    449 		}
    450 
    451 		config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
    452 
    453 		/* init aac encoder core */
    454 		ret = AacEncOpen(hAacEnc, config);
    455 		if(ret)
    456 			return VO_ERR_AUDIO_UNSFEATURE;
    457 		break;
    458 	default:
    459 		return VO_ERR_WRONG_PARAM_ID;
    460 	}
    461 
    462 	return VO_ERR_NONE;
    463 }
    464 
    465 /**
    466 * Get the param for special target.
    467 * \param hCodec [IN]] The Codec Handle which was created by Init function.
    468 * \param uParamID [IN] The param ID.
    469 * \param pData [IN] The param value depend on the ID>
    470 * \retval VO_ERR_NONE Succeeded.
    471 */
    472 VO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
    473 {
    474 	return VO_ERR_NONE;
    475 }
    476 
    477 /**
    478  * Get audio codec API interface
    479  * \param pEncHandle [out] Return the AAC Encoder handle.
    480  * \retval VO_ERR_OK Succeeded.
    481  */
    482 VO_S32 VO_API voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)
    483 {
    484 	if(pDecHandle == NULL)
    485 		return VO_ERR_INVALID_ARG;
    486 
    487 	pDecHandle->Init = voAACEncInit;
    488 	pDecHandle->SetInputData = voAACEncSetInputData;
    489 	pDecHandle->GetOutputData = voAACEncGetOutputData;
    490 	pDecHandle->SetParam = voAACEncSetParam;
    491 	pDecHandle->GetParam = voAACEncGetParam;
    492 	pDecHandle->Uninit = voAACEncUninit;
    493 
    494 	return VO_ERR_NONE;
    495 }