/*
 ** 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_core.c

	Content:	aac encoder core functions

*******************************************************************************/

#include "typedef.h"
#include "aacenc_core.h"
#include "bitenc.h"

#include "psy_configuration.h"
#include "psy_main.h"
#include "qc_main.h"
#include "psy_main.h"
#include "channel_map.h"
#include "aac_rom.h"

/********************************************************************************
*
* function name: AacInitDefaultConfig
* description:  gives reasonable default configuration
*
**********************************************************************************/
void AacInitDefaultConfig(AACENC_CONFIG *config)
{
  /* default configurations */
  config->adtsUsed        = 1;
  config->nChannelsIn     = 2;
  config->nChannelsOut    = 2;
  config->bitRate         = 128000;                      
  config->bandWidth       = 0;                           
}

/********************************************************************************
*
* function name: AacEncOpen
* description:  allocate and initialize a new encoder instance
* returns:      0 if success
*
**********************************************************************************/
Word16  AacEncOpen(  AAC_ENCODER*      hAacEnc,        /* pointer to an encoder handle, initialized on return */
                     const  AACENC_CONFIG     config   /* pre-initialized config struct */
                     )
{
  Word32 i;
  Word32 error = 0;
  Word16 profile = 1;

  ELEMENT_INFO *elInfo = NULL;
   
  if (hAacEnc==0) {
    error=1;                                  
  }
   
  if (!error) {
    hAacEnc->config = config;
  }

  if (!error) {
    error = InitElementInfo (config.nChannelsOut,
                             &hAacEnc->elInfo);
  }

  if (!error) {
    elInfo = &hAacEnc->elInfo;
  }

  if (!error) {
    /* use or not tns tool for long and short block */
	 Word16 tnsMask=3;      

	/* init encoder psychoacoustic */
    error = psyMainInit(&hAacEnc->psyKernel,
                        config.sampleRate,
                        config.bitRate,
                        elInfo->nChannelsInEl,
                        tnsMask,
                        hAacEnc->config.bandWidth);
  }

 /* use or not adts header */
  if(!error) {
	  hAacEnc->qcOut.qcElement.adtsUsed = config.adtsUsed;
  }

  /* init encoder quantization */
  if (!error) {
    struct QC_INIT qcInit;

    /*qcInit.channelMapping = &hAacEnc->channelMapping;*/
    qcInit.elInfo = &hAacEnc->elInfo;

    qcInit.maxBits = (Word16) (MAXBITS_COEF*elInfo->nChannelsInEl);
    qcInit.bitRes = qcInit.maxBits;                                      
    qcInit.averageBits = (Word16) ((config.bitRate * FRAME_LEN_LONG) / config.sampleRate);

    qcInit.padding.paddingRest = config.sampleRate;                          

    qcInit.meanPe = (Word16) ((10 * FRAME_LEN_LONG * hAacEnc->config.bandWidth) /
                                              (config.sampleRate>>1));

    qcInit.maxBitFac = (Word16) ((100 * (MAXBITS_COEF-MINBITS_COEF)* elInfo->nChannelsInEl)/
                                                 (qcInit.averageBits?qcInit.averageBits:1));

    qcInit.bitrate = config.bitRate;                                     

    error = QCInit(&hAacEnc->qcKernel, &qcInit);
  }

  /* init bitstream encoder */
  if (!error) {
    hAacEnc->bseInit.nChannels   = elInfo->nChannelsInEl;                
    hAacEnc->bseInit.bitrate     = config.bitRate;                       
    hAacEnc->bseInit.sampleRate  = config.sampleRate;                    
    hAacEnc->bseInit.profile     = profile;                              
  }

  return error;
}

/********************************************************************************
*
* function name: AacEncEncode
* description:  encode pcm to aac data core function
* returns:      0 if success
*
**********************************************************************************/
Word16 AacEncEncode(AAC_ENCODER *aacEnc,		/*!< an encoder handle */
                    Word16 *timeSignal,         /*!< BLOCKSIZE*nChannels audio samples, interleaved */
                    const UWord8 *ancBytes,     /*!< pointer to ancillary data bytes */
                    Word16 *numAncBytes,		/*!< number of ancillary Data Bytes */
                    UWord8 *outBytes,           /*!< pointer to output buffer (must be large MINBITS_COEF/8*MAX_CHANNELS bytes) */
                    Word32 *numOutBytes         /*!< number of bytes in output buffer after processing */
                    )
{
  ELEMENT_INFO *elInfo = &aacEnc->elInfo;
  Word16 globUsedBits;
  Word16 ancDataBytes, ancDataBytesLeft;
  
  ancDataBytes = ancDataBytesLeft = *numAncBytes;                          

  /* init output aac data buffer and length */
  aacEnc->hBitStream = CreateBitBuffer(&aacEnc->bitStream, outBytes, *numOutBytes);

  /* psychoacoustic process */
  psyMain(aacEnc->config.nChannelsOut,    
          elInfo,
          timeSignal,
          &aacEnc->psyKernel.psyData[elInfo->ChannelIndex[0]],
          &aacEnc->psyKernel.tnsData[elInfo->ChannelIndex[0]],
          &aacEnc->psyKernel.psyConfLong,
          &aacEnc->psyKernel.psyConfShort,
          &aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
          &aacEnc->psyOut.psyOutElement,
          aacEnc->psyKernel.pScratchTns,
		  aacEnc->config.sampleRate);

  /* adjust bitrate and frame length */
  AdjustBitrate(&aacEnc->qcKernel,
                aacEnc->config.bitRate,
                aacEnc->config.sampleRate);
    
  /* quantization and coding process */
  QCMain(&aacEnc->qcKernel,         
         &aacEnc->qcKernel.elementBits,
         &aacEnc->qcKernel.adjThr.adjThrStateElem,
         &aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
         &aacEnc->psyOut.psyOutElement,
         &aacEnc->qcOut.qcChannel[elInfo->ChannelIndex[0]],
         &aacEnc->qcOut.qcElement,
         elInfo->nChannelsInEl,
		 min(ancDataBytesLeft,ancDataBytes));

  ancDataBytesLeft = ancDataBytesLeft - ancDataBytes;

  globUsedBits = FinalizeBitConsumption(&aacEnc->qcKernel,
                         &aacEnc->qcOut);

  /* write bitstream process */
  WriteBitstream(aacEnc->hBitStream,				 
                 *elInfo,
                 &aacEnc->qcOut,
                 &aacEnc->psyOut,
                 &globUsedBits,				 
                 ancBytes,
				 aacEnc->psyKernel.sampleRateIdx);

  updateBitres(&aacEnc->qcKernel,
               &aacEnc->qcOut);

  /* write out the bitstream */
  *numOutBytes = GetBitsAvail(aacEnc->hBitStream) >> 3;

  return 0;
}


/********************************************************************************
*
* function name:AacEncClose
* description: deallocate an encoder instance
*
**********************************************************************************/
void AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP)
{
  if (hAacEnc) {  
    QCDelete(&hAacEnc->qcKernel, pMemOP);

    QCOutDelete(&hAacEnc->qcOut, pMemOP);

    PsyDelete(&hAacEnc->psyKernel, pMemOP);

    PsyOutDelete(&hAacEnc->psyOut, pMemOP);

    DeleteBitBuffer(&hAacEnc->hBitStream);

	if(hAacEnc->intbuf)
	{
		mem_free(pMemOP, hAacEnc->intbuf, VO_INDEX_ENC_AAC);
		hAacEnc->intbuf = NULL;
	}
  }
}
