Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /**************************** MPEG-4 HE-AAC Encoder *************************
     85 
     86   Initial author:       M. Lohwasser
     87   contents/description: FDK HE-AAC Encoder interface library functions
     88 
     89 ****************************************************************************/
     90 
     91 #include "aacenc_lib.h"
     92 #include "FDK_audio.h"
     93 #include "aacenc.h"
     94 
     95 #include "aacEnc_ram.h"
     96 #include "FDK_core.h" /* FDK_tools versioning info */
     97 
     98 /* Encoder library info */
     99 #define AACENCODER_LIB_VL0 3
    100 #define AACENCODER_LIB_VL1 3
    101 #define AACENCODER_LIB_VL2 1
    102 #define AACENCODER_LIB_TITLE "AAC Encoder"
    103 #define AACENCODER_LIB_BUILD_DATE __DATE__
    104 #define AACENCODER_LIB_BUILD_TIME __TIME__
    105 
    106 
    107 #include "sbr_encoder.h"
    108 #include "../src/sbr_ram.h"
    109 #include "channel_map.h"
    110 
    111 #include "psy_const.h"
    112 #include "bitenc.h"
    113 
    114 #include "tpenc_lib.h"
    115 
    116 #include "metadata_main.h"
    117 
    118 #define SBL(fl)            (fl/8)                 /*!< Short block length (hardcoded to 8 short blocks per long block) */
    119 #define BSLA(fl)           (4*SBL(fl)+SBL(fl)/2)  /*!< AAC block switching look-ahead */
    120 #define DELAY_AAC(fl)      (fl+BSLA(fl))          /*!< MDCT + blockswitching */
    121 #define DELAY_AACELD(fl)   ( (fl) + ((fl)/2)  )   /*!< ELD FB delay */
    122 
    123 #define INPUTBUFFER_SIZE (1537+100+2048)
    124 
    125 ////////////////////////////////////////////////////////////////////////////////////
    126 /**
    127  * Flags to characterize encoder modules to be supported in present instance.
    128  */
    129 enum {
    130     ENC_MODE_FLAG_AAC  = 0x0001,
    131     ENC_MODE_FLAG_SBR  = 0x0002,
    132     ENC_MODE_FLAG_PS   = 0x0004,
    133     ENC_MODE_FLAG_SAC  = 0x0008,
    134     ENC_MODE_FLAG_META = 0x0010
    135 };
    136 
    137 ////////////////////////////////////////////////////////////////////////////////////
    138 typedef struct {
    139     AUDIO_OBJECT_TYPE userAOT;               /*!< Audio Object Type.             */
    140     UINT              userSamplerate;        /*!< Sampling frequency.            */
    141     UINT              nChannels;             /*!< will be set via channelMode.   */
    142     CHANNEL_MODE      userChannelMode;
    143     UINT              userBitrate;
    144     UINT              userBitrateMode;
    145     UINT              userBandwidth;
    146     UINT              userAfterburner;
    147     UINT              userFramelength;
    148     UINT              userAncDataRate;
    149 
    150     UCHAR             userTns;               /*!< Use TNS coding. */
    151     UCHAR             userPns;               /*!< Use PNS coding. */
    152     UCHAR             userIntensity;         /*!< Use Intensity coding. */
    153 
    154     TRANSPORT_TYPE    userTpType;            /*!< Transport type */
    155     UCHAR             userTpSignaling;       /*!< Extension AOT signaling mode. */
    156     UCHAR             userTpNsubFrames;      /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1). */
    157     UCHAR             userTpAmxv;            /*!< AudioMuxVersion to be used for LATM (default 0). */
    158     UCHAR             userTpProtection;
    159     UCHAR             userTpHeaderPeriod;    /*!< Parameter used to configure LATM/LOAS SMC rate. Moreover this parameters is
    160                                                   used to configure repetition rate of PCE in raw_data_block. */
    161 
    162     UCHAR             userErTools;           /*!< Use VCB11, HCR and/or RVLC ER tool. */
    163     UINT              userPceAdditions;      /*!< Configure additional bits in PCE. */
    164 
    165     UCHAR             userMetaDataMode;      /*!< Meta data library configuration. */
    166 
    167     UCHAR             userSbrEnabled;
    168 
    169 } USER_PARAM;
    170 
    171 ////////////////////////////////////////////////////////////////////////////////////
    172 
    173 /****************************************************************************
    174                            Structure Definitions
    175 ****************************************************************************/
    176 
    177 typedef struct  AACENC_CONFIG     *HANDLE_AACENC_CONFIG;
    178 
    179 
    180 struct AACENCODER
    181 {
    182     USER_PARAM               extParam;
    183     CODER_CONFIG             coderConfig;
    184 
    185     /* AAC */
    186     AACENC_CONFIG            aacConfig;
    187     HANDLE_AAC_ENC           hAacEnc;
    188 
    189     /* SBR */
    190     HANDLE_SBR_ENCODER       hEnvEnc;
    191 
    192     /* Meta Data */
    193     HANDLE_FDK_METADATA_ENCODER  hMetadataEnc;
    194     INT                          metaDataAllowed; /* Signal whether chosen configuration allows metadata. Necessary for delay
    195                                                      compensation. Metadata mode is a separate parameter. */
    196 
    197     /* Transport */
    198     HANDLE_TRANSPORTENC      hTpEnc;
    199 
    200     /* Output */
    201     UCHAR                   *outBuffer;         /* Internal bitstream buffer */
    202     INT                      outBufferInBytes;   /* Size of internal bitstream buffer*/
    203 
    204     /* Input */
    205     INT_PCM                 *inputBuffer;        /* Internal input buffer. Input source for AAC encoder */
    206     INT                      inputBufferOffset;  /* Where to write new input samples. */
    207 
    208     INT                      nSamplesToRead;    /* number of input samples neeeded for encoding one frame */
    209     INT                      nSamplesRead;      /* number of input samples already in input buffer */
    210     INT                      nZerosAppended;    /* appended zeros at end of file*/
    211     INT                      nDelay;            /* encoder delay */
    212 
    213     AACENC_EXT_PAYLOAD       extPayload [MAX_TOTAL_EXT_PAYLOADS];
    214     /* Extension payload */
    215     UCHAR                    extPayloadData [(1)][(6)][MAX_PAYLOAD_SIZE];
    216     UINT                     extPayloadSize [(1)][(6)]; /* payload sizes in bits */
    217 
    218     ULONG                    InitFlags;         /* internal status to treggier re-initialization */
    219 
    220 
    221    /* Memory allocation info. */
    222    INT                       nMaxAacElements;
    223    INT                       nMaxAacChannels;
    224    INT                       nMaxSbrElements;
    225    INT                       nMaxSbrChannels;
    226    UINT                      nMaxSubFrames;
    227 
    228    UINT                      encoder_modis;
    229 
    230    /* Capabity flags */
    231    UINT                      CAPF_tpEnc;
    232 
    233 } ;
    234 
    235 ////////////////////////////////////////////////////////////////////////////////////
    236 
    237 static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)
    238 {
    239     INT sbrUsed = 0;
    240 
    241     if ( (hAacConfig->audioObjectType==AOT_SBR)         || (hAacConfig->audioObjectType==AOT_PS)
    242       || (hAacConfig->audioObjectType==AOT_MP2_SBR)     || (hAacConfig->audioObjectType==AOT_MP2_PS)
    243       || (hAacConfig->audioObjectType==AOT_DABPLUS_SBR) || (hAacConfig->audioObjectType==AOT_DABPLUS_PS)
    244       || (hAacConfig->audioObjectType==AOT_DRM_SBR)     || (hAacConfig->audioObjectType==AOT_DRM_MPEG_PS) )
    245     {
    246         sbrUsed = 1;
    247     }
    248     if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD && (hAacConfig->syntaxFlags & AC_SBR_PRESENT))
    249     {
    250         sbrUsed = 1;
    251     }
    252 
    253     return ( sbrUsed );
    254 }
    255 
    256 /****************************************************************************
    257                                Allocate Encoder
    258 ****************************************************************************/
    259 
    260 H_ALLOC_MEM (_AacEncoder, AACENCODER)
    261 C_ALLOC_MEM (_AacEncoder, AACENCODER, 1)
    262 
    263 
    264 
    265 
    266 /*
    267  * Map Encoder specific config structures to CODER_CONFIG.
    268  */
    269 static
    270 void FDKaacEnc_MapConfig(CODER_CONFIG *cc, USER_PARAM *extCfg, HANDLE_AACENC_CONFIG hAacConfig)
    271 {
    272   AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT;
    273   FDKmemclear(cc, sizeof(CODER_CONFIG));
    274 
    275   cc->flags = 0;
    276 
    277   /* Map virtual aot to transport aot. */
    278   switch (hAacConfig->audioObjectType) {
    279     case AOT_MP2_AAC_LC:
    280       transport_AOT = AOT_AAC_LC;
    281       break;
    282     case AOT_MP2_SBR:
    283       transport_AOT = AOT_SBR;
    284       cc->flags |= CC_SBR;
    285      break;
    286     case AOT_MP2_PS:
    287       transport_AOT = AOT_PS;
    288       cc->flags |= CC_SBR;
    289       break;
    290     default:
    291       transport_AOT = hAacConfig->audioObjectType;
    292   }
    293 
    294   if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
    295     cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
    296   }
    297 
    298   /* transport type is usually AAC-LC. */
    299   if ( (transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS) ) {
    300     cc->aot           = AOT_AAC_LC;
    301   }
    302   else {
    303     cc->aot           = transport_AOT;
    304   }
    305 
    306   /* Configure extension aot. */
    307   if (extCfg->userTpSignaling==0) {
    308     cc->extAOT = AOT_NULL_OBJECT;  /* implicit */
    309   }
    310   else {
    311     if ( (extCfg->userTpSignaling==1) && ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) ) {
    312       cc->extAOT = AOT_SBR;        /* explicit backward compatible */
    313     }
    314     else {
    315       cc->extAOT = transport_AOT;  /* explicit hierarchical */
    316     }
    317   }
    318   cc->extSamplingRate = extCfg->userSamplerate;
    319   cc->bitRate         = hAacConfig->bitRate;
    320   cc->noChannels      = hAacConfig->nChannels;
    321   cc->flags          |= CC_IS_BASELAYER;
    322   cc->channelMode     = hAacConfig->channelMode;
    323 
    324   cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
    325                  ? hAacConfig->nSubFrames
    326                  : extCfg->userTpNsubFrames;
    327 
    328   cc->flags          |= (extCfg->userTpProtection) ? CC_PROTECTION : 0;
    329 
    330   if (extCfg->userTpHeaderPeriod!=0xFF) {
    331     cc->headerPeriod    = extCfg->userTpHeaderPeriod;
    332   }
    333   else { /* auto-mode */
    334     switch (extCfg->userTpType) {
    335       case TT_MP4_ADTS:
    336       case TT_MP4_LOAS:
    337       case TT_MP4_LATM_MCP1:
    338         cc->headerPeriod = 10;
    339         break;
    340       default:
    341         cc->headerPeriod = 0;
    342     }
    343   }
    344 
    345   cc->samplesPerFrame = hAacConfig->framelength;
    346   cc->samplingRate    = hAacConfig->sampleRate;
    347 
    348   /* Mpeg-4 signaling for transport library. */
    349   switch ( hAacConfig->audioObjectType ) {
    350     case AOT_MP2_AAC_LC:
    351     case AOT_MP2_SBR:
    352     case AOT_MP2_PS:
    353       cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
    354       //config->userTpSignaling=0;
    355       cc->extAOT = AOT_NULL_OBJECT;
    356       break;
    357     default:
    358       cc->flags |= CC_MPEG_ID;
    359   }
    360 
    361   /* ER-tools signaling. */
    362   cc->flags     |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
    363   cc->flags     |= (hAacConfig->syntaxFlags & AC_ER_HCR)   ? CC_HCR : 0;
    364   cc->flags     |= (hAacConfig->syntaxFlags & AC_ER_RVLC)  ? CC_RVLC : 0;
    365 
    366   /* Matrix mixdown coefficient configuration. */
    367   if ( (extCfg->userPceAdditions&0x1) && (hAacConfig->epConfig==-1)
    368       && ((cc->channelMode==MODE_1_2_2)||(cc->channelMode==MODE_1_2_2_1)) )
    369   {
    370     cc->matrixMixdownA       = ((extCfg->userPceAdditions>>1)&0x3)+1;
    371     cc->flags |= (extCfg->userPceAdditions>>3)&0x1 ? CC_PSEUDO_SURROUND : 0;
    372   }
    373   else {
    374     cc->matrixMixdownA = 0;
    375   }
    376 }
    377 
    378 /*
    379  * Examine buffer descriptor regarding choosen identifier.
    380  *
    381  * \param pBufDesc              Pointer to buffer descriptor
    382  * \param identifier            Buffer identifier to look for.
    383 
    384  * \return - Buffer descriptor index.
    385  *         -1, if there is no entry available.
    386  */
    387 static INT getBufDescIdx(
    388         const AACENC_BufDesc         *pBufDesc,
    389         const AACENC_BufferIdentifier identifier
    390 )
    391 {
    392     INT i, idx = -1;
    393 
    394     for (i=0; i<pBufDesc->numBufs; i++) {
    395       if ( (AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] == identifier ) {
    396         idx = i;
    397         break;
    398       }
    399     }
    400     return idx;
    401 }
    402 
    403 
    404 /****************************************************************************
    405                           Function Declarations
    406 ****************************************************************************/
    407 
    408 AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
    409                                       USER_PARAM *config)
    410 {
    411     /* make reasonable default settings */
    412     FDKaacEnc_AacInitDefaultConfig (hAacConfig);
    413 
    414     /* clear confure structure and copy default settings */
    415     FDKmemclear(config, sizeof(USER_PARAM));
    416 
    417     /* copy encoder configuration settings */
    418     config->nChannels       = hAacConfig->nChannels;
    419     config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC;
    420     config->userSamplerate  = hAacConfig->sampleRate;
    421     config->userChannelMode = hAacConfig->channelMode;
    422     config->userBitrate     = hAacConfig->bitRate;
    423     config->userBitrateMode = hAacConfig->bitrateMode;
    424     config->userBandwidth   = hAacConfig->bandWidth;
    425     config->userTns         = hAacConfig->useTns;
    426     config->userPns         = hAacConfig->usePns;
    427     config->userIntensity   = hAacConfig->useIS;
    428     config->userAfterburner = hAacConfig->useRequant;
    429     config->userFramelength = (UINT)-1;
    430 
    431     if (hAacConfig->syntaxFlags & AC_ER_VCB11) {
    432       config->userErTools  |= 0x01;
    433     }
    434     if (hAacConfig->syntaxFlags & AC_ER_HCR) {
    435       config->userErTools  |= 0x02;
    436     }
    437 
    438     /* initialize transport parameters */
    439     config->userTpType         = TT_UNKNOWN;
    440     config->userTpAmxv         = 0;
    441     config->userTpSignaling    = 0;    /* default, implicit signaling */
    442     config->userTpNsubFrames   = 1;
    443     config->userTpProtection   = 0;    /* not crc protected*/
    444     config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */
    445     config->userPceAdditions   = 0;    /* no matrix mixdown coefficient */
    446     config->userMetaDataMode   = 0;    /* do not embed any meta data info */
    447 
    448     config->userAncDataRate    = 0;
    449 
    450     return AAC_ENC_OK;
    451 }
    452 
    453 static
    454 void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, SBR_ELEMENT_INFO *sbrElInfo, INT bitRate)
    455 {
    456   INT codebits = bitRate;
    457   int el;
    458 
    459   /* Copy Element info */
    460   for (el=0; el<channelMapping->nElements; el++) {
    461       sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0];
    462       sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1];
    463       sbrElInfo[el].elType          = channelMapping->elInfo[el].elType;
    464       sbrElInfo[el].bitRate         = (INT)(fMultNorm(channelMapping->elInfo[el].relativeBits, (FIXP_DBL)bitRate));
    465       sbrElInfo[el].instanceTag     = channelMapping->elInfo[el].instanceTag;
    466       sbrElInfo[el].nChannelsInEl   = channelMapping->elInfo[el].nChannelsInEl;
    467 
    468       codebits -= sbrElInfo[el].bitRate;
    469   }
    470   sbrElInfo[0].bitRate += codebits;
    471 }
    472 
    473 
    474 static
    475 INT aacEncoder_LimitBitrate(
    476         const HANDLE_TRANSPORTENC hTpEnc,
    477         const INT samplingRate,
    478         const INT frameLength,
    479         const INT nChannels,
    480         const CHANNEL_MODE channelMode,
    481         INT bitRate,
    482         const INT nSubFrames,
    483         const INT sbrActive,
    484         const AUDIO_OBJECT_TYPE aot
    485         )
    486 {
    487   INT coreSamplingRate;
    488   CHANNEL_MAPPING cm;
    489 
    490   FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
    491 
    492   if (sbrActive) {
    493     /* Assume SBR rate ratio of 2:1 */
    494     coreSamplingRate = samplingRate / 2;
    495   } else {
    496     coreSamplingRate = samplingRate;
    497   }
    498 
    499   /* Consider bandwidth channel bit rate limit (see bandwidth.cpp: GetBandwidthEntry()) */
    500   if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
    501     bitRate = FDKmin(360000*nChannels, bitRate);
    502     bitRate = FDKmax(8000*nChannels, bitRate);
    503   }
    504 
    505   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS)  {
    506     bitRate = FDKmin(576000*nChannels, bitRate);
    507     /*bitRate = FDKmax(0*nChannels, bitRate);*/
    508   }
    509 
    510 
    511   /* Limit bit rate in respect to the core coder */
    512   bitRate = FDKaacEnc_LimitBitrate(
    513           hTpEnc,
    514           coreSamplingRate,
    515           frameLength,
    516           nChannels,
    517           cm.nChannelsEff,
    518           bitRate,
    519           -1,
    520           NULL,
    521           -1,
    522           nSubFrames
    523           );
    524 
    525   /* Limit bit rate in respect to available SBR modes if active */
    526   if (sbrActive)
    527   {
    528     SBR_ELEMENT_INFO sbrElInfo[6];
    529     INT sbrBitRate = 0;
    530     int e, tooBig=-1;
    531 
    532     FDK_ASSERT(cm.nElements <= (6));
    533 
    534     /* Get bit rate for each SBR element */
    535     aacEncDistributeSbrBits(&cm, sbrElInfo, bitRate);
    536 
    537     for (e=0; e<cm.nElements; e++)
    538     {
    539       INT sbrElementBitRateIn, sbrBitRateOut;
    540 
    541       if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
    542         continue;
    543       }
    544       sbrElementBitRateIn = sbrElInfo[e].bitRate;
    545       sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn , cm.elInfo[e].nChannelsInEl, coreSamplingRate, aot);
    546       if (sbrBitRateOut == 0) {
    547         return 0;
    548       }
    549       if (sbrElementBitRateIn < sbrBitRateOut) {
    550         FDK_ASSERT(tooBig != 1);
    551         tooBig = 0;
    552         if (e == 0) {
    553           sbrBitRate = 0;
    554         }
    555       }
    556       if (sbrElementBitRateIn > sbrBitRateOut) {
    557         FDK_ASSERT(tooBig != 0);
    558         tooBig = 1;
    559         if (e == 0) {
    560           sbrBitRate = 5000000;
    561         }
    562       }
    563       if (tooBig != -1)
    564       {
    565         INT sbrBitRateLimit = (INT)fDivNorm((FIXP_DBL)sbrBitRateOut, cm.elInfo[e].relativeBits);
    566         if (tooBig) {
    567           sbrBitRate = fMin(sbrBitRate, sbrBitRateLimit-16);
    568           FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) < sbrBitRateOut);
    569         } else {
    570           sbrBitRate = fMax(sbrBitRate, sbrBitRateLimit+16);
    571           FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) >= sbrBitRateOut);
    572         }
    573       }
    574     }
    575     if (tooBig != -1) {
    576       bitRate = sbrBitRate;
    577     }
    578   }
    579 
    580   FDK_ASSERT(bitRate > 0);
    581 
    582   return bitRate;
    583 }
    584 
    585 /*
    586  * \brief Consistency check of given USER_PARAM struct and
    587  *   copy back configuration from public struct into internal
    588  *   encoder configuration struct.
    589  *
    590  * \hAacEncoder Internal encoder config which is to be updated
    591  * \param config User provided config (public struct)
    592  * \return returns always AAC_ENC_OK
    593  */
    594 static
    595 AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
    596                                          USER_PARAM *config)
    597 {
    598     AACENC_ERROR err = AACENC_OK;
    599 
    600     /* Get struct pointers. */
    601     HANDLE_AACENC_CONFIG    hAacConfig = &hAacEncoder->aacConfig;
    602 
    603     hAacConfig->nChannels       = config->nChannels;
    604 
    605     /* Encoder settings update. */
    606     hAacConfig->sampleRate      = config->userSamplerate;
    607     hAacConfig->useTns          = config->userTns;
    608     hAacConfig->usePns          = config->userPns;
    609     hAacConfig->useIS           = config->userIntensity;
    610     hAacConfig->bitRate         = config->userBitrate;
    611     hAacConfig->channelMode     = config->userChannelMode;
    612     hAacConfig->bitrateMode     = config->userBitrateMode;
    613     hAacConfig->bandWidth       = config->userBandwidth;
    614     hAacConfig->useRequant      = config->userAfterburner;
    615 
    616     hAacConfig->audioObjectType = config->userAOT;
    617     hAacConfig->anc_Rate        = config->userAncDataRate;
    618     hAacConfig->syntaxFlags     = 0;
    619     hAacConfig->epConfig        = -1;
    620 
    621     /* Adapt internal AOT when necessary. */
    622     switch ( hAacConfig->audioObjectType ) {
    623       case AOT_MP2_AAC_LC:
    624       case AOT_MP2_SBR:
    625       case AOT_MP2_PS:
    626           hAacConfig->usePns = 0;
    627           if (config->userTpSignaling!=0) {
    628             return AACENC_INVALID_CONFIG; /* only implicit signaling allowed */
    629           }
    630       case AOT_AAC_LC:
    631       case AOT_SBR:
    632       case AOT_PS:
    633           config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS;
    634           hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 1024;
    635           if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {
    636             return AACENC_INVALID_CONFIG;
    637           }
    638           break;
    639       case AOT_ER_AAC_LC:
    640           hAacConfig->epConfig = 0;
    641           hAacConfig->syntaxFlags |= AC_ER;
    642           hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
    643           hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
    644           config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
    645           hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 1024;
    646           if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {
    647             return AACENC_INVALID_CONFIG;
    648           }
    649           break;
    650       case AOT_ER_AAC_LD:
    651           hAacConfig->epConfig = 0;
    652           hAacConfig->syntaxFlags |= AC_ER|AC_LD;
    653           hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
    654           hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
    655           hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
    656           config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
    657           hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512;
    658           if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
    659             return AACENC_INVALID_CONFIG;
    660           }
    661           break;
    662       case AOT_ER_AAC_ELD:
    663           hAacConfig->epConfig = 0;
    664           hAacConfig->syntaxFlags |= AC_ER|AC_ELD;
    665           hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
    666           hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
    667           hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
    668           hAacConfig->syntaxFlags |= ((config->userSbrEnabled)    ? AC_SBR_PRESENT : 0);
    669           config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
    670           hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512;
    671           if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
    672             return AACENC_INVALID_CONFIG;
    673           }
    674           break;
    675       default:
    676           break;
    677     }
    678 
    679     /* We need the frame length to call aacEncoder_LimitBitrate() */
    680     hAacConfig->bitRate = aacEncoder_LimitBitrate(
    681               NULL,
    682               hAacConfig->sampleRate,
    683               hAacConfig->framelength,
    684               hAacConfig->nChannels,
    685               hAacConfig->channelMode,
    686               config->userBitrate,
    687               hAacConfig->nSubFrames,
    688               isSbrActive(hAacConfig),
    689               hAacConfig->audioObjectType
    690               );
    691 
    692     switch ( hAacConfig->audioObjectType ) {
    693       case AOT_ER_AAC_LD:
    694       case AOT_ER_AAC_ELD:
    695         if (config->userBitrateMode==8) {
    696           hAacConfig->bitrateMode = 0;
    697         }
    698         if (config->userBitrateMode==0) {
    699           hAacConfig->bitreservoir = 50*config->nChannels; /* default, reduced bitreservoir */
    700         }
    701         if (hAacConfig->bitrateMode!=0) {
    702           return AACENC_INVALID_CONFIG;
    703         }
    704         break;
    705       default:
    706         break;
    707     }
    708 
    709     if (hAacConfig->epConfig >= 0) {
    710         hAacConfig->syntaxFlags |= AC_ER;
    711          if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) {
    712            return AACENC_INVALID_CONFIG;        /* Cannel config 0 not supported. */
    713          }
    714     }
    715 
    716     if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) {
    717         return AACENC_INVALID_CONFIG;        /* nChannels doesn't match chMode, this is just a check-up */
    718     }
    719 
    720     if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels)
    721       || ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
    722             isSbrActive(hAacConfig) )
    723          )
    724     {
    725         return AACENC_INVALID_CONFIG;      /* not enough channels allocated */
    726     }
    727 
    728     /* get bitrate in VBR configuration */
    729     if ( (hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5) ) {
    730         /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode. */
    731         hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode, hAacConfig->channelMode);
    732     }
    733 
    734 
    735 
    736     /* Set default bitrate if no external bitrate declared. */
    737     if (hAacConfig->bitRate==-1) {
    738         INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff * hAacConfig->sampleRate;
    739         switch (hAacConfig->audioObjectType)
    740         {
    741             case AOT_AAC_LC:
    742                 hAacConfig->bitRate = bitrate + (bitrate>>1);        /* 1.5 bits per sample */
    743                 break;
    744             case AOT_SBR:
    745                 hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1;   /* 0.625 bits per sample */
    746                 break;
    747             case AOT_PS:
    748                 hAacConfig->bitRate = (bitrate>>1);                  /* 0.5 bit per sample */
    749                 break;
    750             default:
    751                 hAacConfig->bitRate = bitrate;
    752                 break;
    753         }
    754     }
    755 
    756     /* Configure PNS */
    757     if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */
    758         || (hAacConfig->useTns == 0) )                                  /* TNS required. */
    759     {
    760         hAacConfig->usePns = 0;
    761     }
    762 
    763     /* Meta data restriction. */
    764     switch (hAacConfig->audioObjectType)
    765     {
    766       /* Allow metadata support */
    767       case AOT_AAC_LC:
    768       case AOT_SBR:
    769         hAacEncoder->metaDataAllowed = 1;
    770         if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) {
    771           config->userMetaDataMode = 0;
    772         }
    773         break;
    774       /* Prohibit metadata support */
    775       default:
    776         hAacEncoder->metaDataAllowed = 0;
    777     }
    778 
    779     return err;
    780 }
    781 
    782 static
    783 INT aacenc_SbrCallback(
    784         void *                  self,
    785         HANDLE_FDK_BITSTREAM    hBs,
    786         const INT sampleRateIn,
    787         const INT sampleRateOut,
    788         const INT samplesPerFrame,
    789         const AUDIO_OBJECT_TYPE coreCodec,
    790         const MP4_ELEMENT_ID    elementID,
    791         const INT               elementIndex
    792         )
    793 {
    794   HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
    795 
    796   sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0);
    797 
    798   return 0;
    799 }
    800 
    801 static AACENC_ERROR aacEncInit(HANDLE_AACENCODER  hAacEncoder,
    802                                ULONG              InitFlags,
    803                                USER_PARAM        *config)
    804 {
    805     AACENC_ERROR err = AACENC_OK;
    806 
    807     INT aacBufferOffset = 0;
    808     HANDLE_SBR_ENCODER     *hSbrEncoder = &hAacEncoder->hEnvEnc;
    809     HANDLE_AACENC_CONFIG    hAacConfig  = &hAacEncoder->aacConfig;
    810 
    811     hAacEncoder->nZerosAppended = 0;          /* count appended zeros */
    812 
    813     INT frameLength = hAacConfig->framelength;
    814 
    815     if ( (InitFlags & AACENC_INIT_CONFIG) )
    816     {
    817         CHANNEL_MODE prevChMode = hAacConfig->channelMode;
    818 
    819         /* Verify settings and update: config -> heAacEncoder */
    820         if ( (err=FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK ) {
    821             return err;
    822         }
    823         frameLength = hAacConfig->framelength; /* adapt temporal framelength */
    824 
    825         /* Seamless channel reconfiguration in sbr not fully implemented */
    826         if ( (prevChMode!=hAacConfig->channelMode) && isSbrActive(hAacConfig) ) {
    827             InitFlags |= AACENC_INIT_STATES;
    828         }
    829     }
    830 
    831     /* Clear input buffer */
    832     if ( (InitFlags == AACENC_INIT_ALL) ) {
    833         FDKmemclear(hAacEncoder->inputBuffer, sizeof(INT_PCM)*hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE);
    834     }
    835 
    836     if ( (InitFlags & AACENC_INIT_CONFIG) )
    837     {
    838         aacBufferOffset = 0;
    839         if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
    840             hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength);
    841         } else
    842         {
    843             hAacEncoder->nDelay = DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */
    844         }
    845         hAacConfig->ancDataBitRate = 0;
    846     }
    847 
    848     if ( isSbrActive(hAacConfig) &&
    849         ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) )
    850     {
    851         INT sbrError;
    852         SBR_ELEMENT_INFO sbrElInfo[(6)];
    853         CHANNEL_MAPPING channelMapping;
    854 
    855         AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType;
    856 
    857         if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode,
    858                                           hAacConfig->channelOrder,
    859                                          &channelMapping) != AAC_ENC_OK )
    860         {
    861             return AACENC_INIT_ERROR;
    862         }
    863 
    864         /* Check return value and if the SBR encoder can handle enough elements */
    865         if (channelMapping.nElements > (6)) {
    866             return AACENC_INIT_ERROR;
    867         }
    868 
    869         aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate);
    870 
    871         UINT initFlag = 0;
    872         initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0;
    873 
    874         /* Let the SBR encoder take a look at the configuration and change if required. */
    875         sbrError = sbrEncoder_Init(
    876                                 *hSbrEncoder,
    877                                  sbrElInfo,
    878                                  channelMapping.nElements,
    879                                  hAacEncoder->inputBuffer,
    880                                 &hAacConfig->bandWidth,
    881                                 &aacBufferOffset,
    882                                 &hAacConfig->nChannels,
    883                                 &hAacConfig->sampleRate,
    884                                 &frameLength,
    885                                 &hAacConfig->audioObjectType,
    886                                 &hAacEncoder->nDelay,
    887                                  (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
    888                                  initFlag
    889                                 );
    890 
    891         /* Suppress AOT reconfiguration and check error status. */
    892         if ( sbrError || (hAacConfig->audioObjectType!=aot) ) {
    893             return AACENC_INIT_SBR_ERROR;
    894         }
    895 
    896         if (hAacConfig->nChannels == 1) {
    897             hAacConfig->channelMode = MODE_1;
    898         }
    899 
    900         /* Never use PNS if SBR is active */
    901         if ( hAacConfig->usePns ) {
    902            hAacConfig->usePns = 0;
    903         }
    904 
    905         /* estimated bitrate consumed by SBR or PS */
    906         hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder) ;
    907 
    908     } /* sbr initialization */
    909 
    910 
    911     /*
    912      * Initialize Transport - Module.
    913      */
    914     if ( (InitFlags & AACENC_INIT_TRANSPORT) )
    915     {
    916         UINT flags = 0;
    917 
    918         FDKaacEnc_MapConfig(&hAacEncoder->coderConfig, config, hAacConfig);
    919 
    920         /* create flags for transport encoder */
    921         if (config->userTpAmxv == 1) {
    922             flags |= TP_FLAG_LATM_AMV;
    923         }
    924         /* Clear output buffer */
    925         FDKmemclear(hAacEncoder->outBuffer, hAacEncoder->outBufferInBytes*sizeof(UCHAR));
    926 
    927         /* Initialize Bitstream encoder */
    928         if ( transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer, hAacEncoder->outBufferInBytes, config->userTpType, &hAacEncoder->coderConfig, flags) != 0) {
    929             return AACENC_INIT_TP_ERROR;
    930         }
    931 
    932     } /* transport initialization */
    933 
    934     /*
    935      * Initialize AAC - Core.
    936      */
    937     if ( (InitFlags & AACENC_INIT_CONFIG) ||
    938          (InitFlags & AACENC_INIT_STATES) )
    939     {
    940         AAC_ENCODER_ERROR err;
    941         err = FDKaacEnc_Initialize(hAacEncoder->hAacEnc,
    942                                    hAacConfig,
    943                                    hAacEncoder->hTpEnc,
    944                                    (InitFlags & AACENC_INIT_STATES) ? 1 : 0);
    945 
    946         if (err != AAC_ENC_OK) {
    947             return AACENC_INIT_AAC_ERROR;
    948         }
    949 
    950     } /* aac initialization */
    951 
    952     /*
    953      * Initialize Meta Data - Encoder.
    954      */
    955     if ( hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed!=0) &&
    956         ((InitFlags & AACENC_INIT_CONFIG) ||(InitFlags & AACENC_INIT_STATES)) )
    957     {
    958         INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);
    959 
    960         if ( isSbrActive(hAacConfig) && hSbrEncoder!=NULL) {
    961             inputDataDelay = 2*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder);
    962         }
    963 
    964         if ( FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
    965                                  ((InitFlags&AACENC_INIT_STATES) ? 1 : 0),
    966                                   config->userMetaDataMode,
    967                                   inputDataDelay,
    968                                   frameLength,
    969                                   config->userSamplerate,
    970                                   config->nChannels,
    971                                   config->userChannelMode,
    972                                   hAacConfig->channelOrder) != 0)
    973         {
    974             return AACENC_INIT_META_ERROR;
    975         }
    976 
    977         hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc);
    978     }
    979 
    980     /*
    981      * Update pointer to working buffer.
    982      */
    983     if ( (InitFlags & AACENC_INIT_CONFIG) )
    984     {
    985         hAacEncoder->inputBufferOffset = aacBufferOffset;
    986 
    987         hAacEncoder->nSamplesToRead = frameLength * config->nChannels;
    988 
    989         /* Make nDelay comparison compatible with config->nSamplesRead */
    990         hAacEncoder->nDelay *= config->nChannels;
    991 
    992     } /* parameter changed */
    993 
    994     return AACENC_OK;
    995 }
    996 
    997 
    998 AACENC_ERROR aacEncOpen(
    999         HANDLE_AACENCODER        *phAacEncoder,
   1000         const UINT                encModules,
   1001         const UINT                maxChannels
   1002         )
   1003 {
   1004     AACENC_ERROR err = AACENC_OK;
   1005     HANDLE_AACENCODER  hAacEncoder = NULL;
   1006 
   1007     if (phAacEncoder == NULL) {
   1008         err = AACENC_INVALID_HANDLE;
   1009         goto bail;
   1010     }
   1011 
   1012     /* allocate memory */
   1013     hAacEncoder = Get_AacEncoder();
   1014 
   1015     if (hAacEncoder == NULL) {
   1016         err = AACENC_MEMORY_ERROR;
   1017         goto bail;
   1018     }
   1019 
   1020     FDKmemclear(hAacEncoder, sizeof(AACENCODER));
   1021 
   1022     /* Specify encoder modules to be allocated. */
   1023     if (encModules==0) {
   1024         hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC;
   1025         hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR;
   1026         hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS;
   1027         hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META;
   1028     }
   1029     else {
   1030        /* consider SAC and PS module */
   1031         hAacEncoder->encoder_modis = encModules;
   1032     }
   1033 
   1034     /* Determine max channel configuration. */
   1035     if (maxChannels==0) {
   1036         hAacEncoder->nMaxAacChannels = (6);
   1037         hAacEncoder->nMaxSbrChannels = (6);
   1038     }
   1039     else {
   1040         hAacEncoder->nMaxAacChannels = (maxChannels&0x00FF);
   1041         if ( (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SBR) ) {
   1042             hAacEncoder->nMaxSbrChannels = (maxChannels&0xFF00) ? (maxChannels>>8) : hAacEncoder->nMaxAacChannels;
   1043         }
   1044 
   1045         if ( (hAacEncoder->nMaxAacChannels>(6)) || (hAacEncoder->nMaxSbrChannels>(6)) ) {
   1046             err = AACENC_INVALID_CONFIG;
   1047             goto bail;
   1048         }
   1049     } /* maxChannels==0 */
   1050 
   1051     /* Max number of elements could be tuned any more. */
   1052     hAacEncoder->nMaxAacElements = fixMin((6), hAacEncoder->nMaxAacChannels);
   1053     hAacEncoder->nMaxSbrElements = fixMin((6), hAacEncoder->nMaxSbrChannels);
   1054     hAacEncoder->nMaxSubFrames = (1);
   1055 
   1056 
   1057     /* In case of memory overlay, allocate memory out of libraries */
   1058 
   1059     hAacEncoder->inputBuffer = (INT_PCM*)FDKcalloc(hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE, sizeof(INT_PCM));
   1060 
   1061     /* Open SBR Encoder */
   1062     if (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SBR) {
   1063         if ( sbrEncoder_Open(&hAacEncoder->hEnvEnc,
   1064                               hAacEncoder->nMaxSbrElements,
   1065                               hAacEncoder->nMaxSbrChannels,
   1066                              (hAacEncoder->encoder_modis&ENC_MODE_FLAG_PS) ? 1 : 0 ) )
   1067         {
   1068           err = AACENC_MEMORY_ERROR;
   1069           goto bail;
   1070         }
   1071     } /* (encoder_modis&ENC_MODE_FLAG_SBR) */
   1072 
   1073 
   1074     /* Open Aac Encoder */
   1075     if ( FDKaacEnc_Open(&hAacEncoder->hAacEnc,
   1076                          hAacEncoder->nMaxAacElements,
   1077                          hAacEncoder->nMaxAacChannels,
   1078                          (1)) != AAC_ENC_OK )
   1079     {
   1080         err = AACENC_MEMORY_ERROR;
   1081         goto bail;
   1082     }
   1083 
   1084     { /* Get bitstream outputbuffer size */
   1085       UINT ld_M;
   1086       for (ld_M=1; (UINT)(1<<ld_M) < (hAacEncoder->nMaxSubFrames*hAacEncoder->nMaxAacChannels*6144)>>3; ld_M++) ;
   1087       hAacEncoder->outBufferInBytes = (1<<ld_M);  /* buffer has to be 2^n */
   1088     }
   1089     hAacEncoder->outBuffer = GetRam_bsOutbuffer();
   1090     if (OUTPUTBUFFER_SIZE < hAacEncoder->outBufferInBytes ) {
   1091       err = AACENC_MEMORY_ERROR;
   1092       goto bail;
   1093     }
   1094 
   1095     /* Open Meta Data Encoder */
   1096     if (hAacEncoder->encoder_modis&ENC_MODE_FLAG_META) {
   1097       if ( FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc) )
   1098       {
   1099         err = AACENC_MEMORY_ERROR;
   1100         goto bail;
   1101       }
   1102     } /* (encoder_modis&ENC_MODE_FLAG_META) */
   1103 
   1104     /* Open Transport Encoder */
   1105     if ( transportEnc_Open(&hAacEncoder->hTpEnc) != 0 )
   1106     {
   1107         err = AACENC_MEMORY_ERROR;
   1108         goto bail;
   1109     }
   1110     else {
   1111         C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST);
   1112 
   1113         FDKinitLibInfo( pLibInfo);
   1114         transportEnc_GetLibInfo( pLibInfo );
   1115 
   1116         /* Get capabilty flag for transport encoder. */
   1117         hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities( pLibInfo, FDK_TPENC);
   1118 
   1119         C_ALLOC_SCRATCH_END(pLibInfo, LIB_INFO, FDK_MODULE_LAST);
   1120     }
   1121     if ( transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback, hAacEncoder) != 0 ) {
   1122       err = AACENC_INIT_TP_ERROR;
   1123       goto bail;
   1124     }
   1125 
   1126     /* Initialize encoder instance with default parameters. */
   1127     aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam);
   1128 
   1129     /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */
   1130     hAacEncoder->coderConfig.headerPeriod = hAacEncoder->extParam.userTpHeaderPeriod;
   1131 
   1132     /* All encoder modules have to be initialized */
   1133     hAacEncoder->InitFlags = AACENC_INIT_ALL;
   1134 
   1135     /* Return encoder instance */
   1136     *phAacEncoder = hAacEncoder;
   1137 
   1138     return err;
   1139 
   1140 bail:
   1141     aacEncClose(&hAacEncoder);
   1142 
   1143     return err;
   1144 }
   1145 
   1146 
   1147 
   1148 AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder)
   1149 {
   1150     AACENC_ERROR err = AACENC_OK;
   1151 
   1152     if (phAacEncoder == NULL) {
   1153         err = AACENC_INVALID_HANDLE;
   1154         goto bail;
   1155     }
   1156 
   1157     if (*phAacEncoder != NULL) {
   1158         HANDLE_AACENCODER hAacEncoder = *phAacEncoder;
   1159 
   1160 
   1161        if (hAacEncoder->inputBuffer!=NULL) {
   1162            FDKfree(hAacEncoder->inputBuffer);
   1163            hAacEncoder->inputBuffer = NULL;
   1164        }
   1165 
   1166        if (hAacEncoder->outBuffer) {
   1167          FreeRam_bsOutbuffer(&hAacEncoder->outBuffer);
   1168        }
   1169 
   1170         if (hAacEncoder->hEnvEnc) {
   1171             sbrEncoder_Close (&hAacEncoder->hEnvEnc);
   1172         }
   1173         if (hAacEncoder->hAacEnc) {
   1174             FDKaacEnc_Close (&hAacEncoder->hAacEnc);
   1175         }
   1176 
   1177         transportEnc_Close(&hAacEncoder->hTpEnc);
   1178 
   1179         if (hAacEncoder->hMetadataEnc) {
   1180             FDK_MetadataEnc_Close (&hAacEncoder->hMetadataEnc);
   1181         }
   1182 
   1183         Free_AacEncoder(phAacEncoder);
   1184     }
   1185 
   1186 bail:
   1187     return err;
   1188 }
   1189 
   1190 AACENC_ERROR aacEncEncode(
   1191         const HANDLE_AACENCODER   hAacEncoder,
   1192         const AACENC_BufDesc     *inBufDesc,
   1193         const AACENC_BufDesc     *outBufDesc,
   1194         const AACENC_InArgs      *inargs,
   1195         AACENC_OutArgs           *outargs
   1196         )
   1197 {
   1198     AACENC_ERROR err = AACENC_OK;
   1199     INT i, nBsBytes = 0;
   1200     INT  outBytes[(1)];
   1201     int  nExtensions = 0;
   1202     int  ancDataExtIdx = -1;
   1203 
   1204     /* deal with valid encoder handle */
   1205     if (hAacEncoder==NULL) {
   1206         err = AACENC_INVALID_HANDLE;
   1207         goto bail;
   1208     }
   1209 
   1210 
   1211     /*
   1212      * Adjust user settings and trigger reinitialization.
   1213      */
   1214     if (hAacEncoder->InitFlags!=0) {
   1215 
   1216         err = aacEncInit(hAacEncoder,
   1217                          hAacEncoder->InitFlags,
   1218                         &hAacEncoder->extParam);
   1219 
   1220         if (err!=AACENC_OK) {
   1221             /* keep init flags alive! */
   1222             goto bail;
   1223         }
   1224         hAacEncoder->InitFlags = AACENC_INIT_NONE;
   1225     }
   1226 
   1227     if (outargs!=NULL) {
   1228         FDKmemclear(outargs, sizeof(AACENC_OutArgs));
   1229     }
   1230 
   1231     if (outBufDesc!=NULL) {
   1232       for (i=0; i<outBufDesc->numBufs; i++) {
   1233         if (outBufDesc->bufs[i]!=NULL) {
   1234           FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]);
   1235         }
   1236       }
   1237     }
   1238 
   1239     /*
   1240      * If only encoder handle given, independent (re)initialization can be triggered.
   1241      */
   1242     if ( (hAacEncoder!=NULL) & (inBufDesc==NULL) && (outBufDesc==NULL) && (inargs==NULL) && (outargs==NULL) ) {
   1243         goto bail;
   1244     }
   1245 
   1246     /* reset buffer wich signals number of valid bytes in output bitstream buffer */
   1247     FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames*sizeof(INT));
   1248 
   1249     /*
   1250      * Manage incoming audio samples.
   1251      */
   1252     if ( (inargs->numInSamples > 0) && (getBufDescIdx(inBufDesc,IN_AUDIO_DATA) != -1) )
   1253     {
   1254         /* Fetch data until nSamplesToRead reached */
   1255         INT idx = getBufDescIdx(inBufDesc,IN_AUDIO_DATA);
   1256         INT newSamples = fixMax(0,fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead-hAacEncoder->nSamplesRead));
   1257         INT_PCM *pIn = hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset+hAacEncoder->nSamplesRead;
   1258 
   1259         /* Copy new input samples to internal buffer */
   1260         if (inBufDesc->bufElSizes[idx]==(INT)sizeof(INT_PCM)) {
   1261             FDKmemcpy(pIn, (INT_PCM*)inBufDesc->bufs[idx], newSamples*sizeof(INT_PCM));  /* Fast copy. */
   1262         }
   1263         else if (inBufDesc->bufElSizes[idx]>(INT)sizeof(INT_PCM)) {
   1264             for (i=0; i<newSamples; i++) {
   1265                 pIn[i] = (INT_PCM)(((LONG*)inBufDesc->bufs[idx])[i]>>16);                /* Convert 32 to 16 bit. */
   1266             }
   1267         }
   1268         else {
   1269             for (i=0; i<newSamples; i++) {
   1270                 pIn[i] = ((INT_PCM)(((SHORT*)inBufDesc->bufs[idx])[i]))<<16;             /* Convert 16 to 32 bit. */
   1271             }
   1272         }
   1273         hAacEncoder->nSamplesRead += newSamples;
   1274 
   1275         /* Number of fetched input buffer samples. */
   1276         outargs->numInSamples = newSamples;
   1277     }
   1278 
   1279     /* input buffer completely filled ? */
   1280     if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead)
   1281     {
   1282         /* - eof reached and flushing enabled, or
   1283            - return to main and wait for further incoming audio samples */
   1284         if (inargs->numInSamples==-1)
   1285         {
   1286             if ( (hAacEncoder->nZerosAppended < hAacEncoder->nDelay)
   1287                 )
   1288             {
   1289               int nZeros = hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead;
   1290 
   1291               FDK_ASSERT(nZeros >= 0);
   1292 
   1293               /* clear out until end-of-buffer */
   1294               if (nZeros) {
   1295                 FDKmemclear(hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset+hAacEncoder->nSamplesRead, sizeof(INT_PCM)*nZeros );
   1296                 hAacEncoder->nZerosAppended += nZeros;
   1297                 hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead;
   1298               }
   1299             }
   1300             else { /* flushing completed */
   1301               err = AACENC_ENCODE_EOF; /* eof reached */
   1302               goto bail;
   1303             }
   1304         }
   1305         else { /* inargs->numInSamples!= -1 */
   1306             goto bail; /* not enough samples in input buffer and no flushing enabled */
   1307         }
   1308     }
   1309 
   1310     /* init payload */
   1311     FDKmemclear(hAacEncoder->extPayload, sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS);
   1312     for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) {
   1313       hAacEncoder->extPayload[i].associatedChElement = -1;
   1314     }
   1315     FDKmemclear(hAacEncoder->extPayloadData, sizeof(hAacEncoder->extPayloadData));
   1316     FDKmemclear(hAacEncoder->extPayloadSize, sizeof(hAacEncoder->extPayloadSize));
   1317 
   1318 
   1319     /*
   1320      * Calculate Meta Data info.
   1321      */
   1322     if ( (hAacEncoder->hMetadataEnc!=NULL) && (hAacEncoder->metaDataAllowed!=0) ) {
   1323 
   1324         const AACENC_MetaData *pMetaData = NULL;
   1325         AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL;
   1326         UINT nMetaDataExtensions = 0;
   1327         INT  matrix_mixdown_idx = 0;
   1328 
   1329         /* New meta data info available ? */
   1330         if ( getBufDescIdx(inBufDesc,IN_METADATA_SETUP) != -1 ) {
   1331           pMetaData = (AACENC_MetaData*)inBufDesc->bufs[getBufDescIdx(inBufDesc,IN_METADATA_SETUP)];
   1332         }
   1333 
   1334         FDK_MetadataEnc_Process(hAacEncoder->hMetadataEnc,
   1335                                 hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset,
   1336                                 hAacEncoder->nSamplesRead,
   1337                                 pMetaData,
   1338                                &pMetaDataExtPayload,
   1339                                &nMetaDataExtensions,
   1340                                &matrix_mixdown_idx
   1341                                 );
   1342 
   1343         for (i=0; i<(INT)nMetaDataExtensions; i++) {  /* Get meta data extension payload. */
   1344             hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i];
   1345         }
   1346         if (matrix_mixdown_idx!=-1) {            /* Set matrix mixdown coefficient. */
   1347           UINT pceValue = (UINT)( (1<<3) | ((matrix_mixdown_idx&0x2)<<1) | 1 );
   1348           if (hAacEncoder->extParam.userPceAdditions != pceValue) {
   1349             hAacEncoder->extParam.userPceAdditions = pceValue;
   1350             hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
   1351           }
   1352         }
   1353     }
   1354 
   1355 
   1356     if ( isSbrActive(&hAacEncoder->aacConfig) ) {
   1357 
   1358         INT nPayload = 0;
   1359 
   1360         /*
   1361          * Encode SBR data.
   1362          */
   1363         if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc,
   1364                                    hAacEncoder->inputBuffer,
   1365                                    hAacEncoder->extParam.nChannels,
   1366                                    hAacEncoder->extPayloadSize[nPayload],
   1367                                    hAacEncoder->extPayloadData[nPayload]
   1368 #if defined(EVAL_PACKAGE_SILENCE) || defined(EVAL_PACKAGE_SBR_SILENCE)
   1369                                   ,hAacEncoder->hAacEnc->clearOutput
   1370 #endif
   1371                                   ))
   1372         {
   1373             err = AACENC_ENCODE_ERROR;
   1374             goto bail;
   1375         }
   1376         else {
   1377             /* Add SBR extension payload */
   1378             for (i = 0; i < (6); i++) {
   1379                 if (hAacEncoder->extPayloadSize[nPayload][i] > 0) {
   1380                     hAacEncoder->extPayload[nExtensions].pData    = hAacEncoder->extPayloadData[nPayload][i];
   1381                     {
   1382                       hAacEncoder->extPayload[nExtensions].dataSize = hAacEncoder->extPayloadSize[nPayload][i];
   1383                       hAacEncoder->extPayload[nExtensions].associatedChElement = i;
   1384                     }
   1385                     hAacEncoder->extPayload[nExtensions].dataType = EXT_SBR_DATA;  /* Once SBR Encoder supports SBR CRC set EXT_SBR_DATA_CRC */
   1386                     nExtensions++;                                                 /* or EXT_SBR_DATA according to configuration. */
   1387                     FDK_ASSERT(nExtensions<=MAX_TOTAL_EXT_PAYLOADS);
   1388                 }
   1389             }
   1390             nPayload++;
   1391         }
   1392     } /* sbrEnabled */
   1393 
   1394     if ( (inargs->numAncBytes > 0) && ( getBufDescIdx(inBufDesc,IN_ANCILLRY_DATA)!=-1 ) ) {
   1395         INT idx = getBufDescIdx(inBufDesc,IN_ANCILLRY_DATA);
   1396         hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8;
   1397         hAacEncoder->extPayload[nExtensions].pData    = (UCHAR*)inBufDesc->bufs[idx];
   1398         hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT;
   1399         hAacEncoder->extPayload[nExtensions].associatedChElement = -1;
   1400         ancDataExtIdx = nExtensions; /* store index */
   1401         nExtensions++;
   1402     }
   1403 
   1404     /*
   1405      * Encode AAC - Core.
   1406      */
   1407     if ( FDKaacEnc_EncodeFrame( hAacEncoder->hAacEnc,
   1408                                 hAacEncoder->hTpEnc,
   1409                                 hAacEncoder->inputBuffer,
   1410                                 outBytes,
   1411                                 hAacEncoder->extPayload
   1412                                 ) != AAC_ENC_OK )
   1413     {
   1414         err = AACENC_ENCODE_ERROR;
   1415         goto bail;
   1416     }
   1417 
   1418     if (ancDataExtIdx >= 0) {
   1419       outargs->numAncBytes = inargs->numAncBytes - (hAacEncoder->extPayload[ancDataExtIdx].dataSize>>3);
   1420     }
   1421 
   1422     /* samples exhausted */
   1423     hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead;
   1424 
   1425     /*
   1426      * Delay balancing buffer handling
   1427      */
   1428     if (isSbrActive(&hAacEncoder->aacConfig)) {
   1429         sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer);
   1430     }
   1431 
   1432     /*
   1433      * Make bitstream public
   1434      */
   1435     if (outBufDesc->numBufs>=1) {
   1436 
   1437         INT bsIdx = getBufDescIdx(outBufDesc,OUT_BITSTREAM_DATA);
   1438         INT auIdx = getBufDescIdx(outBufDesc,OUT_AU_SIZES);
   1439 
   1440         for (i=0,nBsBytes=0; i<hAacEncoder->aacConfig.nSubFrames; i++) {
   1441           nBsBytes += outBytes[i];
   1442 
   1443           if (auIdx!=-1) {
   1444            ((INT*)outBufDesc->bufs[auIdx])[i] = outBytes[i];
   1445           }
   1446         }
   1447 
   1448         if ( (bsIdx!=-1) && (outBufDesc->bufSizes[bsIdx]>=nBsBytes) ) {
   1449           FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer, sizeof(UCHAR)*nBsBytes);
   1450           outargs->numOutBytes = nBsBytes;
   1451         }
   1452         else {
   1453           /* output buffer too small, can't write valid bitstream */
   1454           err = AACENC_ENCODE_ERROR;
   1455           goto bail;
   1456         }
   1457     }
   1458 
   1459 bail:
   1460     if (err == AACENC_ENCODE_ERROR) {
   1461         /* All encoder modules have to be initialized */
   1462         hAacEncoder->InitFlags = AACENC_INIT_ALL;
   1463     }
   1464 
   1465     return err;
   1466 }
   1467 
   1468 static
   1469 AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER  hAacEncoder,
   1470                                 UINT              *size,
   1471                                 UCHAR             *confBuffer)
   1472 {
   1473     FDK_BITSTREAM tmpConf;
   1474     UINT confType;
   1475     UCHAR buf[64];
   1476     int err;
   1477 
   1478     /* Init bit buffer */
   1479     FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER);
   1480 
   1481     /* write conf in tmp buffer */
   1482     err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig, &tmpConf, &confType);
   1483 
   1484     /* copy data to outbuffer: length in bytes */
   1485     FDKbyteAlign(&tmpConf, 0);
   1486 
   1487     /* Check buffer size */
   1488     if (FDKgetValidBits(&tmpConf) > ((*size)<<3))
   1489       return AAC_ENC_UNKNOWN;
   1490 
   1491     FDKfetchBuffer(&tmpConf, confBuffer, size);
   1492 
   1493     if (err != 0)
   1494       return AAC_ENC_UNKNOWN;
   1495     else
   1496       return AAC_ENC_OK;
   1497 }
   1498 
   1499 
   1500 AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info)
   1501 {
   1502   int i = 0;
   1503 
   1504   if (info == NULL) {
   1505     return AACENC_INVALID_HANDLE;
   1506   }
   1507 
   1508   FDK_toolsGetLibInfo( info );
   1509   transportEnc_GetLibInfo( info );
   1510 
   1511   sbrEncoder_GetLibInfo( info );
   1512 
   1513   /* search for next free tab */
   1514   for (i = 0; i < FDK_MODULE_LAST; i++) {
   1515     if (info[i].module_id == FDK_NONE) break;
   1516   }
   1517   if (i == FDK_MODULE_LAST) {
   1518     return AACENC_INIT_ERROR;
   1519   }
   1520 
   1521   info[i].module_id = FDK_AACENC;
   1522   info[i].build_date = (char*)AACENCODER_LIB_BUILD_DATE;
   1523   info[i].build_time = (char*)AACENCODER_LIB_BUILD_TIME;
   1524   info[i].title = (char*)AACENCODER_LIB_TITLE;
   1525   info[i].version = LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);;
   1526   LIB_VERSION_STRING(&info[i]);
   1527 
   1528   /* Capability flags */
   1529   info[i].flags = 0
   1530     | CAPF_AAC_1024 | CAPF_AAC_LC
   1531     | CAPF_AAC_512
   1532     | CAPF_AAC_480
   1533     | CAPF_AAC_DRC
   1534       ;
   1535   /* End of flags */
   1536 
   1537   return AACENC_OK;
   1538 }
   1539 
   1540 AACENC_ERROR aacEncoder_SetParam(
   1541         const HANDLE_AACENCODER   hAacEncoder,
   1542         const AACENC_PARAM        param,
   1543         const UINT                value
   1544         )
   1545 {
   1546     AACENC_ERROR err = AACENC_OK;
   1547     USER_PARAM *settings = &hAacEncoder->extParam;
   1548 
   1549     /* check encoder handle */
   1550     if (hAacEncoder == NULL) {
   1551         err = AACENC_INVALID_HANDLE;
   1552         goto bail;
   1553     }
   1554 
   1555     /* apply param value */
   1556     switch (param)
   1557     {
   1558     case AACENC_AOT:
   1559         if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) {
   1560             /* check if AOT matches the allocated modules */
   1561             switch ( value ) {
   1562               case AOT_PS:
   1563               case AOT_MP2_PS:
   1564                 if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
   1565                   err = AACENC_INVALID_CONFIG;
   1566                   goto bail;
   1567                 }
   1568               case AOT_SBR:
   1569               case AOT_MP2_SBR:
   1570                 if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
   1571                   err = AACENC_INVALID_CONFIG;
   1572                   goto bail;
   1573                 }
   1574               case AOT_AAC_LC:
   1575               case AOT_MP2_AAC_LC:
   1576               case AOT_ER_AAC_LC:
   1577               case AOT_ER_AAC_LD:
   1578               case AOT_ER_AAC_ELD:
   1579                 if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
   1580                   err = AACENC_INVALID_CONFIG;
   1581                   goto bail;
   1582                 }
   1583                 break;
   1584               default:
   1585                 err = AACENC_INVALID_CONFIG;
   1586                 goto bail;
   1587             }/* switch value */
   1588             settings->userAOT = (AUDIO_OBJECT_TYPE)value;
   1589             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
   1590         }
   1591         break;
   1592     case AACENC_BITRATE:
   1593         if (settings->userBitrate != value) {
   1594             settings->userBitrate = value;
   1595             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
   1596         }
   1597         break;
   1598     case AACENC_BITRATEMODE:
   1599         if (settings->userBitrateMode != value) {
   1600             switch ( value ) {
   1601               case 0:
   1602               case 8:
   1603                 settings->userBitrateMode = value;
   1604                 hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
   1605                 break;
   1606               default:
   1607                 err = AACENC_INVALID_CONFIG;
   1608                 break;
   1609             } /* switch value */
   1610         }
   1611         break;
   1612     case AACENC_SAMPLERATE:
   1613         if (settings->userSamplerate != value) {
   1614             if ( !( (value==8000) || (value==11025) || (value==12000) || (value==16000) || (value==22050) || (value==24000) ||
   1615                    (value==32000) || (value==44100) || (value==48000) || (value==64000) || (value==88200) || (value==96000) ) )
   1616             {
   1617                 err = AACENC_INVALID_CONFIG;
   1618                 break;
   1619             }
   1620             settings->userSamplerate = value;
   1621             hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
   1622             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
   1623         }
   1624         break;
   1625     case AACENC_CHANNELMODE:
   1626         if (settings->userChannelMode != (CHANNEL_MODE)value) {
   1627             const CHANNEL_MODE_CONFIG_TAB* pConfig = FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value);
   1628             if (pConfig==NULL) {
   1629                 err = AACENC_INVALID_CONFIG;
   1630                 break;
   1631             }
   1632             if ( (pConfig->nElements > hAacEncoder->nMaxAacElements)
   1633               || (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)
   1634               || !((value>=1) && (value<=6))
   1635                 )
   1636             {
   1637                 err = AACENC_INVALID_CONFIG;
   1638                 break;
   1639             }
   1640 
   1641             settings->userChannelMode = (CHANNEL_MODE)value;
   1642             settings->nChannels = pConfig->nChannels;
   1643             hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
   1644             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
   1645         }
   1646         break;
   1647     case AACENC_BANDWIDTH:
   1648         if (settings->userBandwidth != value) {
   1649           settings->userBandwidth = value;
   1650           hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
   1651         }
   1652         break;
   1653     case AACENC_CHANNELORDER:
   1654         if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) {
   1655             if (! ((value==0) || (value==1)) ) {
   1656                 err = AACENC_INVALID_CONFIG;
   1657                 break;
   1658             }
   1659             hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value;
   1660             hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
   1661             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
   1662         }
   1663         break;
   1664     case AACENC_AFTERBURNER:
   1665         if (settings->userAfterburner != value) {
   1666             if (! ((value==0) || (value==1)) ) {
   1667                 err = AACENC_INVALID_CONFIG;
   1668                 break;
   1669             }
   1670             settings->userAfterburner = value;
   1671             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
   1672         }
   1673         break;
   1674     case AACENC_GRANULE_LENGTH:
   1675         if (settings->userFramelength != value) {
   1676           switch (value) {
   1677             case 1024:
   1678             case 512:
   1679             case 480:
   1680               settings->userFramelength = value;
   1681               hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
   1682               break;
   1683             default:
   1684               err = AACENC_INVALID_CONFIG;
   1685               break;
   1686           }
   1687         }
   1688         break;
   1689     case AACENC_SBR_MODE:
   1690         if (settings->userSbrEnabled != value) {
   1691             settings->userSbrEnabled = value;
   1692             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
   1693         }
   1694         break;
   1695     case AACENC_TRANSMUX:
   1696         if (settings->userTpType != (TRANSPORT_TYPE)value) {
   1697 
   1698             TRANSPORT_TYPE  type  = (TRANSPORT_TYPE)value;
   1699             UINT            flags = hAacEncoder->CAPF_tpEnc;
   1700 
   1701             if ( !( ((type==TT_MP4_ADIF)      &&  (flags&CAPF_ADIF))
   1702                  || ((type==TT_MP4_ADTS)      &&  (flags&CAPF_ADTS))
   1703                  || ((type==TT_MP4_LATM_MCP0) && ((flags&CAPF_LATM) && (flags&CAPF_RAWPACKETS)))
   1704                  || ((type==TT_MP4_LATM_MCP1) && ((flags&CAPF_LATM) && (flags&CAPF_RAWPACKETS)))
   1705                  || ((type==TT_MP4_LOAS)      &&  (flags&CAPF_LOAS))
   1706                  || ((type==TT_MP4_RAW)       &&  (flags&CAPF_RAWPACKETS))
   1707                 ) )
   1708             {
   1709                 err = AACENC_INVALID_CONFIG;
   1710                 break;
   1711             }
   1712             settings->userTpType = (TRANSPORT_TYPE)value;
   1713             hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
   1714         }
   1715         break;
   1716     case AACENC_SIGNALING_MODE:
   1717         if (settings->userTpSignaling != value) {
   1718             if ( !((value==0) || (value==1) || (value==2)) ) {
   1719                 err = AACENC_INVALID_CONFIG;
   1720                 break;
   1721             }
   1722             settings->userTpSignaling = value;
   1723             hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
   1724         }
   1725         break;
   1726     case AACENC_PROTECTION:
   1727         if (settings->userTpProtection != value) {
   1728             if ( !((value==0) || (value==1)) ) {
   1729                 err = AACENC_INVALID_CONFIG;
   1730                 break;
   1731             }
   1732             settings->userTpProtection = value;
   1733             hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
   1734         }
   1735         break;
   1736     case AACENC_HEADER_PERIOD:
   1737         if (settings->userTpHeaderPeriod != value) {
   1738             settings->userTpHeaderPeriod = value;
   1739             hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
   1740         }
   1741         break;
   1742     case AACENC_TPSUBFRAMES:
   1743         if (settings->userTpNsubFrames != value) {
   1744             if (! ( (value>=1) && (value<=4) ) ) {
   1745                 err = AACENC_INVALID_CONFIG;
   1746                 break;
   1747             }
   1748             settings->userTpNsubFrames = value;
   1749             hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
   1750         }
   1751         break;
   1752     case AACENC_ANCILLARY_BITRATE:
   1753         if (settings->userAncDataRate != value) {
   1754             settings->userAncDataRate = value;
   1755         }
   1756         break;
   1757     case AACENC_CONTROL_STATE:
   1758         if (hAacEncoder->InitFlags != value) {
   1759             if (value&AACENC_RESET_INBUFFER) {
   1760                 hAacEncoder->nSamplesRead = 0;
   1761             }
   1762             hAacEncoder->InitFlags = value;
   1763         }
   1764         break;
   1765     case AACENC_METADATA_MODE:
   1766         if ((UINT)settings->userMetaDataMode != value) {
   1767             if ( !((value>=0) && (value<=2)) ) {
   1768                 err = AACENC_INVALID_CONFIG;
   1769                 break;
   1770             }
   1771             settings->userMetaDataMode = value;
   1772             hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
   1773         }
   1774         break;
   1775     default:
   1776       err = AACENC_UNSUPPORTED_PARAMETER;
   1777       break;
   1778     }  /* switch(param) */
   1779 
   1780 bail:
   1781     return err;
   1782 }
   1783 
   1784 UINT aacEncoder_GetParam(
   1785         const HANDLE_AACENCODER   hAacEncoder,
   1786         const AACENC_PARAM        param
   1787         )
   1788 {
   1789     UINT value = 0;
   1790     USER_PARAM *settings = &hAacEncoder->extParam;
   1791 
   1792     /* check encoder handle */
   1793     if (hAacEncoder == NULL) {
   1794         goto bail;
   1795     }
   1796 
   1797     /* apply param value */
   1798     switch (param)
   1799     {
   1800     case AACENC_AOT:
   1801         value = (UINT)hAacEncoder->aacConfig.audioObjectType;
   1802         break;
   1803     case AACENC_BITRATE:
   1804         value = (UINT)((hAacEncoder->aacConfig.bitrateMode==AACENC_BR_MODE_CBR) ? hAacEncoder->aacConfig.bitRate : -1);
   1805         break;
   1806     case AACENC_BITRATEMODE:
   1807         value = (UINT)hAacEncoder->aacConfig.bitrateMode;
   1808         break;
   1809     case AACENC_SAMPLERATE:
   1810         value = (UINT)settings->userSamplerate;
   1811         break;
   1812     case AACENC_CHANNELMODE:
   1813         value = (UINT)hAacEncoder->aacConfig.channelMode;
   1814         break;
   1815     case AACENC_BANDWIDTH:
   1816         value = (UINT)hAacEncoder->aacConfig.bandWidth;
   1817         break;
   1818     case AACENC_CHANNELORDER:
   1819         value = (UINT)hAacEncoder->aacConfig.channelOrder;
   1820         break;
   1821     case AACENC_AFTERBURNER:
   1822         value = (UINT)hAacEncoder->aacConfig.useRequant;
   1823         break;
   1824     case AACENC_GRANULE_LENGTH:
   1825         value = (UINT)hAacEncoder->aacConfig.framelength;
   1826        break;
   1827     case AACENC_SBR_MODE:
   1828         value = (UINT) (hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
   1829         break;
   1830     case AACENC_TRANSMUX:
   1831         value = (UINT)settings->userTpType;
   1832         break;
   1833     case AACENC_SIGNALING_MODE:
   1834         value = (UINT)settings->userTpSignaling;
   1835         break;
   1836     case AACENC_PROTECTION:
   1837         value = (UINT)settings->userTpProtection;
   1838         break;
   1839     case AACENC_HEADER_PERIOD:
   1840         value = (UINT)hAacEncoder->coderConfig.headerPeriod;
   1841         break;
   1842     case AACENC_TPSUBFRAMES:
   1843         value = (UINT)settings->userTpNsubFrames;
   1844         break;
   1845     case AACENC_ANCILLARY_BITRATE:
   1846         value = (UINT)hAacEncoder->aacConfig.anc_Rate;
   1847         break;
   1848     case AACENC_CONTROL_STATE:
   1849         value = (UINT)hAacEncoder->InitFlags;
   1850         break;
   1851     case AACENC_METADATA_MODE:
   1852         value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode;
   1853         break;
   1854     default:
   1855       //err = MPS_INVALID_PARAMETER;
   1856       break;
   1857     }  /* switch(param) */
   1858 
   1859 bail:
   1860     return value;
   1861 }
   1862 
   1863 AACENC_ERROR aacEncInfo(
   1864         const HANDLE_AACENCODER   hAacEncoder,
   1865         AACENC_InfoStruct        *pInfo
   1866         )
   1867 {
   1868     AACENC_ERROR err = AACENC_OK;
   1869 
   1870     FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
   1871     pInfo->confSize = 64; /* pre-initialize */
   1872 
   1873     pInfo->maxOutBufBytes    = ((hAacEncoder->nMaxAacChannels*6144)+7)>>3;
   1874     pInfo->maxAncBytes       = hAacEncoder->aacConfig.maxAncBytesPerAU;
   1875     pInfo->inBufFillLevel    = hAacEncoder->nSamplesRead/hAacEncoder->extParam.nChannels;
   1876     pInfo->inputChannels     = hAacEncoder->extParam.nChannels;
   1877     pInfo->frameLength       = hAacEncoder->nSamplesToRead/hAacEncoder->extParam.nChannels;
   1878     pInfo->encoderDelay      = hAacEncoder->nDelay/hAacEncoder->extParam.nChannels;
   1879 
   1880     /* Get encoder configuration */
   1881     if ( aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) != AAC_ENC_OK) {
   1882         err = AACENC_INIT_ERROR;
   1883         goto bail;
   1884     }
   1885 bail:
   1886     return err;
   1887 }
   1888 
   1889