/*
 ** 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) */
                    VO_U32 *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;
	}
  }
}
