/***
* 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;
}
Beispiel #2
0
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;
}