Coverage Report

Created: 2025-07-01 06:21

/src/aac/libAACenc/src/aacenc.cpp
Line
Count
Source (jump to first uncovered line)
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
0
  300 /* default threshold for using reduced/disabled bitres mode */
119
0
#define BITRES_MAX_LD 4000
120
0
#define BITRES_MIN_LD 500
121
0
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
122
0
#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
123
124
INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
125
0
                               const INT samplingRate) {
126
0
  int shift = 0;
127
0
  while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
128
0
         (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
129
0
    shift++;
130
0
  }
131
132
0
  return (bitRate * (frameLength >> shift)) / (samplingRate >> shift);
133
0
}
134
135
INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
136
0
                          const INT samplingRate) {
137
0
  int shift = 0;
138
0
  while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
139
0
         (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
140
0
    shift++;
141
0
  }
142
143
0
  return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift);
144
0
}
145
146
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
147
    INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
148
    INT sampleRate);
149
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
0
                           AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
155
0
  INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
156
0
  INT minBitsPerFrame = 40 * nChannels;
157
0
  if (isLowDelay(aot)) {
158
0
    minBitrate = 8000 * nChannelsEff;
159
0
  }
160
161
0
  do {
162
0
    prevBitRate = bitRate;
163
0
    averageBitsPerFrame =
164
0
        FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
165
0
        nSubFrames;
166
167
0
    if (pAverageBitsPerFrame != NULL) {
168
0
      *pAverageBitsPerFrame = averageBitsPerFrame;
169
0
    }
170
171
0
    if (hTpEnc != NULL) {
172
0
      transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
173
0
    } else {
174
      /* Assume some worst case */
175
0
      transportBits = 208;
176
0
    }
177
178
0
    bitRate = fMax(bitRate,
179
0
                   fMax(minBitrate,
180
0
                        FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
181
0
                                              frameLength, coreSamplingRate)));
182
0
    FDK_ASSERT(bitRate >= 0);
183
184
0
    bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
185
0
                                (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
186
0
                                frameLength, coreSamplingRate));
187
0
    FDK_ASSERT(bitRate >= 0);
188
189
0
  } while (prevBitRate != bitRate && iter++ < 3);
190
191
0
  return bitRate;
192
0
}
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
 ------------------------------------------------------------------------------*/
216
INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
217
0
                            CHANNEL_MODE channelMode) {
218
0
  INT bitrate = 0;
219
0
  INT monoStereoMode = 0; /* default mono */
220
221
0
  if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
222
0
    monoStereoMode = 1;
223
0
  }
224
225
0
  switch (bitrateMode) {
226
0
    case AACENC_BR_MODE_VBR_1:
227
0
    case AACENC_BR_MODE_VBR_2:
228
0
    case AACENC_BR_MODE_VBR_3:
229
0
    case AACENC_BR_MODE_VBR_4:
230
0
    case AACENC_BR_MODE_VBR_5:
231
0
      bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
232
0
      break;
233
0
    case AACENC_BR_MODE_INVALID:
234
0
    case AACENC_BR_MODE_CBR:
235
0
    case AACENC_BR_MODE_SFR:
236
0
    case AACENC_BR_MODE_FF:
237
0
    default:
238
0
      bitrate = 0;
239
0
      break;
240
0
  }
241
242
  /* convert channel bitrate to overall bitrate*/
243
0
  bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
244
245
0
  return bitrate;
246
0
}
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
 ------------------------------------------------------------------------------*/
258
AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
259
0
    AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode) {
260
0
  AACENC_BITRATE_MODE newBitrateMode = bitrateMode;
261
262
0
  if (bitrate != -1) {
263
0
    const INT monoStereoMode =
264
0
        (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) ? 1 : 0;
265
0
    const INT nChannelsEff =
266
0
        FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
267
0
    newBitrateMode = AACENC_BR_MODE_INVALID;
268
269
0
    for (int idx = (int)(sizeof(configTabVBR) / sizeof(*configTabVBR)) - 1;
270
0
         idx >= 0; idx--) {
271
0
      if (bitrate >=
272
0
          configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff) {
273
0
        if (configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff <
274
0
            FDKaacEnc_GetVBRBitrate(bitrateMode, channelMode)) {
275
0
          newBitrateMode = configTabVBR[idx].bitrateMode;
276
0
        } else {
277
0
          newBitrateMode = bitrateMode;
278
0
        }
279
0
        break;
280
0
      }
281
0
    }
282
0
  }
283
284
0
  return AACENC_BR_MODE_IS_VBR(newBitrateMode) ? newBitrateMode
285
0
                                               : AACENC_BR_MODE_INVALID;
286
0
}
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
 */
295
0
static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
296
0
  INT transportBitreservoir = 0;
297
298
0
  switch (hAacEnc->bitrateMode) {
299
0
    case AACENC_BR_MODE_CBR:
300
0
      transportBitreservoir =
301
0
          hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
302
0
      break;
303
0
    case AACENC_BR_MODE_VBR_1:
304
0
    case AACENC_BR_MODE_VBR_2:
305
0
    case AACENC_BR_MODE_VBR_3:
306
0
    case AACENC_BR_MODE_VBR_4:
307
0
    case AACENC_BR_MODE_VBR_5:
308
0
      transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
309
0
      break;
310
0
    case AACENC_BR_MODE_SFR:
311
0
      transportBitreservoir = 0; /* super framing and fixed framing */
312
0
      break;                     /* without bitreservoir signaling */
313
0
    default:
314
0
    case AACENC_BR_MODE_INVALID:
315
0
      transportBitreservoir = 0; /* invalid configuration*/
316
0
  }
317
318
0
  if (hAacEnc->config->audioMuxVersion == 2) {
319
0
    transportBitreservoir =
320
0
        MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
321
0
  }
322
323
0
  return transportBitreservoir;
324
0
}
325
326
0
INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
327
0
  return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
328
0
}
329
330
/*-----------------------------------------------------------------------------
331
332
     functionname: FDKaacEnc_AacInitDefaultConfig
333
     description:  gives reasonable default configuration
334
     returns:      ---
335
336
 ------------------------------------------------------------------------------*/
337
0
void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
338
  /* make the preinitialization of the structs flexible */
339
0
  FDKmemclear(config, sizeof(AACENC_CONFIG));
340
341
  /* default ancillary */
342
0
  config->anc_Rate = 0;       /* no ancillary data */
343
0
  config->ancDataBitRate = 0; /* no additional consumed bitrate */
344
345
  /* default configurations */
346
0
  config->bitRate = -1; /* bitrate must be set*/
347
0
  config->averageBits =
348
0
      -1; /* instead of bitrate/s we can configure bits/superframe */
349
0
  config->bitrateMode =
350
0
      AACENC_BR_MODE_CBR;           /* set bitrate mode to constant bitrate */
351
0
  config->bandWidth = 0;            /* get bandwidth from table */
352
0
  config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
353
0
  config->usePns =
354
0
      1; /* depending on channelBitrate this might be set to 0 later */
355
0
  config->useIS = 1;        /* Intensity Stereo Configuration */
356
0
  config->useMS = 1;        /* MS Stereo tool */
357
0
  config->framelength = -1; /* Framesize not configured */
358
0
  config->syntaxFlags = 0;  /* default syntax with no specialities */
359
0
  config->epConfig = -1;    /* no ER syntax -> no additional error protection */
360
0
  config->nSubFrames = 1;   /* default, no sub frames */
361
0
  config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
362
0
  config->channelMode = MODE_UNKNOWN;
363
0
  config->minBitsPerFrame = -1; /* minum number of bits in each AU */
364
0
  config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
365
0
  config->audioMuxVersion = -1; /* audio mux version not configured */
366
0
  config->downscaleFactor =
367
0
      1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
368
0
}
369
370
/*---------------------------------------------------------------------------
371
372
    functionname: FDKaacEnc_Open
373
    description:  allocate and initialize a new encoder instance
374
    returns:      error code
375
376
  ---------------------------------------------------------------------------*/
377
AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
378
0
                                 const INT nChannels, const INT nSubFrames) {
379
0
  AAC_ENCODER_ERROR ErrorStatus;
380
0
  AAC_ENC *hAacEnc = NULL;
381
0
  UCHAR *dynamicRAM = NULL;
382
383
0
  if (phAacEnc == NULL) {
384
0
    return AAC_ENC_INVALID_HANDLE;
385
0
  }
386
387
  /* allocate encoder structure */
388
0
  hAacEnc = GetRam_aacEnc_AacEncoder();
389
0
  if (hAacEnc == NULL) {
390
0
    ErrorStatus = AAC_ENC_NO_MEMORY;
391
0
    goto bail;
392
0
  }
393
0
  FDKmemclear(hAacEnc, sizeof(AAC_ENC));
394
395
0
  if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
396
0
    ErrorStatus = AAC_ENC_NO_MEMORY;
397
0
    goto bail;
398
0
  }
399
0
  dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;
400
401
  /* allocate the Psy aud Psy Out structure */
402
0
  ErrorStatus =
403
0
      FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
404
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
405
406
0
  ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
407
0
                                    nSubFrames, dynamicRAM);
408
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
409
410
  /* allocate the Q&C Out structure */
411
0
  ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
412
0
                                   nSubFrames, dynamicRAM);
413
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
414
415
  /* allocate the Q&C kernel */
416
0
  ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
417
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
418
419
0
  hAacEnc->maxChannels = nChannels;
420
0
  hAacEnc->maxElements = nElements;
421
0
  hAacEnc->maxFrames = nSubFrames;
422
423
0
bail:
424
0
  *phAacEnc = hAacEnc;
425
0
  return ErrorStatus;
426
0
}
427
428
AAC_ENCODER_ERROR FDKaacEnc_Initialize(
429
    HANDLE_AAC_ENC hAacEnc,
430
    AACENC_CONFIG *config, /* pre-initialized config struct */
431
0
    HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
432
0
  AAC_ENCODER_ERROR ErrorStatus;
433
0
  INT psyBitrate, tnsMask;  // INT profile = 1;
434
0
  CHANNEL_MAPPING *cm = NULL;
435
436
0
  INT mbfac_e, qbw;
437
0
  FIXP_DBL mbfac, bw_ratio;
438
0
  QC_INIT qcInit;
439
0
  INT averageBitsPerFrame = 0;
440
0
  const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
441
442
0
  if (config == NULL) return AAC_ENC_INVALID_HANDLE;
443
444
  /******************* sanity checks *******************/
445
446
  /* check config structure */
447
0
  if (config->nChannels < 1 || config->nChannels > (8)) {
448
0
    return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
449
0
  }
450
451
  /* check sample rate */
452
0
  switch (config->sampleRate) {
453
0
    case 8000:
454
0
    case 11025:
455
0
    case 12000:
456
0
    case 16000:
457
0
    case 22050:
458
0
    case 24000:
459
0
    case 32000:
460
0
    case 44100:
461
0
    case 48000:
462
0
    case 64000:
463
0
    case 88200:
464
0
    case 96000:
465
0
      break;
466
0
    default:
467
0
      return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
468
0
  }
469
470
  /* bitrate has to be set */
471
0
  if (config->bitRate == -1) {
472
0
    return AAC_ENC_UNSUPPORTED_BITRATE;
473
0
  }
474
475
  /* check bit rate */
476
477
0
  if (FDKaacEnc_LimitBitrate(
478
0
          hTpEnc, config->audioObjectType, config->sampleRate,
479
0
          config->framelength, config->nChannels,
480
0
          FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
481
0
              ->nChannelsEff,
482
0
          config->bitRate, config->averageBits, &averageBitsPerFrame,
483
0
          config->bitrateMode, config->nSubFrames) != config->bitRate &&
484
0
      !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
485
0
    return AAC_ENC_UNSUPPORTED_BITRATE;
486
0
  }
487
488
0
  if (config->syntaxFlags & AC_ER_VCB11) {
489
0
    return AAC_ENC_UNSUPPORTED_ER_FORMAT;
490
0
  }
491
0
  if (config->syntaxFlags & AC_ER_HCR) {
492
0
    return AAC_ENC_UNSUPPORTED_ER_FORMAT;
493
0
  }
494
495
  /* check frame length */
496
0
  switch (config->framelength) {
497
0
    case 1024:
498
0
      if (isLowDelay(config->audioObjectType)) {
499
0
        return AAC_ENC_INVALID_FRAME_LENGTH;
500
0
      }
501
0
      break;
502
0
    case 128:
503
0
    case 256:
504
0
    case 512:
505
0
    case 120:
506
0
    case 240:
507
0
    case 480:
508
0
      if (!isLowDelay(config->audioObjectType)) {
509
0
        return AAC_ENC_INVALID_FRAME_LENGTH;
510
0
      }
511
0
      break;
512
0
    default:
513
0
      return AAC_ENC_INVALID_FRAME_LENGTH;
514
0
  }
515
516
0
  if (config->anc_Rate != 0) {
517
0
    ErrorStatus = FDKaacEnc_InitCheckAncillary(
518
0
        config->bitRate, config->framelength, config->anc_Rate,
519
0
        &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
520
0
    if (ErrorStatus != AAC_ENC_OK) goto bail;
521
522
    /* update estimated consumed bitrate */
523
0
    config->ancDataBitRate +=
524
0
        FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
525
0
                              config->framelength, config->sampleRate);
526
0
  }
527
528
  /* maximal allowed DSE bytes in frame */
529
0
  config->maxAncBytesPerAU =
530
0
      fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
531
0
                              (config->bitRate - (config->nChannels * 8000)),
532
0
                              config->framelength, config->sampleRate) >>
533
0
                              3));
534
535
  /* bind config to hAacEnc->config */
536
0
  hAacEnc->config = config;
537
538
  /* set hAacEnc->bitrateMode */
539
0
  hAacEnc->bitrateMode = config->bitrateMode;
540
541
0
  hAacEnc->encoderMode = config->channelMode;
542
543
0
  ErrorStatus = FDKaacEnc_InitChannelMapping(
544
0
      hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
545
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
546
547
0
  cm = &hAacEnc->channelMapping;
548
549
0
  ErrorStatus = FDKaacEnc_DetermineBandWidth(
550
0
      config->bandWidth, config->bitRate - config->ancDataBitRate,
551
0
      hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
552
0
      hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
553
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
554
555
0
  hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;
556
557
0
  tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
558
0
  psyBitrate = config->bitRate - config->ancDataBitRate;
559
560
0
  if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
561
    /* Reinitialize psych states in case of channel configuration change ore if
562
     * full reset requested. */
563
0
    ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
564
0
                                    hAacEnc->maxFrames, hAacEnc->maxChannels,
565
0
                                    config->audioObjectType, cm);
566
0
    if (ErrorStatus != AAC_ENC_OK) goto bail;
567
0
  }
568
569
0
  ErrorStatus = FDKaacEnc_psyMainInit(
570
0
      hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
571
0
      config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
572
0
      config->usePns, config->useIS, config->useMS, config->syntaxFlags,
573
0
      initFlags);
574
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
575
576
0
  ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
577
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
578
579
0
  qcInit.channelMapping = &hAacEnc->channelMapping;
580
0
  qcInit.sceCpe = 0;
581
582
0
  if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
583
0
    qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
584
0
    qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
585
0
    qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
586
0
    qcInit.maxBits = (config->maxBitsPerFrame != -1)
587
0
                         ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
588
0
                         : qcInit.maxBits;
589
0
    qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7);
590
0
    qcInit.minBits =
591
0
        (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
592
0
    qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
593
0
  } else {
594
0
    INT bitreservoir = -1; /* default bitreservoir size*/
595
0
    if (isLowDelay(config->audioObjectType)) {
596
0
      INT brPerChannel = config->bitRate / config->nChannels;
597
0
      brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
598
599
      /* bitreservoir  =
600
       * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
601
       */
602
0
      FIXP_DBL slope = fDivNorm(
603
0
          (brPerChannel - BITRATE_MIN_LD),
604
0
          BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */
605
0
      bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
606
0
                     BITRES_MIN_LD;     /* interpolate */
607
0
      bitreservoir = bitreservoir & ~7; /* align to bytes */
608
0
    }
609
610
0
    int maxBitres;
611
0
    qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
612
0
    maxBitres =
613
0
        (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
614
0
    qcInit.bitRes =
615
0
        (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;
616
617
0
    qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
618
0
                            ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes);
619
0
    qcInit.maxBits = (config->maxBitsPerFrame != -1)
620
0
                         ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
621
0
                         : qcInit.maxBits;
622
0
    qcInit.maxBits =
623
0
        fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
624
0
               fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7));
625
626
0
    qcInit.minBits = fixMax(
627
0
        0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes -
628
0
               transportEnc_GetStaticBits(
629
0
                   hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes));
630
0
    qcInit.minBits = (config->minBitsPerFrame != -1)
631
0
                         ? fixMax(qcInit.minBits, config->minBitsPerFrame)
632
0
                         : qcInit.minBits;
633
0
    qcInit.minBits = fixMin(
634
0
        qcInit.minBits, (averageBitsPerFrame -
635
0
                         transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) &
636
0
                            ~7);
637
0
  }
638
639
0
  qcInit.sampleRate = config->sampleRate;
640
0
  qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
641
0
  qcInit.nSubFrames = config->nSubFrames;
642
0
  qcInit.padding.paddingRest = config->sampleRate;
643
644
0
  if (qcInit.maxBits - qcInit.averageBits >=
645
0
      ((qcInit.isLowDelay) ? BITRES_MIN_LD : BITRES_MIN) * config->nChannels) {
646
0
    qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
647
0
  } else if (qcInit.maxBits > qcInit.averageBits) {
648
0
    qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
649
0
  } else {
650
0
    qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
651
0
  }
652
653
  /* Configure bitrate distribution strategy. */
654
0
  switch (config->channelMode) {
655
0
    case MODE_1_2:
656
0
    case MODE_1_2_1:
657
0
    case MODE_1_2_2:
658
0
    case MODE_1_2_2_1:
659
0
    case MODE_6_1:
660
0
    case MODE_1_2_2_2_1:
661
0
    case MODE_7_1_BACK:
662
0
    case MODE_7_1_TOP_FRONT:
663
0
    case MODE_7_1_REAR_SURROUND:
664
0
    case MODE_7_1_FRONT_CENTER:
665
0
      qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
666
0
      break;
667
0
    case MODE_1:
668
0
    case MODE_2:
669
0
    default:                          /* all non mpeg defined channel modes */
670
0
      qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
671
0
  }                                   /* config->channelMode */
672
673
  /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
674
   * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
675
0
  bw_ratio =
676
0
      fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
677
0
               (FIXP_DBL)(config->sampleRate), &qbw);
678
0
  qcInit.meanPe =
679
0
      fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);
680
681
  /* Calc maxBitFac, scale it to 24 bit accuracy */
682
0
  mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
683
0
                   &mbfac_e);
684
0
  qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));
685
686
0
  switch (config->bitrateMode) {
687
0
    case AACENC_BR_MODE_CBR:
688
0
      qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
689
0
      break;
690
0
    case AACENC_BR_MODE_VBR_1:
691
0
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
692
0
      break;
693
0
    case AACENC_BR_MODE_VBR_2:
694
0
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
695
0
      break;
696
0
    case AACENC_BR_MODE_VBR_3:
697
0
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
698
0
      break;
699
0
    case AACENC_BR_MODE_VBR_4:
700
0
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
701
0
      break;
702
0
    case AACENC_BR_MODE_VBR_5:
703
0
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
704
0
      break;
705
0
    case AACENC_BR_MODE_SFR:
706
0
      qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
707
0
      break;
708
0
    case AACENC_BR_MODE_FF:
709
0
      qcInit.bitrateMode = QCDATA_BR_MODE_FF;
710
0
      break;
711
0
    default:
712
0
      ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
713
0
      goto bail;
714
0
  }
715
716
0
  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
0
  if (isLowDelay(config->audioObjectType)) {
728
0
    qcInit.maxIterations = 2;
729
0
  } else {
730
0
    qcInit.maxIterations = 5;
731
0
  }
732
733
0
  qcInit.bitrate = config->bitRate - config->ancDataBitRate;
734
735
0
  qcInit.staticBits = transportEnc_GetStaticBits(
736
0
      hTpEnc, qcInit.averageBits / qcInit.nSubFrames);
737
738
0
  ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
739
0
  if (ErrorStatus != AAC_ENC_OK) goto bail;
740
741
  /* Map virtual aot's to intern aot used in bitstream writer. */
742
0
  switch (hAacEnc->config->audioObjectType) {
743
0
    case AOT_MP2_AAC_LC:
744
0
      hAacEnc->aot = AOT_AAC_LC;
745
0
      break;
746
0
    case AOT_MP2_SBR:
747
0
      hAacEnc->aot = AOT_SBR;
748
0
      break;
749
0
    default:
750
0
      hAacEnc->aot = hAacEnc->config->audioObjectType;
751
0
  }
752
753
  /* common things */
754
755
0
  return AAC_ENC_OK;
756
757
0
bail:
758
759
0
  return ErrorStatus;
760
0
}
761
762
/*---------------------------------------------------------------------------
763
764
    functionname: FDKaacEnc_EncodeFrame
765
    description:  encodes one frame
766
    returns:      error code
767
768
  ---------------------------------------------------------------------------*/
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
0
    AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
774
0
  AAC_ENCODER_ERROR ErrorStatus;
775
0
  int el, n, c = 0;
776
0
  UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];
777
778
0
  CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;
779
780
0
  PSY_OUT *psyOut = hAacEnc->psyOut[c];
781
0
  QC_OUT *qcOut = hAacEnc->qcOut[c];
782
783
0
  FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));
784
785
0
  qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
786
0
  qcOut->staticBits = 0;     /* sum up side info bits of each element */
787
0
  qcOut->totalNoRedPe = 0;   /* sum up PE */
788
789
  /* advance psychoacoustics */
790
0
  for (el = 0; el < cm->nElements; el++) {
791
0
    ELEMENT_INFO elInfo = cm->elInfo[el];
792
793
0
    if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
794
0
        (elInfo.elType == ID_LFE)) {
795
0
      int ch;
796
797
      /* update pointer!*/
798
0
      for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
799
0
        PSY_OUT_CHANNEL *psyOutChan =
800
0
            psyOut->psyOutElement[el]->psyOutChannel[ch];
801
0
        QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];
802
803
0
        psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
804
0
        psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
805
0
        psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
806
0
        psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
807
0
        psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
808
0
        psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
809
0
      }
810
811
0
      ErrorStatus = FDKaacEnc_psyMain(
812
0
          elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
813
0
          hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
814
0
          psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
815
0
          cm->elInfo[el].ChannelIndex, cm->nChannels);
816
817
0
      if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
818
819
      /* FormFactor, Pe and staticBitDemand calculation */
820
0
      ErrorStatus = FDKaacEnc_QCMainPrepare(
821
0
          &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
822
0
          psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
823
0
          hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
824
825
0
      if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
826
827
      /*-------------------------------------------- */
828
829
0
      qcOut->qcElement[el]->extBitsUsed = 0;
830
0
      qcOut->qcElement[el]->nExtensions = 0;
831
      /* reset extension payload */
832
0
      FDKmemclear(&qcOut->qcElement[el]->extension,
833
0
                  (1) * sizeof(QC_OUT_EXTENSION));
834
835
0
      for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
836
0
        if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
837
0
            (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
838
0
          int idx = qcOut->qcElement[el]->nExtensions++;
839
840
0
          qcOut->qcElement[el]->extension[idx].type =
841
0
              extPayload[n].dataType; /* Perform a sanity check on the type? */
842
0
          qcOut->qcElement[el]->extension[idx].nPayloadBits =
843
0
              extPayload[n].dataSize;
844
0
          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
0
          qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
848
0
              NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
849
0
              hAacEnc->config->syntaxFlags, hAacEnc->aot,
850
0
              hAacEnc->config->epConfig);
851
0
          extPayloadUsed[n] = 1;
852
0
        }
853
0
      }
854
855
      /* sum up extension and static bits for all channel elements */
856
0
      qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
857
0
      qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;
858
859
      /* sum up pe */
860
0
      qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
861
0
    }
862
0
  }
863
864
0
  qcOut->nExtensions = 0;
865
0
  qcOut->globalExtBits = 0;
866
867
  /* reset extension payload */
868
0
  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
0
  for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
873
0
    if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
874
0
        (extPayload[n].pData != NULL)) {
875
0
      UINT payloadBits = 0;
876
877
0
      if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
878
0
        if (hAacEnc->ancillaryBitsPerFrame) {
879
          /* granted frame dse bitrate */
880
0
          payloadBits = hAacEnc->ancillaryBitsPerFrame;
881
0
        } else {
882
          /* write anc data if bitrate constraint fulfilled */
883
0
          if ((extPayload[n].dataSize >> 3) <=
884
0
              hAacEnc->config->maxAncBytesPerAU) {
885
0
            payloadBits = extPayload[n].dataSize;
886
0
          }
887
0
        }
888
0
        payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
889
0
      } else {
890
0
        payloadBits = extPayload[n].dataSize;
891
0
      }
892
893
0
      if (payloadBits > 0) {
894
0
        int idx = qcOut->nExtensions++;
895
896
0
        qcOut->extension[idx].type =
897
0
            extPayload[n].dataType; /* Perform a sanity check on the type? */
898
0
        qcOut->extension[idx].nPayloadBits = payloadBits;
899
0
        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
0
        qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
903
0
            NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
904
0
            hAacEnc->aot, hAacEnc->config->epConfig);
905
0
        if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
906
          /* substract the processed bits */
907
0
          extPayload[n].dataSize -= payloadBits;
908
0
        }
909
0
        extPayloadUsed[n] = 1;
910
0
      }
911
0
    }
912
0
  }
913
914
0
  if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
915
0
    qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
916
0
  }
917
918
  /* build bitstream all nSubFrames */
919
0
  {
920
0
    INT totalBits = 0; /* Total AU bits */
921
0
    ;
922
0
    INT avgTotalBits = 0;
923
924
    /*-------------------------------------------- */
925
    /* Get average total bits */
926
    /*-------------------------------------------- */
927
0
    {
928
      /* frame wise bitrate adaption */
929
0
      FDKaacEnc_AdjustBitrate(
930
0
          hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
931
0
          hAacEnc->config->sampleRate, hAacEnc->config->framelength);
932
933
      /* adjust super frame bitrate */
934
0
      avgTotalBits *= hAacEnc->config->nSubFrames;
935
0
    }
936
937
    /* Make first estimate of transport header overhead.
938
       Take maximum possible frame size into account to prevent bitreservoir
939
       underrun. */
940
0
    hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
941
0
        hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);
942
943
    /*-------------------------------------------- */
944
    /*-------------------------------------------- */
945
    /*-------------------------------------------- */
946
947
0
    ErrorStatus = FDKaacEnc_QCMain(
948
0
        hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
949
0
        hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
950
951
0
    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
952
    /*-------------------------------------------- */
953
954
    /*-------------------------------------------- */
955
0
    ErrorStatus = FDKaacEnc_updateFillBits(
956
0
        cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
957
0
    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
958
959
    /*-------------------------------------------- */
960
0
    ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
961
0
        cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
962
0
        hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
963
0
    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
964
    /*-------------------------------------------- */
965
0
    totalBits += qcOut->totalBits;
966
967
    /*-------------------------------------------- */
968
0
    FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);
969
970
    /*-------------------------------------------- */
971
972
    /* for ( all sub frames ) ... */
973
    /* write bitstream header */
974
0
    if (TRANSPORTENC_OK !=
975
0
        transportEnc_WriteAccessUnit(hTpEnc, totalBits,
976
0
                                     FDKaacEnc_EncBitresToTpBitres(hAacEnc),
977
0
                                     cm->nChannelsEff)) {
978
0
      return AAC_ENC_UNKNOWN;
979
0
    }
980
981
    /* write bitstream */
982
0
    ErrorStatus = FDKaacEnc_WriteBitstream(
983
0
        hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
984
0
        hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
985
986
0
    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
987
988
    /* transportEnc_EndAccessUnit() is being called inside
989
     * FDKaacEnc_WriteBitstream() */
990
0
    if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
991
0
      return AAC_ENC_UNKNOWN;
992
0
    }
993
994
0
  } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */
995
996
  /*-------------------------------------------- */
997
0
  return AAC_ENC_OK;
998
0
}
999
1000
/*---------------------------------------------------------------------------
1001
1002
    functionname:FDKaacEnc_Close
1003
    description: delete encoder instance
1004
    returns:
1005
1006
  ---------------------------------------------------------------------------*/
1007
1008
void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
1009
0
{
1010
0
  if (*phAacEnc == NULL) {
1011
0
    return;
1012
0
  }
1013
0
  AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;
1014
1015
0
  if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);
1016
1017
0
  FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);
1018
1019
0
  FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);
1020
1021
0
  FreeRam_aacEnc_AacEncoder(phAacEnc);
1022
0
}
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
0
#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
  ---------------------------------------------------------------------------*/
1037
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
1038
    INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
1039
0
    INT sampleRate) {
1040
  /* don't use negative ancillary rates */
1041
0
  if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1042
1043
  /* check if ancillary rate is ok */
1044
0
  if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
1045
    /* ancRate <= 15% of bitrate && ancRate < 19200 */
1046
0
    if ((ancillaryRate >= MAX_ANCRATE) ||
1047
0
        ((ancillaryRate * 20) > (bitRate * 3))) {
1048
0
      return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1049
0
    }
1050
0
  } 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
0
    if (bitRate >= (MAX_ANCRATE * 10)) {
1054
      /* ancillary rate is 19199 */
1055
0
      ancillaryRate = (MAX_ANCRATE - 1);
1056
0
    } else { /* 10% of bitrate */
1057
0
      ancillaryRate = bitRate / 10;
1058
0
    }
1059
0
  }
1060
1061
  /* make ancillaryBitsPerFrame byte align */
1062
0
  *ancillaryBitsPerFrame =
1063
0
      FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;
1064
1065
0
  return AAC_ENC_OK;
1066
0
}