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