1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5© Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@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 */
129enum {
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////////////////////////////////////////////////////////////////////////////////////
138typedef 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
177typedef struct  AACENC_CONFIG     *HANDLE_AACENC_CONFIG;
178
179
180struct 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
237static 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
260H_ALLOC_MEM (_AacEncoder, AACENCODER)
261C_ALLOC_MEM (_AacEncoder, AACENCODER, 1)
262
263
264
265
266/*
267 * Map Encoder specific config structures to CODER_CONFIG.
268 */
269static
270void 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 */
387static 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
408AAC_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
453static
454void 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
474static
475INT 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 */
594static
595AACENC_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
782static
783INT 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
801static 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
998AACENC_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
1140bail:
1141    aacEncClose(&hAacEncoder);
1142
1143    return err;
1144}
1145
1146
1147
1148AACENC_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
1186bail:
1187    return err;
1188}
1189
1190AACENC_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
1459bail:
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
1468static
1469AAC_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
1500AACENC_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
1540AACENC_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
1780bail:
1781    return err;
1782}
1783
1784UINT 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
1859bail:
1860    return value;
1861}
1862
1863AACENC_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    }
1885bail:
1886    return err;
1887}
1888
1889