• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** AAC encoder library ******************************
96 
97    Author(s):   M. Schug / A. Groeschel
98 
99    Description: fast aac coder functions
100 
101 *******************************************************************************/
102 
103 #include "aacenc.h"
104 
105 #include "bitenc.h"
106 #include "interface.h"
107 #include "psy_configuration.h"
108 #include "psy_main.h"
109 #include "qc_main.h"
110 #include "bandwidth.h"
111 #include "channel_map.h"
112 #include "tns_func.h"
113 #include "aacEnc_ram.h"
114 
115 #include "genericStds.h"
116 
117 #define BITRES_MIN \
118   300 /* default threshold for using reduced/disabled bitres mode */
119 #define BITRES_MAX_LD 4000
120 #define BITRES_MIN_LD 500
121 #define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
122 #define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
123 
FDKaacEnc_CalcBitsPerFrame(const INT bitRate,const INT frameLength,const INT samplingRate)124 INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
125                                const INT samplingRate) {
126   int shift = 0;
127   while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
128          (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
129     shift++;
130   }
131 
132   return (bitRate * (frameLength >> shift)) / (samplingRate >> shift);
133 }
134 
FDKaacEnc_CalcBitrate(const INT bitsPerFrame,const INT frameLength,const INT samplingRate)135 INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
136                           const INT samplingRate) {
137   int shift = 0;
138   while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
139          (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
140     shift++;
141   }
142 
143   return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift);
144 }
145 
146 static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
147     INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
148     INT sampleRate);
149 
FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc,AUDIO_OBJECT_TYPE aot,INT coreSamplingRate,INT frameLength,INT nChannels,INT nChannelsEff,INT bitRate,INT averageBits,INT * pAverageBitsPerFrame,AACENC_BITRATE_MODE bitrateMode,INT nSubFrames)150 INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
151                            INT coreSamplingRate, INT frameLength, INT nChannels,
152                            INT nChannelsEff, INT bitRate, INT averageBits,
153                            INT *pAverageBitsPerFrame,
154                            AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
155   INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
156   INT minBitsPerFrame = 40 * nChannels;
157   if (isLowDelay(aot)) {
158     minBitrate = 8000 * nChannelsEff;
159   }
160 
161   do {
162     prevBitRate = bitRate;
163     averageBitsPerFrame =
164         FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
165         nSubFrames;
166 
167     if (pAverageBitsPerFrame != NULL) {
168       *pAverageBitsPerFrame = averageBitsPerFrame;
169     }
170 
171     if (hTpEnc != NULL) {
172       transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
173     } else {
174       /* Assume some worst case */
175       transportBits = 208;
176     }
177 
178     bitRate = fMax(bitRate,
179                    fMax(minBitrate,
180                         FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
181                                               frameLength, coreSamplingRate)));
182     FDK_ASSERT(bitRate >= 0);
183 
184     bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
185                                 (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
186                                 frameLength, coreSamplingRate));
187     FDK_ASSERT(bitRate >= 0);
188 
189   } while (prevBitRate != bitRate && iter++ < 3);
190 
191   return bitRate;
192 }
193 
194 typedef struct {
195   AACENC_BITRATE_MODE bitrateMode;
196   int chanBitrate[2]; /* mono/stereo settings */
197 } CONFIG_TAB_ENTRY_VBR;
198 
199 static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = {
200     {AACENC_BR_MODE_CBR, {0, 0}},
201     {AACENC_BR_MODE_VBR_1, {32000, 20000}},
202     {AACENC_BR_MODE_VBR_2, {40000, 32000}},
203     {AACENC_BR_MODE_VBR_3, {56000, 48000}},
204     {AACENC_BR_MODE_VBR_4, {72000, 64000}},
205     {AACENC_BR_MODE_VBR_5, {112000, 96000}}};
206 
207 /*-----------------------------------------------------------------------------
208 
209      functionname: FDKaacEnc_GetVBRBitrate
210      description:  Get VBR bitrate from vbr quality
211      input params: int vbrQuality (VBR0, VBR1, VBR2)
212                    channelMode
213      returns:      vbr bitrate
214 
215  ------------------------------------------------------------------------------*/
FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,CHANNEL_MODE channelMode)216 INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
217                             CHANNEL_MODE channelMode) {
218   INT bitrate = 0;
219   INT monoStereoMode = 0; /* default mono */
220 
221   if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
222     monoStereoMode = 1;
223   }
224 
225   switch (bitrateMode) {
226     case AACENC_BR_MODE_VBR_1:
227     case AACENC_BR_MODE_VBR_2:
228     case AACENC_BR_MODE_VBR_3:
229     case AACENC_BR_MODE_VBR_4:
230     case AACENC_BR_MODE_VBR_5:
231       bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
232       break;
233     case AACENC_BR_MODE_INVALID:
234     case AACENC_BR_MODE_CBR:
235     case AACENC_BR_MODE_SFR:
236     case AACENC_BR_MODE_FF:
237     default:
238       bitrate = 0;
239       break;
240   }
241 
242   /* convert channel bitrate to overall bitrate*/
243   bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
244 
245   return bitrate;
246 }
247 
248 /*-----------------------------------------------------------------------------
249 
250     functionname: FDKaacEnc_AdjustVBRBitrateMode
251     description:  Adjust bitrate mode to given bitrate parameter
252     input params: int vbrQuality (VBR0, VBR1, VBR2)
253                   bitrate
254                   channelMode
255     returns:      vbr bitrate mode
256 
257  ------------------------------------------------------------------------------*/
FDKaacEnc_AdjustVBRBitrateMode(AACENC_BITRATE_MODE bitrateMode,INT bitrate,CHANNEL_MODE channelMode)258 AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
259     AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode) {
260   AACENC_BITRATE_MODE newBitrateMode = bitrateMode;
261 
262   if (bitrate != -1) {
263     const INT monoStereoMode =
264         (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) ? 1 : 0;
265     const INT nChannelsEff =
266         FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
267     newBitrateMode = AACENC_BR_MODE_INVALID;
268 
269     for (int idx = (int)(sizeof(configTabVBR) / sizeof(*configTabVBR)) - 1;
270          idx >= 0; idx--) {
271       if (bitrate >=
272           configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff) {
273         if (configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff <
274             FDKaacEnc_GetVBRBitrate(bitrateMode, channelMode)) {
275           newBitrateMode = configTabVBR[idx].bitrateMode;
276         } else {
277           newBitrateMode = bitrateMode;
278         }
279         break;
280       }
281     }
282   }
283 
284   return AACENC_BR_MODE_IS_VBR(newBitrateMode) ? newBitrateMode
285                                                : AACENC_BR_MODE_INVALID;
286 }
287 
288 /**
289  * \brief  Convert encoder bitreservoir value for transport library.
290  *
291  * \param hAacEnc               Encoder handle
292  *
293  * \return  Corrected bitreservoir level used in transport library.
294  */
FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc)295 static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
296   INT transportBitreservoir = 0;
297 
298   switch (hAacEnc->bitrateMode) {
299     case AACENC_BR_MODE_CBR:
300       transportBitreservoir =
301           hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
302       break;
303     case AACENC_BR_MODE_VBR_1:
304     case AACENC_BR_MODE_VBR_2:
305     case AACENC_BR_MODE_VBR_3:
306     case AACENC_BR_MODE_VBR_4:
307     case AACENC_BR_MODE_VBR_5:
308       transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
309       break;
310     case AACENC_BR_MODE_SFR:
311       transportBitreservoir = 0; /* super framing and fixed framing */
312       break;                     /* without bitreservoir signaling */
313     default:
314     case AACENC_BR_MODE_INVALID:
315       transportBitreservoir = 0; /* invalid configuration*/
316   }
317 
318   if (hAacEnc->config->audioMuxVersion == 2) {
319     transportBitreservoir =
320         MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
321   }
322 
323   return transportBitreservoir;
324 }
325 
FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder)326 INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
327   return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
328 }
329 
330 /*-----------------------------------------------------------------------------
331 
332      functionname: FDKaacEnc_AacInitDefaultConfig
333      description:  gives reasonable default configuration
334      returns:      ---
335 
336  ------------------------------------------------------------------------------*/
FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG * config)337 void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
338   /* make the preinitialization of the structs flexible */
339   FDKmemclear(config, sizeof(AACENC_CONFIG));
340 
341   /* default ancillary */
342   config->anc_Rate = 0;       /* no ancillary data */
343   config->ancDataBitRate = 0; /* no additional consumed bitrate */
344 
345   /* default configurations */
346   config->bitRate = -1; /* bitrate must be set*/
347   config->averageBits =
348       -1; /* instead of bitrate/s we can configure bits/superframe */
349   config->bitrateMode =
350       AACENC_BR_MODE_CBR;           /* set bitrate mode to constant bitrate */
351   config->bandWidth = 0;            /* get bandwidth from table */
352   config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
353   config->usePns =
354       1; /* depending on channelBitrate this might be set to 0 later */
355   config->useIS = 1;        /* Intensity Stereo Configuration */
356   config->useMS = 1;        /* MS Stereo tool */
357   config->framelength = -1; /* Framesize not configured */
358   config->syntaxFlags = 0;  /* default syntax with no specialities */
359   config->epConfig = -1;    /* no ER syntax -> no additional error protection */
360   config->nSubFrames = 1;   /* default, no sub frames */
361   config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
362   config->channelMode = MODE_UNKNOWN;
363   config->minBitsPerFrame = -1; /* minum number of bits in each AU */
364   config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
365   config->audioMuxVersion = -1; /* audio mux version not configured */
366   config->downscaleFactor =
367       1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
368 }
369 
370 /*---------------------------------------------------------------------------
371 
372     functionname: FDKaacEnc_Open
373     description:  allocate and initialize a new encoder instance
374     returns:      error code
375 
376   ---------------------------------------------------------------------------*/
FDKaacEnc_Open(HANDLE_AAC_ENC * phAacEnc,const INT nElements,const INT nChannels,const INT nSubFrames)377 AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
378                                  const INT nChannels, const INT nSubFrames) {
379   AAC_ENCODER_ERROR ErrorStatus;
380   AAC_ENC *hAacEnc = NULL;
381   UCHAR *dynamicRAM = NULL;
382 
383   if (phAacEnc == NULL) {
384     return AAC_ENC_INVALID_HANDLE;
385   }
386 
387   /* allocate encoder structure */
388   hAacEnc = GetRam_aacEnc_AacEncoder();
389   if (hAacEnc == NULL) {
390     ErrorStatus = AAC_ENC_NO_MEMORY;
391     goto bail;
392   }
393   FDKmemclear(hAacEnc, sizeof(AAC_ENC));
394 
395   if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
396     ErrorStatus = AAC_ENC_NO_MEMORY;
397     goto bail;
398   }
399   dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;
400 
401   /* allocate the Psy aud Psy Out structure */
402   ErrorStatus =
403       FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
404   if (ErrorStatus != AAC_ENC_OK) goto bail;
405 
406   ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
407                                     nSubFrames, dynamicRAM);
408   if (ErrorStatus != AAC_ENC_OK) goto bail;
409 
410   /* allocate the Q&C Out structure */
411   ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
412                                    nSubFrames, dynamicRAM);
413   if (ErrorStatus != AAC_ENC_OK) goto bail;
414 
415   /* allocate the Q&C kernel */
416   ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
417   if (ErrorStatus != AAC_ENC_OK) goto bail;
418 
419   hAacEnc->maxChannels = nChannels;
420   hAacEnc->maxElements = nElements;
421   hAacEnc->maxFrames = nSubFrames;
422 
423 bail:
424   *phAacEnc = hAacEnc;
425   return ErrorStatus;
426 }
427 
FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,AACENC_CONFIG * config,HANDLE_TRANSPORTENC hTpEnc,ULONG initFlags)428 AAC_ENCODER_ERROR FDKaacEnc_Initialize(
429     HANDLE_AAC_ENC hAacEnc,
430     AACENC_CONFIG *config, /* pre-initialized config struct */
431     HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
432   AAC_ENCODER_ERROR ErrorStatus;
433   INT psyBitrate, tnsMask;  // INT profile = 1;
434   CHANNEL_MAPPING *cm = NULL;
435 
436   INT mbfac_e, qbw;
437   FIXP_DBL mbfac, bw_ratio;
438   QC_INIT qcInit;
439   INT averageBitsPerFrame = 0;
440   const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
441 
442   if (config == NULL) return AAC_ENC_INVALID_HANDLE;
443 
444   /******************* sanity checks *******************/
445 
446   /* check config structure */
447   if (config->nChannels < 1 || config->nChannels > (8)) {
448     return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
449   }
450 
451   /* check sample rate */
452   switch (config->sampleRate) {
453     case 8000:
454     case 11025:
455     case 12000:
456     case 16000:
457     case 22050:
458     case 24000:
459     case 32000:
460     case 44100:
461     case 48000:
462     case 64000:
463     case 88200:
464     case 96000:
465       break;
466     default:
467       return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
468   }
469 
470   /* bitrate has to be set */
471   if (config->bitRate == -1) {
472     return AAC_ENC_UNSUPPORTED_BITRATE;
473   }
474 
475   /* check bit rate */
476 
477   if (FDKaacEnc_LimitBitrate(
478           hTpEnc, config->audioObjectType, config->sampleRate,
479           config->framelength, config->nChannels,
480           FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
481               ->nChannelsEff,
482           config->bitRate, config->averageBits, &averageBitsPerFrame,
483           config->bitrateMode, config->nSubFrames) != config->bitRate &&
484       !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
485     return AAC_ENC_UNSUPPORTED_BITRATE;
486   }
487 
488   if (config->syntaxFlags & AC_ER_VCB11) {
489     return AAC_ENC_UNSUPPORTED_ER_FORMAT;
490   }
491   if (config->syntaxFlags & AC_ER_HCR) {
492     return AAC_ENC_UNSUPPORTED_ER_FORMAT;
493   }
494 
495   /* check frame length */
496   switch (config->framelength) {
497     case 1024:
498       if (isLowDelay(config->audioObjectType)) {
499         return AAC_ENC_INVALID_FRAME_LENGTH;
500       }
501       break;
502     case 128:
503     case 256:
504     case 512:
505     case 120:
506     case 240:
507     case 480:
508       if (!isLowDelay(config->audioObjectType)) {
509         return AAC_ENC_INVALID_FRAME_LENGTH;
510       }
511       break;
512     default:
513       return AAC_ENC_INVALID_FRAME_LENGTH;
514   }
515 
516   if (config->anc_Rate != 0) {
517     ErrorStatus = FDKaacEnc_InitCheckAncillary(
518         config->bitRate, config->framelength, config->anc_Rate,
519         &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
520     if (ErrorStatus != AAC_ENC_OK) goto bail;
521 
522     /* update estimated consumed bitrate */
523     config->ancDataBitRate +=
524         FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
525                               config->framelength, config->sampleRate);
526   }
527 
528   /* maximal allowed DSE bytes in frame */
529   config->maxAncBytesPerAU =
530       fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
531                               (config->bitRate - (config->nChannels * 8000)),
532                               config->framelength, config->sampleRate) >>
533                               3));
534 
535   /* bind config to hAacEnc->config */
536   hAacEnc->config = config;
537 
538   /* set hAacEnc->bitrateMode */
539   hAacEnc->bitrateMode = config->bitrateMode;
540 
541   hAacEnc->encoderMode = config->channelMode;
542 
543   ErrorStatus = FDKaacEnc_InitChannelMapping(
544       hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
545   if (ErrorStatus != AAC_ENC_OK) goto bail;
546 
547   cm = &hAacEnc->channelMapping;
548 
549   ErrorStatus = FDKaacEnc_DetermineBandWidth(
550       config->bandWidth, config->bitRate - config->ancDataBitRate,
551       hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
552       hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
553   if (ErrorStatus != AAC_ENC_OK) goto bail;
554 
555   hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;
556 
557   tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
558   psyBitrate = config->bitRate - config->ancDataBitRate;
559 
560   if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
561     /* Reinitialize psych states in case of channel configuration change ore if
562      * full reset requested. */
563     ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
564                                     hAacEnc->maxFrames, hAacEnc->maxChannels,
565                                     config->audioObjectType, cm);
566     if (ErrorStatus != AAC_ENC_OK) goto bail;
567   }
568 
569   ErrorStatus = FDKaacEnc_psyMainInit(
570       hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
571       config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
572       config->usePns, config->useIS, config->useMS, config->syntaxFlags,
573       initFlags);
574   if (ErrorStatus != AAC_ENC_OK) goto bail;
575 
576   ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
577   if (ErrorStatus != AAC_ENC_OK) goto bail;
578 
579   qcInit.channelMapping = &hAacEnc->channelMapping;
580   qcInit.sceCpe = 0;
581 
582   if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
583     qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
584     qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
585     qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
586     qcInit.maxBits = (config->maxBitsPerFrame != -1)
587                          ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
588                          : qcInit.maxBits;
589     qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7);
590     qcInit.minBits =
591         (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
592     qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
593   } else {
594     INT bitreservoir = -1; /* default bitreservoir size*/
595     if (isLowDelay(config->audioObjectType)) {
596       INT brPerChannel = config->bitRate / config->nChannels;
597       brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
598 
599       /* bitreservoir  =
600        * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
601        */
602       FIXP_DBL slope = fDivNorm(
603           (brPerChannel - BITRATE_MIN_LD),
604           BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */
605       bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
606                      BITRES_MIN_LD;     /* interpolate */
607       bitreservoir = bitreservoir & ~7; /* align to bytes */
608     }
609 
610     int maxBitres;
611     qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
612     maxBitres =
613         (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
614     qcInit.bitRes =
615         (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;
616 
617     qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
618                             ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes);
619     qcInit.maxBits = (config->maxBitsPerFrame != -1)
620                          ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
621                          : qcInit.maxBits;
622     qcInit.maxBits =
623         fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
624                fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7));
625 
626     qcInit.minBits = fixMax(
627         0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes -
628                transportEnc_GetStaticBits(
629                    hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes));
630     qcInit.minBits = (config->minBitsPerFrame != -1)
631                          ? fixMax(qcInit.minBits, config->minBitsPerFrame)
632                          : qcInit.minBits;
633     qcInit.minBits = fixMin(
634         qcInit.minBits, (averageBitsPerFrame -
635                          transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) &
636                             ~7);
637   }
638 
639   qcInit.sampleRate = config->sampleRate;
640   qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
641   qcInit.nSubFrames = config->nSubFrames;
642   qcInit.padding.paddingRest = config->sampleRate;
643 
644   if (qcInit.maxBits - qcInit.averageBits >=
645       ((qcInit.isLowDelay) ? BITRES_MIN_LD : BITRES_MIN) * config->nChannels) {
646     qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
647   } else if (qcInit.maxBits > qcInit.averageBits) {
648     qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
649   } else {
650     qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
651   }
652 
653   /* Configure bitrate distribution strategy. */
654   switch (config->channelMode) {
655     case MODE_1_2:
656     case MODE_1_2_1:
657     case MODE_1_2_2:
658     case MODE_1_2_2_1:
659     case MODE_6_1:
660     case MODE_1_2_2_2_1:
661     case MODE_7_1_BACK:
662     case MODE_7_1_TOP_FRONT:
663     case MODE_7_1_REAR_SURROUND:
664     case MODE_7_1_FRONT_CENTER:
665       qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
666       break;
667     case MODE_1:
668     case MODE_2:
669     default:                          /* all non mpeg defined channel modes */
670       qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
671   }                                   /* config->channelMode */
672 
673   /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
674    * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
675   bw_ratio =
676       fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
677                (FIXP_DBL)(config->sampleRate), &qbw);
678   qcInit.meanPe =
679       fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);
680 
681   /* Calc maxBitFac, scale it to 24 bit accuracy */
682   mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
683                    &mbfac_e);
684   qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));
685 
686   switch (config->bitrateMode) {
687     case AACENC_BR_MODE_CBR:
688       qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
689       break;
690     case AACENC_BR_MODE_VBR_1:
691       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
692       break;
693     case AACENC_BR_MODE_VBR_2:
694       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
695       break;
696     case AACENC_BR_MODE_VBR_3:
697       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
698       break;
699     case AACENC_BR_MODE_VBR_4:
700       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
701       break;
702     case AACENC_BR_MODE_VBR_5:
703       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
704       break;
705     case AACENC_BR_MODE_SFR:
706       qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
707       break;
708     case AACENC_BR_MODE_FF:
709       qcInit.bitrateMode = QCDATA_BR_MODE_FF;
710       break;
711     default:
712       ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
713       goto bail;
714   }
715 
716   qcInit.invQuant = (config->useRequant) ? 2 : 0;
717 
718   /* maxIterations should be set to the maximum number of requantization
719    * iterations that are allowed before the crash recovery functionality is
720    * activated. This setting should be adjusted to the processing power
721    * available, i.e. to the processing power headroom in one frame that is still
722    * left after normal encoding without requantization. Please note that if
723    * activated this functionality is used most likely only in cases where the
724    * encoder is operating beyond recommended settings, i.e. the audio quality is
725    * suboptimal anyway. Activating the crash recovery does not further reduce
726    * audio quality significantly in these cases. */
727   if (isLowDelay(config->audioObjectType)) {
728     qcInit.maxIterations = 2;
729   } else {
730     qcInit.maxIterations = 5;
731   }
732 
733   qcInit.bitrate = config->bitRate - config->ancDataBitRate;
734 
735   qcInit.staticBits = transportEnc_GetStaticBits(
736       hTpEnc, qcInit.averageBits / qcInit.nSubFrames);
737 
738   ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
739   if (ErrorStatus != AAC_ENC_OK) goto bail;
740 
741   /* Map virtual aot's to intern aot used in bitstream writer. */
742   switch (hAacEnc->config->audioObjectType) {
743     case AOT_MP2_AAC_LC:
744       hAacEnc->aot = AOT_AAC_LC;
745       break;
746     case AOT_MP2_SBR:
747       hAacEnc->aot = AOT_SBR;
748       break;
749     default:
750       hAacEnc->aot = hAacEnc->config->audioObjectType;
751   }
752 
753   /* common things */
754 
755   return AAC_ENC_OK;
756 
757 bail:
758 
759   return ErrorStatus;
760 }
761 
762 /*---------------------------------------------------------------------------
763 
764     functionname: FDKaacEnc_EncodeFrame
765     description:  encodes one frame
766     returns:      error code
767 
768   ---------------------------------------------------------------------------*/
FDKaacEnc_EncodeFrame(HANDLE_AAC_ENC hAacEnc,HANDLE_TRANSPORTENC hTpEnc,INT_PCM * RESTRICT inputBuffer,const UINT inputBufferBufSize,INT * nOutBytes,AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS])769 AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
770     HANDLE_AAC_ENC hAacEnc, /* encoder handle */
771     HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer,
772     const UINT inputBufferBufSize, INT *nOutBytes,
773     AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
774   AAC_ENCODER_ERROR ErrorStatus;
775   int el, n, c = 0;
776   UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];
777 
778   CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;
779 
780   PSY_OUT *psyOut = hAacEnc->psyOut[c];
781   QC_OUT *qcOut = hAacEnc->qcOut[c];
782 
783   FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));
784 
785   qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
786   qcOut->staticBits = 0;     /* sum up side info bits of each element */
787   qcOut->totalNoRedPe = 0;   /* sum up PE */
788 
789   /* advance psychoacoustics */
790   for (el = 0; el < cm->nElements; el++) {
791     ELEMENT_INFO elInfo = cm->elInfo[el];
792 
793     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
794         (elInfo.elType == ID_LFE)) {
795       int ch;
796 
797       /* update pointer!*/
798       for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
799         PSY_OUT_CHANNEL *psyOutChan =
800             psyOut->psyOutElement[el]->psyOutChannel[ch];
801         QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];
802 
803         psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
804         psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
805         psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
806         psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
807         psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
808         psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
809       }
810 
811       ErrorStatus = FDKaacEnc_psyMain(
812           elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
813           hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
814           psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
815           cm->elInfo[el].ChannelIndex, cm->nChannels);
816 
817       if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
818 
819       /* FormFactor, Pe and staticBitDemand calculation */
820       ErrorStatus = FDKaacEnc_QCMainPrepare(
821           &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
822           psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
823           hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
824 
825       if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
826 
827       /*-------------------------------------------- */
828 
829       qcOut->qcElement[el]->extBitsUsed = 0;
830       qcOut->qcElement[el]->nExtensions = 0;
831       /* reset extension payload */
832       FDKmemclear(&qcOut->qcElement[el]->extension,
833                   (1) * sizeof(QC_OUT_EXTENSION));
834 
835       for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
836         if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
837             (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
838           int idx = qcOut->qcElement[el]->nExtensions++;
839 
840           qcOut->qcElement[el]->extension[idx].type =
841               extPayload[n].dataType; /* Perform a sanity check on the type? */
842           qcOut->qcElement[el]->extension[idx].nPayloadBits =
843               extPayload[n].dataSize;
844           qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData;
845           /* Now ask the bitstream encoder how many bits we need to encode the
846            * data with the current bitstream syntax: */
847           qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
848               NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
849               hAacEnc->config->syntaxFlags, hAacEnc->aot,
850               hAacEnc->config->epConfig);
851           extPayloadUsed[n] = 1;
852         }
853       }
854 
855       /* sum up extension and static bits for all channel elements */
856       qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
857       qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;
858 
859       /* sum up pe */
860       qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
861     }
862   }
863 
864   qcOut->nExtensions = 0;
865   qcOut->globalExtBits = 0;
866 
867   /* reset extension payload */
868   FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION));
869 
870   /* Add extension payload not assigned to an channel element
871     (Ancillary data is the only supported type up to now) */
872   for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
873     if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
874         (extPayload[n].pData != NULL)) {
875       UINT payloadBits = 0;
876 
877       if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
878         if (hAacEnc->ancillaryBitsPerFrame) {
879           /* granted frame dse bitrate */
880           payloadBits = hAacEnc->ancillaryBitsPerFrame;
881         } else {
882           /* write anc data if bitrate constraint fulfilled */
883           if ((extPayload[n].dataSize >> 3) <=
884               hAacEnc->config->maxAncBytesPerAU) {
885             payloadBits = extPayload[n].dataSize;
886           }
887         }
888         payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
889       } else {
890         payloadBits = extPayload[n].dataSize;
891       }
892 
893       if (payloadBits > 0) {
894         int idx = qcOut->nExtensions++;
895 
896         qcOut->extension[idx].type =
897             extPayload[n].dataType; /* Perform a sanity check on the type? */
898         qcOut->extension[idx].nPayloadBits = payloadBits;
899         qcOut->extension[idx].pPayload = extPayload[n].pData;
900         /* Now ask the bitstream encoder how many bits we need to encode the
901          * data with the current bitstream syntax: */
902         qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
903             NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
904             hAacEnc->aot, hAacEnc->config->epConfig);
905         if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
906           /* substract the processed bits */
907           extPayload[n].dataSize -= payloadBits;
908         }
909         extPayloadUsed[n] = 1;
910       }
911     }
912   }
913 
914   if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
915     qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
916   }
917 
918   /* build bitstream all nSubFrames */
919   {
920     INT totalBits = 0; /* Total AU bits */
921     ;
922     INT avgTotalBits = 0;
923 
924     /*-------------------------------------------- */
925     /* Get average total bits */
926     /*-------------------------------------------- */
927     {
928       /* frame wise bitrate adaption */
929       FDKaacEnc_AdjustBitrate(
930           hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
931           hAacEnc->config->sampleRate, hAacEnc->config->framelength);
932 
933       /* adjust super frame bitrate */
934       avgTotalBits *= hAacEnc->config->nSubFrames;
935     }
936 
937     /* Make first estimate of transport header overhead.
938        Take maximum possible frame size into account to prevent bitreservoir
939        underrun. */
940     hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
941         hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);
942 
943     /*-------------------------------------------- */
944     /*-------------------------------------------- */
945     /*-------------------------------------------- */
946 
947     ErrorStatus = FDKaacEnc_QCMain(
948         hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
949         hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
950 
951     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
952     /*-------------------------------------------- */
953 
954     /*-------------------------------------------- */
955     ErrorStatus = FDKaacEnc_updateFillBits(
956         cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
957     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
958 
959     /*-------------------------------------------- */
960     ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
961         cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
962         hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
963     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
964     /*-------------------------------------------- */
965     totalBits += qcOut->totalBits;
966 
967     /*-------------------------------------------- */
968     FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);
969 
970     /*-------------------------------------------- */
971 
972     /* for ( all sub frames ) ... */
973     /* write bitstream header */
974     if (TRANSPORTENC_OK !=
975         transportEnc_WriteAccessUnit(hTpEnc, totalBits,
976                                      FDKaacEnc_EncBitresToTpBitres(hAacEnc),
977                                      cm->nChannelsEff)) {
978       return AAC_ENC_UNKNOWN;
979     }
980 
981     /* write bitstream */
982     ErrorStatus = FDKaacEnc_WriteBitstream(
983         hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
984         hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
985 
986     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
987 
988     /* transportEnc_EndAccessUnit() is being called inside
989      * FDKaacEnc_WriteBitstream() */
990     if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
991       return AAC_ENC_UNKNOWN;
992     }
993 
994   } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */
995 
996   /*-------------------------------------------- */
997   return AAC_ENC_OK;
998 }
999 
1000 /*---------------------------------------------------------------------------
1001 
1002     functionname:FDKaacEnc_Close
1003     description: delete encoder instance
1004     returns:
1005 
1006   ---------------------------------------------------------------------------*/
1007 
FDKaacEnc_Close(HANDLE_AAC_ENC * phAacEnc)1008 void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
1009 {
1010   if (*phAacEnc == NULL) {
1011     return;
1012   }
1013   AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;
1014 
1015   if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);
1016 
1017   FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);
1018 
1019   FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);
1020 
1021   FreeRam_aacEnc_AacEncoder(phAacEnc);
1022 }
1023 
1024 /* The following functions are in this source file only for convenience and */
1025 /* need not be visible outside of a possible encoder library. */
1026 
1027 /* basic defines for ancillary data */
1028 #define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */
1029 
1030 /*---------------------------------------------------------------------------
1031 
1032     functionname:  FDKaacEnc_InitCheckAncillary
1033     description:   initialize and check ancillary data struct
1034     return:        if success or NULL if error
1035 
1036   ---------------------------------------------------------------------------*/
FDKaacEnc_InitCheckAncillary(INT bitRate,INT framelength,INT ancillaryRate,INT * ancillaryBitsPerFrame,INT sampleRate)1037 static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
1038     INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
1039     INT sampleRate) {
1040   /* don't use negative ancillary rates */
1041   if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1042 
1043   /* check if ancillary rate is ok */
1044   if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
1045     /* ancRate <= 15% of bitrate && ancRate < 19200 */
1046     if ((ancillaryRate >= MAX_ANCRATE) ||
1047         ((ancillaryRate * 20) > (bitRate * 3))) {
1048       return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1049     }
1050   } else if (ancillaryRate == -1) {
1051     /* if no special ancRate is requested but a ancillary file is
1052        stated, then generate a ancillary rate matching to the bitrate */
1053     if (bitRate >= (MAX_ANCRATE * 10)) {
1054       /* ancillary rate is 19199 */
1055       ancillaryRate = (MAX_ANCRATE - 1);
1056     } else { /* 10% of bitrate */
1057       ancillaryRate = bitRate / 10;
1058     }
1059   }
1060 
1061   /* make ancillaryBitsPerFrame byte align */
1062   *ancillaryBitsPerFrame =
1063       FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;
1064 
1065   return AAC_ENC_OK;
1066 }
1067