/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
/*******************************************************************************
	File:		aacenc.c

	Content:	aac encoder interface functions

*******************************************************************************/

#include "voAAC.h"
#include "typedef.h"
#include "aacenc_core.h"
#include "aac_rom.h"
#include "cmnMemory.h"
#include "memalign.h"

/**
* 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;
}

/**
* Set input audio data.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param pInput [IN] The input buffer param.
* \param pOutBuffer [OUT] The output buffer info.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncSetInputData(VO_HANDLE hCodec, VO_CODECBUFFER * pInput)
{
	AAC_ENCODER *hAacEnc;
	int  length;

	if(NULL == hCodec || NULL == pInput || NULL == pInput->Buffer)
	{
		return VO_ERR_INVALID_ARG;
	}
	
	hAacEnc = (AAC_ENCODER *)hCodec;
	
	/* init input pcm buffer and length*/
	hAacEnc->inbuf = (short *)pInput->Buffer;
	hAacEnc->inlen = pInput->Length / sizeof(short);
	hAacEnc->uselength = 0;

	hAacEnc->encbuf = hAacEnc->inbuf;
	hAacEnc->enclen = hAacEnc->inlen;
	
	/* rebuild intra pcm buffer and length*/
	if(hAacEnc->intlen)
	{
		length = min(hAacEnc->config.nChannelsIn*AACENC_BLOCKSIZE - hAacEnc->intlen, hAacEnc->inlen);
		hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen, 
			hAacEnc->inbuf, length*sizeof(short));

		hAacEnc->encbuf = hAacEnc->intbuf;
		hAacEnc->enclen = hAacEnc->intlen + length;

		hAacEnc->inbuf += length;
		hAacEnc->inlen -= length;
	}
	
	return VO_ERR_NONE;
}

/**
* Get the outut audio data
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param pOutBuffer [OUT] The output audio data
* \param pOutInfo [OUT] The dec module filled audio format and used the input size.
*						 pOutInfo->InputUsed is total used the input size.
* \retval  VO_ERR_NONE Succeeded.
*			VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought.
*/
VO_U32 VO_API voAACEncGetOutputData(VO_HANDLE hCodec, VO_CODECBUFFER * pOutput, VO_AUDIO_OUTPUTINFO * pOutInfo)
{
	AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
	Word16 numAncDataBytes=0;
	Word32  inbuflen;
	int ret, length;
	if(NULL == hAacEnc)
		return VO_ERR_INVALID_ARG;

	 inbuflen = AACENC_BLOCKSIZE*hAacEnc->config.nChannelsIn;

	 /* check the input pcm buffer and length*/
	 if(NULL == hAacEnc->encbuf || hAacEnc->enclen < inbuflen)
	 {
		length = hAacEnc->enclen;		
		if(hAacEnc->intlen == 0)
		{	
			hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf, 
				hAacEnc->encbuf, length*sizeof(short));		
			hAacEnc->uselength += length*sizeof(short);
		}
		else
		{
			hAacEnc->uselength += (length - hAacEnc->intlen)*sizeof(short);
		}

		hAacEnc->intlen = length;

		pOutput->Length = 0;
		if(pOutInfo)
			pOutInfo->InputUsed = hAacEnc->uselength;
		return VO_ERR_INPUT_BUFFER_SMALL;	
	 }

	 /* check the output aac buffer and length*/
	 if(NULL == pOutput || NULL == pOutput->Buffer || pOutput->Length < (6144/8)*hAacEnc->config.nChannelsOut/(sizeof(Word32)))
		 return VO_ERR_OUTPUT_BUFFER_SMALL;

	 /* aac encoder core function */
	 AacEncEncode( hAacEnc,
			(Word16*)hAacEnc->encbuf,
			NULL,
			&numAncDataBytes,
			pOutput->Buffer,
			&pOutput->Length);

	 /* update the input pcm buffer and length*/
	 if(hAacEnc->intlen)
	 {
		length = inbuflen - hAacEnc->intlen;		
		hAacEnc->encbuf = hAacEnc->inbuf;
		hAacEnc->enclen = hAacEnc->inlen;
		hAacEnc->uselength += length*sizeof(short);
		hAacEnc->intlen = 0;
	 }
	 else
	 {
		 hAacEnc->encbuf = hAacEnc->encbuf + inbuflen;
		 hAacEnc->enclen = hAacEnc->enclen - inbuflen;
		 hAacEnc->uselength += inbuflen*sizeof(short);
	 }	 

	 /* update the output aac information */
	if(pOutInfo)
	{
		pOutInfo->Format.Channels = hAacEnc->config.nChannelsOut;
		pOutInfo->Format.SampleRate = hAacEnc->config.sampleRate;
		pOutInfo->Format.SampleBits = 16;
		pOutInfo->InputUsed = hAacEnc->uselength;
	}

	 return VO_ERR_NONE;
}

/**
* Uninit the Codec.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec)
{
	AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
	
	if(NULL != hAacEnc)
	{
		/* close the aac encoder */
		AacEncClose(hAacEnc, hAacEnc->voMemop);

		/* free the aac encoder handle*/
		mem_free(hAacEnc->voMemop, hAacEnc, VO_INDEX_ENC_AAC);
		hAacEnc = NULL;
	}	

	return VO_ERR_NONE;
}

/**
* Set the param for special target.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param uParamID [IN] The param ID.
* \param pData [IN] The param value depend on the ID>
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
{
	AACENC_CONFIG config;
	AACENC_PARAM* pAAC_param;
	VO_AUDIO_FORMAT *pWAV_Format;
	AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
	int ret, i, bitrate, tmp;
	int SampleRateIdx;

	if(NULL == hAacEnc)
		return VO_ERR_INVALID_ARG;
	
	switch(uParamID)
	{
	case VO_PID_AAC_ENCPARAM:  /* init aac encoder parameter*/
		AacInitDefaultConfig(&config);
		if(pData == NULL)
			return VO_ERR_INVALID_ARG;
		pAAC_param = (AACENC_PARAM*)pData;
		config.adtsUsed = pAAC_param->adtsUsed;
		config.bitRate = pAAC_param->bitRate;
		config.nChannelsIn = pAAC_param->nChannels;
		config.nChannelsOut = pAAC_param->nChannels;
		config.sampleRate = pAAC_param->sampleRate;

		/* check the channel */
		if(config.nChannelsIn< 1  || config.nChannelsIn > MAX_CHANNELS  ||
             config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
			 return VO_ERR_AUDIO_UNSCHANNEL;

		/* check the samplerate */
		ret = -1;
		for(i = 0; i < NUM_SAMPLE_RATES; i++)
		{
			if(config.sampleRate == sampRateTab[i])
			{
				ret = 0;
				break;
			}
		}
		if(ret < 0)
			return VO_ERR_AUDIO_UNSSAMPLERATE;

		SampleRateIdx = i;

		tmp = 441;
		if(config.sampleRate%8000 == 0) 
			tmp =480;
		/* check the bitrate */
		if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) ||
           (config.bitRate/config.nChannelsOut > 160000) || 
		   (config.bitRate > config.sampleRate*6*config.nChannelsOut))
		{
			config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;

			if(config.bitRate/config.nChannelsOut < 4000)
				config.bitRate = 4000 * config.nChannelsOut;
			else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
				config.bitRate = config.sampleRate*6*config.nChannelsOut;
			else if(config.bitRate/config.nChannelsOut > 160000)
				config.bitRate = config.nChannelsOut*160000;
		}

		/* check the bandwidth */
		bitrate = config.bitRate / config.nChannelsOut;
		bitrate = bitrate * tmp / config.sampleRate;

		for (i = 0; rates[i]; i++)
		{
			if (rates[i] >= bitrate)
				break;
		}

		config.bandWidth = BandwithCoefTab[i][SampleRateIdx];

		/* init aac encoder core */
		ret = AacEncOpen(hAacEnc, config);
		if(ret) 
			return VO_ERR_AUDIO_UNSFEATURE;
		break;
	case VO_PID_AUDIO_FORMAT:	/* init pcm channel and samplerate*/
		AacInitDefaultConfig(&config);
		if(pData == NULL)
			return VO_ERR_INVALID_ARG;
		pWAV_Format = (VO_AUDIO_FORMAT*)pData;
		config.adtsUsed = 1;
		config.nChannelsIn = pWAV_Format->Channels;
		config.nChannelsOut = pWAV_Format->Channels;
		config.sampleRate = pWAV_Format->SampleRate;

		/* check the channel */
		if(config.nChannelsIn< 1  || config.nChannelsIn > MAX_CHANNELS  ||
             config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
			 return VO_ERR_AUDIO_UNSCHANNEL;

		/* check the samplebits */
		if(pWAV_Format->SampleBits != 16)
		{
			return VO_ERR_AUDIO_UNSFEATURE;
		}

		/* check the samplerate */
		ret = -1;
		for(i = 0; i < NUM_SAMPLE_RATES; i++)
		{
			if(config.sampleRate == sampRateTab[i])
			{
				ret = 0;
				break;
			}
		}
		if(ret < 0)
			return VO_ERR_AUDIO_UNSSAMPLERATE;

		SampleRateIdx = i;

		/* update the bitrates */
		tmp = 441;
		if(config.sampleRate%8000 == 0) 
			tmp =480;

		config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;

		if(config.bitRate/config.nChannelsOut < 4000)
			config.bitRate = 4000 * config.nChannelsOut;
		else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
			config.bitRate = config.sampleRate*6*config.nChannelsOut;
		else if(config.bitRate/config.nChannelsOut > 160000)
			config.bitRate = config.nChannelsOut*160000;

		/* check the bandwidth */
		bitrate = config.bitRate / config.nChannelsOut;
		bitrate = bitrate * tmp / config.sampleRate;

		for (i = 0; rates[i]; i++)
		{
			if (rates[i] >= bitrate)
				break;
		}

		config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
		
		/* init aac encoder core */
		ret = AacEncOpen(hAacEnc, config);
		if(ret) 
			return VO_ERR_AUDIO_UNSFEATURE;
		break;
	default:
		return VO_ERR_WRONG_PARAM_ID;
	}

	return VO_ERR_NONE;
}

/**
* Get the param for special target.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param uParamID [IN] The param ID.
* \param pData [IN] The param value depend on the ID>
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
{
	return VO_ERR_NONE;
}

/**
 * Get audio codec API interface
 * \param pEncHandle [out] Return the AAC Encoder handle.
 * \retval VO_ERR_OK Succeeded.
 */
VO_S32 VO_API voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)
{
	if(pDecHandle == NULL)
		return VO_ERR_INVALID_ARG;
		
	pDecHandle->Init = voAACEncInit;
	pDecHandle->SetInputData = voAACEncSetInputData;
	pDecHandle->GetOutputData = voAACEncGetOutputData;
	pDecHandle->SetParam = voAACEncSetParam;
	pDecHandle->GetParam = voAACEncGetParam;
	pDecHandle->Uninit = voAACEncUninit;

	return VO_ERR_NONE;
}