Coverage Report

Created: 2025-07-23 06:37

/src/aac/libAACenc/src/qc_main.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. Werner
98
99
   Description: Quantizing & coding
100
101
*******************************************************************************/
102
103
#include "qc_main.h"
104
#include "quantize.h"
105
#include "interface.h"
106
#include "adj_thr.h"
107
#include "sf_estim.h"
108
#include "bit_cnt.h"
109
#include "dyn_bits.h"
110
#include "channel_map.h"
111
#include "aacEnc_ram.h"
112
113
#include "genericStds.h"
114
115
0
#define AACENC_DZQ_BR_THR 32000 /* Dead zone quantizer bitrate threshold */
116
117
typedef struct {
118
  QCDATA_BR_MODE bitrateMode;
119
  LONG vbrQualFactor;
120
} TAB_VBR_QUAL_FACTOR;
121
122
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
123
    {QCDATA_BR_MODE_VBR_1,
124
     FL2FXCONST_DBL(0.150f)}, /* Approx.  32 kbps mono   AAC-LC + SBR + PS */
125
    {QCDATA_BR_MODE_VBR_2,
126
     FL2FXCONST_DBL(0.162f)}, /* Approx.  64 kbps stereo AAC-LC + SBR      */
127
    {QCDATA_BR_MODE_VBR_3,
128
     FL2FXCONST_DBL(0.176f)}, /* Approx.  96 kbps stereo AAC-LC            */
129
    {QCDATA_BR_MODE_VBR_4,
130
     FL2FXCONST_DBL(0.120f)}, /* Approx. 128 kbps stereo AAC-LC            */
131
    {QCDATA_BR_MODE_VBR_5,
132
     FL2FXCONST_DBL(0.070f)} /* Approx. 192 kbps stereo AAC-LC            */
133
};
134
135
0
static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
136
0
  return (((bitrateMode == QCDATA_BR_MODE_CBR) ||
137
0
           (bitrateMode == QCDATA_BR_MODE_SFR) ||
138
0
           (bitrateMode == QCDATA_BR_MODE_FF))
139
0
              ? 1
140
0
              : 0);
141
0
}
142
143
typedef enum {
144
  FRAME_LEN_BYTES_MODULO = 1,
145
  FRAME_LEN_BYTES_INT = 2
146
} FRAME_LEN_RESULT_MODE;
147
148
/* forward declarations */
149
150
static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
151
                                       INT sfbPerGroup, INT* RESTRICT sfbOffset,
152
                                       SHORT* RESTRICT quantSpectrum,
153
                                       UINT* RESTRICT maxValue);
154
155
static void FDKaacEnc_crashRecovery(INT nChannels,
156
                                    PSY_OUT_ELEMENT* psyOutElement,
157
                                    QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
158
                                    INT bitsToSave, AUDIO_OBJECT_TYPE aot,
159
                                    UINT syntaxFlags, SCHAR epConfig);
160
161
static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
162
    int* iterations, const int maxIterations, int gainAdjustment,
163
    int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
164
    PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
165
    ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
166
    SCHAR epConfig);
167
168
void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC);
169
170
/*****************************************************************************
171
172
    functionname: FDKaacEnc_calcFrameLen
173
    description:
174
    returns:
175
    input:
176
    output:
177
178
*****************************************************************************/
179
static INT FDKaacEnc_calcFrameLen(INT bitRate, INT sampleRate,
180
                                  INT granuleLength,
181
0
                                  FRAME_LEN_RESULT_MODE mode) {
182
0
  INT result;
183
184
0
  result = ((granuleLength) >> 3) * (bitRate);
185
186
0
  switch (mode) {
187
0
    case FRAME_LEN_BYTES_MODULO:
188
0
      result %= sampleRate;
189
0
      break;
190
0
    case FRAME_LEN_BYTES_INT:
191
0
      result /= sampleRate;
192
0
      break;
193
0
  }
194
0
  return (result);
195
0
}
196
197
/*****************************************************************************
198
199
    functionname:FDKaacEnc_framePadding
200
    description: Calculates if padding is needed for actual frame
201
    returns:
202
    input:
203
    output:
204
205
*****************************************************************************/
206
static INT FDKaacEnc_framePadding(INT bitRate, INT sampleRate,
207
0
                                  INT granuleLength, INT* paddingRest) {
208
0
  INT paddingOn;
209
0
  INT difference;
210
211
0
  paddingOn = 0;
212
213
0
  difference = FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
214
0
                                      FRAME_LEN_BYTES_MODULO);
215
0
  *paddingRest -= difference;
216
217
0
  if (*paddingRest <= 0) {
218
0
    paddingOn = 1;
219
0
    *paddingRest += sampleRate;
220
0
  }
221
222
0
  return (paddingOn);
223
0
}
224
225
/*********************************************************************************
226
227
         functionname: FDKaacEnc_QCOutNew
228
         description:
229
         return:
230
231
**********************************************************************************/
232
AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT** phQC, const INT nElements,
233
                                     const INT nChannels, const INT nSubFrames,
234
0
                                     UCHAR* dynamic_RAM) {
235
0
  AAC_ENCODER_ERROR ErrorStatus;
236
0
  int n, i;
237
0
  int elInc = 0, chInc = 0;
238
239
0
  for (n = 0; n < nSubFrames; n++) {
240
0
    phQC[n] = GetRam_aacEnc_QCout(n);
241
0
    if (phQC[n] == NULL) {
242
0
      ErrorStatus = AAC_ENC_NO_MEMORY;
243
0
      goto QCOutNew_bail;
244
0
    }
245
246
0
    for (i = 0; i < nChannels; i++) {
247
0
      phQC[n]->pQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM);
248
0
      if (phQC[n]->pQcOutChannels[i] == NULL) {
249
0
        ErrorStatus = AAC_ENC_NO_MEMORY;
250
0
        goto QCOutNew_bail;
251
0
      }
252
253
0
      chInc++;
254
0
    } /* nChannels */
255
256
0
    for (i = 0; i < nElements; i++) {
257
0
      phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc);
258
0
      if (phQC[n]->qcElement[i] == NULL) {
259
0
        ErrorStatus = AAC_ENC_NO_MEMORY;
260
0
        goto QCOutNew_bail;
261
0
      }
262
0
      elInc++;
263
264
      /* initialize pointer to dynamic buffer which are used in adjust
265
       * thresholds */
266
0
      phQC[n]->qcElement[i]->dynMem_Ah_Flag = dynamic_RAM + (P_BUF_1);
267
0
      phQC[n]->qcElement[i]->dynMem_Thr_Exp =
268
0
          dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE;
269
0
      phQC[n]->qcElement[i]->dynMem_SfbNActiveLinesLdData =
270
0
          dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE;
271
272
0
    } /* nElements */
273
274
0
  } /* nSubFrames */
275
276
0
  return AAC_ENC_OK;
277
278
0
QCOutNew_bail:
279
0
  return ErrorStatus;
280
0
}
281
282
/*********************************************************************************
283
284
         functionname: FDKaacEnc_QCOutInit
285
         description:
286
         return:
287
288
**********************************************************************************/
289
AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT* phQC[(1)], const INT nSubFrames,
290
0
                                      const CHANNEL_MAPPING* cm) {
291
0
  INT n, i, ch;
292
293
0
  for (n = 0; n < nSubFrames; n++) {
294
0
    INT chInc = 0;
295
0
    for (i = 0; i < cm->nElements; i++) {
296
0
      for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
297
0
        phQC[n]->qcElement[i]->qcOutChannel[ch] =
298
0
            phQC[n]->pQcOutChannels[chInc];
299
0
        chInc++;
300
0
      } /* chInEl */
301
0
    }   /* nElements */
302
0
  }     /* nSubFrames */
303
304
0
  return AAC_ENC_OK;
305
0
}
306
307
/*********************************************************************************
308
309
         functionname: FDKaacEnc_QCNew
310
         description:
311
         return:
312
313
**********************************************************************************/
314
AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE** phQC, INT nElements,
315
0
                                  UCHAR* dynamic_RAM) {
316
0
  AAC_ENCODER_ERROR ErrorStatus;
317
0
  int i;
318
319
0
  QC_STATE* hQC = GetRam_aacEnc_QCstate();
320
0
  *phQC = hQC;
321
0
  if (hQC == NULL) {
322
0
    ErrorStatus = AAC_ENC_NO_MEMORY;
323
0
    goto QCNew_bail;
324
0
  }
325
326
0
  if (FDKaacEnc_AdjThrNew(&hQC->hAdjThr, nElements)) {
327
0
    ErrorStatus = AAC_ENC_NO_MEMORY;
328
0
    goto QCNew_bail;
329
0
  }
330
331
0
  if (FDKaacEnc_BCNew(&(hQC->hBitCounter), dynamic_RAM)) {
332
0
    ErrorStatus = AAC_ENC_NO_MEMORY;
333
0
    goto QCNew_bail;
334
0
  }
335
336
0
  for (i = 0; i < nElements; i++) {
337
0
    hQC->elementBits[i] = GetRam_aacEnc_ElementBits(i);
338
0
    if (hQC->elementBits[i] == NULL) {
339
0
      ErrorStatus = AAC_ENC_NO_MEMORY;
340
0
      goto QCNew_bail;
341
0
    }
342
0
  }
343
344
0
  return AAC_ENC_OK;
345
346
0
QCNew_bail:
347
0
  FDKaacEnc_QCClose(phQC, NULL);
348
0
  return ErrorStatus;
349
0
}
350
351
/*********************************************************************************
352
353
         functionname: FDKaacEnc_QCInit
354
         description:
355
         return:
356
357
**********************************************************************************/
358
AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init,
359
0
                                   const ULONG initFlags) {
360
0
  AAC_ENCODER_ERROR err = AAC_ENC_OK;
361
362
0
  int i;
363
0
  hQC->maxBitsPerFrame = init->maxBits;
364
0
  hQC->minBitsPerFrame = init->minBits;
365
0
  hQC->nElements = init->channelMapping->nElements;
366
0
  if ((initFlags != 0) || ((init->bitrateMode != QCDATA_BR_MODE_FF) &&
367
0
                           (hQC->bitResTotMax != init->bitRes))) {
368
0
    hQC->bitResTot = init->bitRes;
369
0
  }
370
0
  hQC->bitResTotMax = init->bitRes;
371
0
  hQC->maxBitFac = init->maxBitFac;
372
0
  hQC->bitrateMode = init->bitrateMode;
373
0
  hQC->invQuant = init->invQuant;
374
0
  hQC->maxIterations = init->maxIterations;
375
376
  /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
377
0
  hQC->bitResMode = init->bitResMode;
378
379
0
  hQC->padding.paddingRest = init->padding.paddingRest;
380
381
0
  hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */
382
383
0
  err = FDKaacEnc_InitElementBits(
384
0
      hQC, init->channelMapping, init->bitrate,
385
0
      (init->averageBits / init->nSubFrames) - hQC->globHdrBits,
386
0
      hQC->maxBitsPerFrame / init->channelMapping->nChannelsEff);
387
0
  if (err != AAC_ENC_OK) goto bail;
388
389
0
  hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
390
0
  for (i = 0;
391
0
       i < (int)(sizeof(tableVbrQualFactor) / sizeof(TAB_VBR_QUAL_FACTOR));
392
0
       i++) {
393
0
    if (hQC->bitrateMode == tableVbrQualFactor[i].bitrateMode) {
394
0
      hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor;
395
0
      break;
396
0
    }
397
0
  }
398
399
0
  if (init->channelMapping->nChannelsEff == 1 &&
400
0
      (init->bitrate / init->channelMapping->nChannelsEff) <
401
0
          AACENC_DZQ_BR_THR &&
402
0
      init->isLowDelay !=
403
0
          0) /* watch out here: init->bitrate is the bitrate "minus" the
404
                standard SBR bitrate (=2500kbps) --> for the FDK the OFFSTE
405
                tuning should start somewhere below 32000kbps-2500kbps ... so
406
                everything is fine here */
407
0
  {
408
0
    hQC->dZoneQuantEnable = 1;
409
0
  } else {
410
0
    hQC->dZoneQuantEnable = 0;
411
0
  }
412
413
0
  FDKaacEnc_AdjThrInit(
414
0
      hQC->hAdjThr, init->meanPe, hQC->invQuant, init->channelMapping,
415
0
      init->sampleRate, /* output sample rate */
416
0
      init->bitrate,    /* total bitrate */
417
0
      init->isLowDelay, /* if set, calc bits2PE factor
418
                           depending on samplerate */
419
0
      init->bitResMode  /* for a small bitreservoir, the pe
420
                           correction is calc'd differently */
421
0
      ,
422
0
      hQC->dZoneQuantEnable, init->bitDistributionMode, hQC->vbrQualFactor);
423
424
0
bail:
425
0
  return err;
426
0
}
427
428
/*********************************************************************************
429
430
         functionname: FDKaacEnc_QCMainPrepare
431
         description:
432
         return:
433
434
**********************************************************************************/
435
AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(
436
    ELEMENT_INFO* elInfo, ATS_ELEMENT* RESTRICT adjThrStateElement,
437
    PSY_OUT_ELEMENT* RESTRICT psyOutElement,
438
    QC_OUT_ELEMENT* RESTRICT qcOutElement, AUDIO_OBJECT_TYPE aot,
439
0
    UINT syntaxFlags, SCHAR epConfig) {
440
0
  AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
441
0
  INT nChannels = elInfo->nChannelsInEl;
442
443
0
  PSY_OUT_CHANNEL** RESTRICT psyOutChannel =
444
0
      psyOutElement->psyOutChannel; /* may be modified in-place */
445
446
0
  FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel,
447
0
                           nChannels);
448
449
  /* prepare and calculate PE without reduction */
450
0
  FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel,
451
0
                          qcOutElement->qcOutChannel, &psyOutElement->toolsInfo,
452
0
                          adjThrStateElement, nChannels);
453
454
0
  ErrorStatus = FDKaacEnc_ChannelElementWrite(
455
0
      NULL, elInfo, NULL, psyOutElement, psyOutElement->psyOutChannel,
456
0
      syntaxFlags, aot, epConfig, &qcOutElement->staticBitsUsed, 0);
457
458
0
  return ErrorStatus;
459
0
}
460
461
/*********************************************************************************
462
463
         functionname: FDKaacEnc_AdjustBitrate
464
         description:  adjusts framelength via padding on a frame to frame
465
basis, to achieve a bitrate that demands a non byte aligned framelength return:
466
errorcode
467
468
**********************************************************************************/
469
AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(
470
    QC_STATE* RESTRICT hQC, CHANNEL_MAPPING* RESTRICT cm, INT* avgTotalBits,
471
    INT bitRate,       /* total bitrate */
472
    INT sampleRate,    /* output sampling rate */
473
    INT granuleLength) /* frame length */
474
0
{
475
0
  INT paddingOn;
476
0
  INT frameLen;
477
478
  /* Do we need an extra padding byte? */
479
0
  paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength,
480
0
                                     &hQC->padding.paddingRest);
481
482
0
  frameLen =
483
0
      paddingOn + FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
484
0
                                         FRAME_LEN_BYTES_INT);
485
486
0
  *avgTotalBits = frameLen << 3;
487
488
0
  return AAC_ENC_OK;
489
0
}
490
491
#define isAudioElement(elType) \
492
0
  ((elType == ID_SCE) || (elType == ID_CPE) || (elType == ID_LFE))
493
494
/*********************************************************************************
495
496
         functionname: FDKaacEnc_distributeElementDynBits
497
         description:  distributes all bits over all elements. The relative bit
498
                       distibution is described in the ELEMENT_INFO of the
499
                       appropriate element. The bit distribution table is
500
                       initialized in FDKaacEnc_InitChannelMapping().
501
         return:       errorcode
502
503
**********************************************************************************/
504
static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(
505
    QC_STATE* hQC, QC_OUT_ELEMENT* qcElement[((8))], CHANNEL_MAPPING* cm,
506
0
    INT codeBits) {
507
0
  INT i;             /* counter variable */
508
0
  INT totalBits = 0; /* sum of bits over all elements */
509
510
0
  for (i = (cm->nElements - 1); i >= 0; i--) {
511
0
    if (isAudioElement(cm->elInfo[i].elType)) {
512
0
      qcElement[i]->grantedDynBits =
513
0
          fMax(0, fMultI(hQC->elementBits[i]->relativeBitsEl, codeBits));
514
0
      totalBits += qcElement[i]->grantedDynBits;
515
0
    }
516
0
  }
517
518
  /* Due to inaccuracies with the multiplication, codeBits may differ from
519
     totalBits. For that case, the difference must be added/substracted again
520
     to/from one element, i.e:
521
     Negative differences are substracted from the element with the most bits.
522
     Positive differences are added to the element with the least bits.
523
  */
524
0
  if (codeBits != totalBits) {
525
0
    INT elMaxBits = cm->nElements - 1; /* element with the most bits */
526
0
    INT elMinBits = cm->nElements - 1; /* element with the least bits */
527
528
    /* Search for biggest and smallest audio element */
529
0
    for (i = (cm->nElements - 1); i >= 0; i--) {
530
0
      if (isAudioElement(cm->elInfo[i].elType)) {
531
0
        if (qcElement[i]->grantedDynBits >
532
0
            qcElement[elMaxBits]->grantedDynBits) {
533
0
          elMaxBits = i;
534
0
        }
535
0
        if (qcElement[i]->grantedDynBits <
536
0
            qcElement[elMinBits]->grantedDynBits) {
537
0
          elMinBits = i;
538
0
        }
539
0
      }
540
0
    }
541
    /* Compensate for bit distibution difference */
542
0
    if (codeBits - totalBits > 0) {
543
0
      qcElement[elMinBits]->grantedDynBits += codeBits - totalBits;
544
0
    } else {
545
0
      qcElement[elMaxBits]->grantedDynBits += codeBits - totalBits;
546
0
    }
547
0
  }
548
549
0
  return AAC_ENC_OK;
550
0
}
551
552
/**
553
 * \brief  Verify whether minBitsPerFrame criterion can be satisfied.
554
 *
555
 * This function evaluates the bit consumption only if minBitsPerFrame parameter
556
 * is not 0. In hyperframing mode the difference between grantedDynBits and
557
 * usedDynBits of all sub frames results the number of fillbits to be written.
558
 * This bits can be distrubitued in superframe to reach minBitsPerFrame bit
559
 * consumption in single AU's. The return value denotes if enough desired fill
560
 * bits are available to achieve minBitsPerFrame in all frames. This check can
561
 * only be used within superframes.
562
 *
563
 * \param qcOut            Pointer to coding data struct.
564
 * \param minBitsPerFrame  Minimal number of bits to be consumed in each frame.
565
 * \param nSubFrames       Number of frames in superframe
566
 *
567
 * \return
568
 *          - 1: all fine
569
 *          - 0: criterion not fulfilled
570
 */
571
static int checkMinFrameBitsDemand(QC_OUT** qcOut, const INT minBitsPerFrame,
572
0
                                   const INT nSubFrames) {
573
0
  int result = 1; /* all fine*/
574
0
  return result;
575
0
}
576
577
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
578
579
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
580
/*********************************************************************************
581
582
         functionname: FDKaacEnc_getMinimalStaticBitdemand
583
         description:  calculate minmal size of static bits by reduction ,
584
                       to zero spectrum and deactivating tns and MS
585
         return:       number of static bits
586
587
**********************************************************************************/
588
static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm,
589
0
                                               PSY_OUT** psyOut) {
590
0
  AUDIO_OBJECT_TYPE aot = AOT_AAC_LC;
591
0
  UINT syntaxFlags = 0;
592
0
  SCHAR epConfig = -1;
593
0
  int i, bitcount = 0;
594
595
0
  for (i = 0; i < cm->nElements; i++) {
596
0
    ELEMENT_INFO elInfo = cm->elInfo[i];
597
598
0
    if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
599
0
        (elInfo.elType == ID_LFE)) {
600
0
      INT minElBits = 0;
601
602
0
      FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL,
603
0
                                    psyOut[0]->psyOutElement[i],
604
0
                                    psyOut[0]->psyOutElement[i]->psyOutChannel,
605
0
                                    syntaxFlags, aot, epConfig, &minElBits, 1);
606
0
      bitcount += minElBits;
607
0
    }
608
0
  }
609
610
0
  return bitcount;
611
0
}
612
613
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
614
615
static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(
616
    QC_STATE* hQC, PSY_OUT** psyOut, QC_OUT** qcOut, CHANNEL_MAPPING* cm,
617
    QC_OUT_ELEMENT* qcElement[(1)][((8))], INT avgTotalBits,
618
0
    INT* totalAvailableBits, INT* avgTotalDynBits) {
619
0
  int i;
620
  /* get maximal allowed dynamic bits */
621
0
  qcOut[0]->grantedDynBits =
622
0
      (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits) & ~7;
623
0
  qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
624
0
                               qcOut[0]->elementExtBits);
625
0
  qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame) & ~7) -
626
0
                         (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
627
0
                          qcOut[0]->elementExtBits);
628
  /* assure that enough bits are available */
629
0
  if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < 0) {
630
    /* crash recovery allows to reduce static bits to a minimum */
631
0
    if ((qcOut[0]->grantedDynBits + hQC->bitResTot) <
632
0
        (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut) -
633
0
         qcOut[0]->staticBits))
634
0
      return AAC_ENC_BITRES_TOO_LOW;
635
0
  }
636
637
  /* distribute dynamic bits to each element */
638
0
  FDKaacEnc_distributeElementDynBits(hQC, qcElement[0], cm,
639
0
                                     qcOut[0]->grantedDynBits);
640
641
0
  *avgTotalDynBits = 0; /*frameDynBits;*/
642
643
0
  *totalAvailableBits = avgTotalBits;
644
645
  /* sum up corrected granted PE */
646
0
  qcOut[0]->totalGrantedPeCorr = 0;
647
648
0
  for (i = 0; i < cm->nElements; i++) {
649
0
    ELEMENT_INFO elInfo = cm->elInfo[i];
650
0
    int nChannels = elInfo.nChannelsInEl;
651
652
0
    if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
653
0
        (elInfo.elType == ID_LFE)) {
654
      /* for ( all sub frames ) ... */
655
0
      FDKaacEnc_DistributeBits(
656
0
          hQC->hAdjThr, hQC->hAdjThr->adjThrStateElem[i],
657
0
          psyOut[0]->psyOutElement[i]->psyOutChannel, &qcElement[0][i]->peData,
658
0
          &qcElement[0][i]->grantedPe, &qcElement[0][i]->grantedPeCorr,
659
0
          nChannels, psyOut[0]->psyOutElement[i]->commonWindow,
660
0
          qcElement[0][i]->grantedDynBits, hQC->elementBits[i]->bitResLevelEl,
661
0
          hQC->elementBits[i]->maxBitResBitsEl, hQC->maxBitFac,
662
0
          hQC->bitResMode);
663
664
0
      *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl;
665
      /* get total corrected granted PE */
666
0
      qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr;
667
0
    } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
668
669
0
  } /* -end- element loop */
670
671
0
  *totalAvailableBits = fMin(hQC->maxBitsPerFrame, (*totalAvailableBits));
672
673
0
  return AAC_ENC_OK;
674
0
}
675
676
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
677
static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(
678
    INT* sumDynBitsConsumed, QC_OUT_ELEMENT* qcElement[((8))],
679
0
    CHANNEL_MAPPING* cm) {
680
0
  INT i;
681
682
0
  *sumDynBitsConsumed = 0;
683
684
0
  for (i = 0; i < cm->nElements; i++) {
685
0
    ELEMENT_INFO elInfo = cm->elInfo[i];
686
687
0
    if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
688
0
        (elInfo.elType == ID_LFE)) {
689
      /* sum up bits consumed */
690
0
      *sumDynBitsConsumed += qcElement[i]->dynBitsUsed;
691
0
    } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
692
693
0
  } /* -end- element loop */
694
695
0
  return AAC_ENC_OK;
696
0
}
697
698
0
static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, INT nSubFrames) {
699
0
  INT c, totalBits = 0;
700
701
  /* sum up bit consumption for all sub frames */
702
0
  for (c = 0; c < nSubFrames; c++) {
703
    /* bit consumption not valid if dynamic bits
704
       not available in one sub frame */
705
0
    if (qcOut[c]->usedDynBits == -1) return -1;
706
0
    totalBits += qcOut[c]->usedDynBits;
707
0
  }
708
709
0
  return totalBits;
710
0
}
711
712
static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut,
713
                                          QC_OUT_ELEMENT* qcElement[(1)][((8))],
714
                                          CHANNEL_MAPPING* cm, INT globHdrBits,
715
0
                                          INT nSubFrames) {
716
0
  int c, i;
717
0
  int totalUsedBits = 0;
718
719
0
  for (c = 0; c < nSubFrames; c++) {
720
0
    int dataBits = 0;
721
0
    for (i = 0; i < cm->nElements; i++) {
722
0
      if ((cm->elInfo[i].elType == ID_SCE) ||
723
0
          (cm->elInfo[i].elType == ID_CPE) ||
724
0
          (cm->elInfo[i].elType == ID_LFE)) {
725
0
        dataBits += qcElement[c][i]->dynBitsUsed +
726
0
                    qcElement[c][i]->staticBitsUsed +
727
0
                    qcElement[c][i]->extBitsUsed;
728
0
      }
729
0
    }
730
0
    dataBits += qcOut[c]->globalExtBits;
731
732
0
    totalUsedBits += (8 - (dataBits) % 8) % 8;
733
0
    totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */
734
0
  }
735
0
  return totalUsedBits;
736
0
}
737
738
static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution(
739
    QC_STATE* const hQC, const CHANNEL_MAPPING* const cm,
740
0
    const INT avgTotalBits) {
741
  /* check bitreservoir fill level */
742
0
  if (hQC->bitResTot < 0) {
743
0
    return AAC_ENC_BITRES_TOO_LOW;
744
0
  } else if (hQC->bitResTot > hQC->bitResTotMax) {
745
0
    return AAC_ENC_BITRES_TOO_HIGH;
746
0
  } else {
747
0
    INT i;
748
0
    INT totalBits = 0, totalBits_max = 0;
749
750
0
    const int totalBitreservoir =
751
0
        fMin(hQC->bitResTot, (hQC->maxBitsPerFrame - avgTotalBits));
752
0
    const int totalBitreservoirMax =
753
0
        fMin(hQC->bitResTotMax, (hQC->maxBitsPerFrame - avgTotalBits));
754
755
0
    for (i = (cm->nElements - 1); i >= 0; i--) {
756
0
      if ((cm->elInfo[i].elType == ID_SCE) ||
757
0
          (cm->elInfo[i].elType == ID_CPE) ||
758
0
          (cm->elInfo[i].elType == ID_LFE)) {
759
0
        hQC->elementBits[i]->bitResLevelEl =
760
0
            fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoir);
761
0
        totalBits += hQC->elementBits[i]->bitResLevelEl;
762
763
0
        hQC->elementBits[i]->maxBitResBitsEl =
764
0
            fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoirMax);
765
0
        totalBits_max += hQC->elementBits[i]->maxBitResBitsEl;
766
0
      }
767
0
    }
768
0
    for (i = 0; i < cm->nElements; i++) {
769
0
      if ((cm->elInfo[i].elType == ID_SCE) ||
770
0
          (cm->elInfo[i].elType == ID_CPE) ||
771
0
          (cm->elInfo[i].elType == ID_LFE)) {
772
0
        int deltaBits = fMax(totalBitreservoir - totalBits,
773
0
                             -hQC->elementBits[i]->bitResLevelEl);
774
0
        hQC->elementBits[i]->bitResLevelEl += deltaBits;
775
0
        totalBits += deltaBits;
776
777
0
        deltaBits = fMax(totalBitreservoirMax - totalBits_max,
778
0
                         -hQC->elementBits[i]->maxBitResBitsEl);
779
0
        hQC->elementBits[i]->maxBitResBitsEl += deltaBits;
780
0
        totalBits_max += deltaBits;
781
0
      }
782
0
    }
783
0
  }
784
785
0
  return AAC_ENC_OK;
786
0
}
787
788
AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut,
789
                                   QC_OUT** qcOut, INT avgTotalBits,
790
                                   CHANNEL_MAPPING* cm,
791
                                   const AUDIO_OBJECT_TYPE aot,
792
0
                                   UINT syntaxFlags, SCHAR epConfig) {
793
0
  int i, c;
794
0
  AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
795
0
  INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */
796
0
  INT totalAvailableBits = 0;
797
0
  INT nSubFrames = 1;
798
0
  const INT isCBRAdjustment = (isConstantBitrateMode(hQC->bitrateMode) ||
799
0
                               (hQC->bitResMode != AACENC_BR_MODE_FULL))
800
0
                                  ? 1
801
0
                                  : 0;
802
803
  /*-------------------------------------------- */
804
  /* redistribute total bitreservoir to elements */
805
0
  ErrorStatus = FDKaacEnc_BitResRedistribution(
806
0
      hQC, cm, (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits);
807
0
  if (ErrorStatus != AAC_ENC_OK) {
808
0
    return ErrorStatus;
809
0
  }
810
811
  /*-------------------------------------------- */
812
  /* fastenc needs one time threshold simulation,
813
     in case of multiple frames, one more guess has to be calculated */
814
815
  /*-------------------------------------------- */
816
  /* helper pointer */
817
0
  QC_OUT_ELEMENT* qcElement[(1)][((8))];
818
819
  /* work on a copy of qcChannel and qcElement */
820
0
  for (i = 0; i < cm->nElements; i++) {
821
0
    ELEMENT_INFO elInfo = cm->elInfo[i];
822
823
0
    if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
824
0
        (elInfo.elType == ID_LFE)) {
825
      /* for ( all sub frames ) ... */
826
0
      for (c = 0; c < nSubFrames; c++) {
827
0
        { qcElement[c][i] = qcOut[c]->qcElement[i]; }
828
0
      }
829
0
    }
830
0
  }
831
832
  /*-------------------------------------------- */
833
  /*-------------------------------------------- */
834
  /* calc granted dynamic bits for sub frame and
835
     distribute it to each element */
836
0
  ErrorStatus = FDKaacEnc_prepareBitDistribution(
837
0
      hQC, psyOut, qcOut, cm, qcElement,
838
0
      (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits,
839
0
      &totalAvailableBits, &avgTotalDynBits);
840
841
0
  if (ErrorStatus != AAC_ENC_OK) {
842
0
    return ErrorStatus;
843
0
  }
844
845
  /* for ( all sub frames ) ... */
846
0
  for (c = 0; c < nSubFrames; c++) {
847
    /* for CBR and VBR mode */
848
0
    FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c],
849
0
                               psyOut[c]->psyOutElement, isCBRAdjustment, cm);
850
851
0
  } /* -end- sub frame counter */
852
853
  /*-------------------------------------------- */
854
0
  INT iterations[(1)][((8))];
855
0
  INT chConstraintsFulfilled[(1)][((8))][(2)];
856
0
  INT calculateQuant[(1)][((8))][(2)];
857
0
  INT constraintsFulfilled[(1)][((8))];
858
  /*-------------------------------------------- */
859
860
  /* for ( all sub frames ) ... */
861
0
  for (c = 0; c < nSubFrames; c++) {
862
0
    for (i = 0; i < cm->nElements; i++) {
863
0
      ELEMENT_INFO elInfo = cm->elInfo[i];
864
0
      INT ch, nChannels = elInfo.nChannelsInEl;
865
866
0
      if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
867
0
          (elInfo.elType == ID_LFE)) {
868
        /* Turn thresholds into scalefactors, optimize bit consumption and
869
         * verify conformance */
870
0
        FDKaacEnc_EstimateScaleFactors(
871
0
            psyOut[c]->psyOutElement[i]->psyOutChannel,
872
0
            qcElement[c][i]->qcOutChannel, hQC->invQuant, hQC->dZoneQuantEnable,
873
0
            cm->elInfo[i].nChannelsInEl);
874
875
        /*-------------------------------------------- */
876
0
        constraintsFulfilled[c][i] = 1;
877
0
        iterations[c][i] = 0;
878
879
0
        for (ch = 0; ch < nChannels; ch++) {
880
0
          chConstraintsFulfilled[c][i][ch] = 1;
881
0
          calculateQuant[c][i][ch] = 1;
882
0
        }
883
884
        /*-------------------------------------------- */
885
886
0
      } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
887
888
0
    } /* -end- element loop */
889
890
0
    qcOut[c]->usedDynBits = -1;
891
892
0
  } /* -end- sub frame counter */
893
894
0
  INT quantizationDone = 0;
895
0
  INT sumDynBitsConsumedTotal = 0;
896
0
  INT decreaseBitConsumption = -1; /* no direction yet! */
897
898
  /*-------------------------------------------- */
899
  /* -start- Quantization loop ...               */
900
  /*-------------------------------------------- */
901
0
  do /* until max allowed bits per frame and maxDynBits!=-1*/
902
0
  {
903
0
    quantizationDone = 0;
904
905
0
    c = 0; /* get frame to process */
906
907
0
    for (i = 0; i < cm->nElements; i++) {
908
0
      ELEMENT_INFO elInfo = cm->elInfo[i];
909
0
      INT ch, nChannels = elInfo.nChannelsInEl;
910
911
0
      if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
912
0
          (elInfo.elType == ID_LFE)) {
913
0
        do /* until element bits < nChannels*MIN_BUFSIZE_PER_EFF_CHAN */
914
0
        {
915
0
          do /* until spectral values < MAX_QUANT */
916
0
          {
917
            /*-------------------------------------------- */
918
0
            if (!constraintsFulfilled[c][i]) {
919
0
              if ((ErrorStatus = FDKaacEnc_reduceBitConsumption(
920
0
                       &iterations[c][i], hQC->maxIterations,
921
0
                       (decreaseBitConsumption) ? 1 : -1,
922
0
                       chConstraintsFulfilled[c][i], calculateQuant[c][i],
923
0
                       nChannels, psyOut[c]->psyOutElement[i], qcOut[c],
924
0
                       qcElement[c][i], hQC->elementBits[i], aot, syntaxFlags,
925
0
                       epConfig)) != AAC_ENC_OK) {
926
0
                return ErrorStatus;
927
0
              }
928
0
            }
929
930
            /*-------------------------------------------- */
931
            /*-------------------------------------------- */
932
0
            constraintsFulfilled[c][i] = 1;
933
934
            /*-------------------------------------------- */
935
            /* quantize spectrum (per each channel) */
936
0
            for (ch = 0; ch < nChannels; ch++) {
937
              /*-------------------------------------------- */
938
0
              chConstraintsFulfilled[c][i][ch] = 1;
939
940
              /*-------------------------------------------- */
941
942
0
              if (calculateQuant[c][i][ch]) {
943
0
                QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
944
0
                PSY_OUT_CHANNEL* psyOutCh =
945
0
                    psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
946
947
0
                calculateQuant[c][i][ch] =
948
0
                    0; /* calculate quantization only if necessary */
949
950
                /*-------------------------------------------- */
951
0
                FDKaacEnc_QuantizeSpectrum(
952
0
                    psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
953
0
                    psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
954
0
                    qcOutCh->mdctSpectrum, qcOutCh->globalGain, qcOutCh->scf,
955
0
                    qcOutCh->quantSpec, hQC->dZoneQuantEnable);
956
957
                /*-------------------------------------------- */
958
0
                if (FDKaacEnc_calcMaxValueInSfb(
959
0
                        psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
960
0
                        psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
961
0
                        qcOutCh->quantSpec,
962
0
                        qcOutCh->maxValueInSfb) > MAX_QUANT) {
963
0
                  chConstraintsFulfilled[c][i][ch] = 0;
964
0
                  constraintsFulfilled[c][i] = 0;
965
                  /* if quanizted value out of range; increase global gain! */
966
0
                  decreaseBitConsumption = 1;
967
0
                }
968
969
                /*-------------------------------------------- */
970
971
0
              } /* if calculateQuant[c][i][ch] */
972
973
0
            } /* channel loop */
974
975
            /*-------------------------------------------- */
976
            /* quantize spectrum (per each channel) */
977
978
            /*-------------------------------------------- */
979
980
0
          } while (!constraintsFulfilled[c][i]); /* does not regard bit
981
                                                    consumption */
982
983
          /*-------------------------------------------- */
984
          /*-------------------------------------------- */
985
0
          qcElement[c][i]->dynBitsUsed = 0; /* reset dynamic bits */
986
987
          /* quantization valid in current channel! */
988
0
          for (ch = 0; ch < nChannels; ch++) {
989
0
            QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
990
0
            PSY_OUT_CHANNEL* psyOutCh =
991
0
                psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
992
993
            /* count dynamic bits */
994
0
            INT chDynBits = FDKaacEnc_dynBitCount(
995
0
                hQC->hBitCounter, qcOutCh->quantSpec, qcOutCh->maxValueInSfb,
996
0
                qcOutCh->scf, psyOutCh->lastWindowSequence, psyOutCh->sfbCnt,
997
0
                psyOutCh->maxSfbPerGroup, psyOutCh->sfbPerGroup,
998
0
                psyOutCh->sfbOffsets, &qcOutCh->sectionData, psyOutCh->noiseNrg,
999
0
                psyOutCh->isBook, psyOutCh->isScale, syntaxFlags);
1000
1001
            /* sum up dynamic channel bits */
1002
0
            qcElement[c][i]->dynBitsUsed += chDynBits;
1003
0
          }
1004
1005
          /* save dynBitsUsed for correction of bits2pe relation */
1006
0
          if (hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast == -1) {
1007
0
            hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast =
1008
0
                qcElement[c][i]->dynBitsUsed;
1009
0
          }
1010
1011
          /* hold total bit consumption in present element below maximum allowed
1012
           */
1013
0
          if (qcElement[c][i]->dynBitsUsed >
1014
0
              ((nChannels * MIN_BUFSIZE_PER_EFF_CHAN) -
1015
0
               qcElement[c][i]->staticBitsUsed -
1016
0
               qcElement[c][i]->extBitsUsed)) {
1017
0
            constraintsFulfilled[c][i] = 0;
1018
0
          }
1019
1020
0
        } while (!constraintsFulfilled[c][i]);
1021
1022
0
      } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
1023
1024
0
    } /* -end- element loop */
1025
1026
    /* update dynBits of current subFrame */
1027
0
    FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, qcElement[c], cm);
1028
1029
    /* get total consumed bits, dyn bits in all sub frames have to be valid */
1030
0
    sumDynBitsConsumedTotal =
1031
0
        FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames);
1032
1033
0
    if (sumDynBitsConsumedTotal == -1) {
1034
0
      quantizationDone = 0; /* bit consumption not valid in all sub frames */
1035
0
    } else {
1036
0
      int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
1037
0
          qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
1038
1039
      /* in all frames are valid dynamic bits */
1040
0
      if (((sumBitsConsumedTotal < totalAvailableBits) ||
1041
0
           sumDynBitsConsumedTotal == 0) &&
1042
0
          (decreaseBitConsumption == 1) &&
1043
0
          checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)
1044
0
          /*()*/) {
1045
0
        quantizationDone = 1; /* exit bit adjustment */
1046
0
      }
1047
0
      if (sumBitsConsumedTotal > totalAvailableBits &&
1048
0
          (decreaseBitConsumption == 0)) {
1049
0
        quantizationDone = 0; /* reset! */
1050
0
      }
1051
0
    }
1052
1053
    /*-------------------------------------------- */
1054
1055
0
    int emergencyIterations = 1;
1056
0
    int dynBitsOvershoot = 0;
1057
1058
0
    for (c = 0; c < nSubFrames; c++) {
1059
0
      for (i = 0; i < cm->nElements; i++) {
1060
0
        ELEMENT_INFO elInfo = cm->elInfo[i];
1061
1062
0
        if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
1063
0
            (elInfo.elType == ID_LFE)) {
1064
          /* iteration limitation */
1065
0
          emergencyIterations &=
1066
0
              ((iterations[c][i] < hQC->maxIterations) ? 0 : 1);
1067
0
        }
1068
0
      }
1069
      /* detection if used dyn bits exceeds the maximal allowed criterion */
1070
0
      dynBitsOvershoot |=
1071
0
          ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0);
1072
0
    }
1073
1074
0
    if (quantizationDone == 0 || dynBitsOvershoot) {
1075
0
      int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
1076
0
          qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
1077
1078
0
      if ((sumDynBitsConsumedTotal >= avgTotalDynBits) ||
1079
0
          (sumDynBitsConsumedTotal == 0)) {
1080
0
        quantizationDone = 1;
1081
0
      }
1082
0
      if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) {
1083
0
        quantizationDone = 1;
1084
0
      }
1085
0
      if ((sumBitsConsumedTotal > totalAvailableBits) ||
1086
0
          !checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
1087
0
        quantizationDone = 0;
1088
0
      }
1089
0
      if ((sumBitsConsumedTotal < totalAvailableBits) &&
1090
0
          checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
1091
0
        decreaseBitConsumption = 0;
1092
0
      } else {
1093
0
        decreaseBitConsumption = 1;
1094
0
      }
1095
1096
0
      if (dynBitsOvershoot) {
1097
0
        quantizationDone = 0;
1098
0
        decreaseBitConsumption = 1;
1099
0
      }
1100
1101
      /* reset constraints fullfilled flags */
1102
0
      FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled));
1103
0
      FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled));
1104
1105
0
    } /* quantizationDone */
1106
1107
0
  } while (!quantizationDone);
1108
1109
  /*-------------------------------------------- */
1110
  /* ... -end- Quantization loop                 */
1111
  /*-------------------------------------------- */
1112
1113
  /*-------------------------------------------- */
1114
  /*-------------------------------------------- */
1115
1116
0
  return AAC_ENC_OK;
1117
0
}
1118
1119
static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
1120
    int* iterations, const int maxIterations, int gainAdjustment,
1121
    int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
1122
    PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
1123
    ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
1124
0
    SCHAR epConfig) {
1125
0
  int ch;
1126
1127
  /** SOLVING PROBLEM **/
1128
0
  if ((*iterations) < maxIterations) {
1129
    /* increase gain (+ next iteration) */
1130
0
    for (ch = 0; ch < nChannels; ch++) {
1131
0
      if (!chConstraintsFulfilled[ch]) {
1132
0
        qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment;
1133
0
        calculateQuant[ch] = 1; /* global gain has changed, recalculate
1134
                                   quantization in next iteration! */
1135
0
      }
1136
0
    }
1137
0
  } else if ((*iterations) == maxIterations) {
1138
0
    if (qcOutElement->dynBitsUsed == 0) {
1139
0
      return AAC_ENC_QUANT_ERROR;
1140
0
    } else {
1141
      /* crash recovery */
1142
0
      INT bitsToSave = 0;
1143
0
      if ((bitsToSave = fixMax(
1144
0
               (qcOutElement->dynBitsUsed + 8) -
1145
0
                   (elBits->bitResLevelEl + qcOutElement->grantedDynBits),
1146
0
               (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) -
1147
0
                   (elBits->maxBitsEl))) > 0) {
1148
0
        FDKaacEnc_crashRecovery(nChannels, psyOutElement, qcOut, qcOutElement,
1149
0
                                bitsToSave, aot, syntaxFlags, epConfig);
1150
0
      } else {
1151
0
        for (ch = 0; ch < nChannels; ch++) {
1152
0
          qcOutElement->qcOutChannel[ch]->globalGain += 1;
1153
0
        }
1154
0
      }
1155
0
      for (ch = 0; ch < nChannels; ch++) {
1156
0
        calculateQuant[ch] = 1;
1157
0
      }
1158
0
    }
1159
0
  } else {
1160
    /* (*iterations) > maxIterations */
1161
0
    return AAC_ENC_QUANT_ERROR;
1162
0
  }
1163
0
  (*iterations)++;
1164
1165
0
  return AAC_ENC_OK;
1166
0
}
1167
1168
AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
1169
                                           QC_STATE* qcKernel,
1170
                                           ELEMENT_BITS* RESTRICT elBits[((8))],
1171
0
                                           QC_OUT** qcOut) {
1172
0
  switch (qcKernel->bitrateMode) {
1173
0
    case QCDATA_BR_MODE_SFR:
1174
0
      break;
1175
1176
0
    case QCDATA_BR_MODE_FF:
1177
0
      break;
1178
0
    case QCDATA_BR_MODE_VBR_1:
1179
0
    case QCDATA_BR_MODE_VBR_2:
1180
0
    case QCDATA_BR_MODE_VBR_3:
1181
0
    case QCDATA_BR_MODE_VBR_4:
1182
0
    case QCDATA_BR_MODE_VBR_5:
1183
0
      qcOut[0]->totFillBits =
1184
0
          (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits) &
1185
0
          7; /* precalculate alignment bits */
1186
0
      qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits +
1187
0
                            qcOut[0]->totFillBits + qcOut[0]->elementExtBits +
1188
0
                            qcOut[0]->globalExtBits;
1189
0
      qcOut[0]->totFillBits +=
1190
0
          (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
1191
0
      break;
1192
0
    case QCDATA_BR_MODE_CBR:
1193
0
    case QCDATA_BR_MODE_INVALID:
1194
0
    default:
1195
0
      INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot;
1196
      /* processing fill-bits */
1197
0
      INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits;
1198
0
      qcOut[0]->totFillBits = fixMax(
1199
0
          (deltaBitRes & 7), (deltaBitRes - (fixMax(0, bitResSpace - 7) & ~7)));
1200
0
      qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits +
1201
0
                            qcOut[0]->totFillBits + qcOut[0]->elementExtBits +
1202
0
                            qcOut[0]->globalExtBits;
1203
0
      qcOut[0]->totFillBits +=
1204
0
          (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
1205
0
      break;
1206
0
  } /* switch (qcKernel->bitrateMode) */
1207
1208
0
  return AAC_ENC_OK;
1209
0
}
1210
1211
/*********************************************************************************
1212
1213
         functionname: FDKaacEnc_calcMaxValueInSfb
1214
         description:
1215
         return:
1216
1217
**********************************************************************************/
1218
1219
static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
1220
                                       INT sfbPerGroup, INT* RESTRICT sfbOffset,
1221
                                       SHORT* RESTRICT quantSpectrum,
1222
0
                                       UINT* RESTRICT maxValue) {
1223
0
  INT sfbOffs, sfb;
1224
0
  INT maxValueAll = 0;
1225
1226
0
  for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup)
1227
0
    for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
1228
0
      INT line;
1229
0
      INT maxThisSfb = 0;
1230
0
      for (line = sfbOffset[sfbOffs + sfb]; line < sfbOffset[sfbOffs + sfb + 1];
1231
0
           line++) {
1232
0
        INT tmp = fixp_abs(quantSpectrum[line]);
1233
0
        maxThisSfb = fixMax(tmp, maxThisSfb);
1234
0
      }
1235
1236
0
      maxValue[sfbOffs + sfb] = maxThisSfb;
1237
0
      maxValueAll = fixMax(maxThisSfb, maxValueAll);
1238
0
    }
1239
0
  return maxValueAll;
1240
0
}
1241
1242
/*********************************************************************************
1243
1244
         functionname: FDKaacEnc_updateBitres
1245
         description:
1246
         return:
1247
1248
**********************************************************************************/
1249
void FDKaacEnc_updateBitres(CHANNEL_MAPPING* cm, QC_STATE* qcKernel,
1250
0
                            QC_OUT** qcOut) {
1251
0
  switch (qcKernel->bitrateMode) {
1252
0
    case QCDATA_BR_MODE_VBR_1:
1253
0
    case QCDATA_BR_MODE_VBR_2:
1254
0
    case QCDATA_BR_MODE_VBR_3:
1255
0
    case QCDATA_BR_MODE_VBR_4:
1256
0
    case QCDATA_BR_MODE_VBR_5:
1257
      /* variable bitrate */
1258
0
      qcKernel->bitResTot =
1259
0
          fMin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax);
1260
0
      break;
1261
0
    case QCDATA_BR_MODE_CBR:
1262
0
    case QCDATA_BR_MODE_SFR:
1263
0
    case QCDATA_BR_MODE_INVALID:
1264
0
    default:
1265
0
      int c = 0;
1266
      /* constant bitrate */
1267
0
      {
1268
0
        qcKernel->bitResTot += qcOut[c]->grantedDynBits -
1269
0
                               (qcOut[c]->usedDynBits + qcOut[c]->totFillBits +
1270
0
                                qcOut[c]->alignBits);
1271
0
      }
1272
0
      break;
1273
0
  }
1274
0
}
1275
1276
/*********************************************************************************
1277
1278
         functionname: FDKaacEnc_FinalizeBitConsumption
1279
         description:
1280
         return:
1281
1282
**********************************************************************************/
1283
AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
1284
    CHANNEL_MAPPING* cm, QC_STATE* qcKernel, QC_OUT* qcOut,
1285
    QC_OUT_ELEMENT** qcElement, HANDLE_TRANSPORTENC hTpEnc,
1286
0
    AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig) {
1287
0
  QC_OUT_EXTENSION fillExtPayload;
1288
0
  INT totFillBits, alignBits;
1289
1290
  /* Get total consumed bits in AU */
1291
0
  qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
1292
0
                     qcOut->totFillBits + qcOut->elementExtBits +
1293
0
                     qcOut->globalExtBits;
1294
1295
0
  if (qcKernel->bitrateMode == QCDATA_BR_MODE_CBR) {
1296
    /* Now we can get the exact transport bit amount, and hopefully it is equal
1297
     * to the estimated value */
1298
0
    INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
1299
1300
0
    if (exactTpBits != qcKernel->globHdrBits) {
1301
0
      INT diffFillBits = 0;
1302
1303
      /* How many bits can be take by bitreservoir */
1304
0
      const INT bitresSpace =
1305
0
          qcKernel->bitResTotMax -
1306
0
          (qcKernel->bitResTot +
1307
0
           (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits)));
1308
1309
      /* Number of bits which can be moved to bitreservoir. */
1310
0
      const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits;
1311
0
      FDK_ASSERT(bitsToBitres >= 0); /* is always positive */
1312
1313
      /* If bitreservoir can not take all bits, move ramaining bits to fillbits
1314
       */
1315
0
      diffFillBits = fMax(0, bitsToBitres - bitresSpace);
1316
1317
      /* Assure previous alignment */
1318
0
      diffFillBits = (diffFillBits + 7) & ~7;
1319
1320
      /* Move as many bits as possible to bitreservoir */
1321
0
      qcKernel->bitResTot += (bitsToBitres - diffFillBits);
1322
1323
      /* Write remaing bits as fill bits */
1324
0
      qcOut->totFillBits += diffFillBits;
1325
0
      qcOut->totalBits += diffFillBits;
1326
0
      qcOut->grantedDynBits += diffFillBits;
1327
1328
      /* Get new header bits */
1329
0
      qcKernel->globHdrBits =
1330
0
          transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
1331
1332
0
      if (qcKernel->globHdrBits != exactTpBits) {
1333
        /* In previous step, fill bits and corresponding total bits were changed
1334
           when bitreservoir was completely filled. Now we can take the too much
1335
           taken bits caused by header overhead from bitreservoir.
1336
         */
1337
0
        qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits);
1338
0
      }
1339
0
    }
1340
1341
0
  } /* MODE_CBR */
1342
1343
  /* Update exact number of consumed header bits. */
1344
0
  qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
1345
1346
  /* Save total fill bits and distribut to alignment and fill bits */
1347
0
  totFillBits = qcOut->totFillBits;
1348
1349
  /* fake a fill extension payload */
1350
0
  FDKmemclear(&fillExtPayload, sizeof(QC_OUT_EXTENSION));
1351
1352
0
  fillExtPayload.type = EXT_FILL_DATA;
1353
0
  fillExtPayload.nPayloadBits = totFillBits;
1354
1355
  /* ask bitstream encoder how many of that bits can be written in a fill
1356
   * extension data entity */
1357
0
  qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0,
1358
0
                                                    syntaxFlags, aot, epConfig);
1359
1360
  /* now distribute extra fillbits and alignbits */
1361
0
  alignBits =
1362
0
      7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits +
1363
0
           qcOut->totFillBits + qcOut->globalExtBits - 1) %
1364
0
              8;
1365
1366
  /* Maybe we could remove this */
1367
0
  if (((alignBits + qcOut->totFillBits - totFillBits) == 8) &&
1368
0
      (qcOut->totFillBits > 8))
1369
0
    qcOut->totFillBits -= 8;
1370
1371
0
  qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
1372
0
                     qcOut->totFillBits + alignBits + qcOut->elementExtBits +
1373
0
                     qcOut->globalExtBits;
1374
1375
0
  if ((qcOut->totalBits > qcKernel->maxBitsPerFrame) ||
1376
0
      (qcOut->totalBits < qcKernel->minBitsPerFrame)) {
1377
0
    return AAC_ENC_QUANT_ERROR;
1378
0
  }
1379
1380
0
  qcOut->alignBits = alignBits;
1381
1382
0
  return AAC_ENC_OK;
1383
0
}
1384
1385
/*********************************************************************************
1386
1387
         functionname: FDKaacEnc_crashRecovery
1388
         description:  fulfills constraints by means of brute force...
1389
                       => bits are saved by cancelling out spectral lines!!
1390
                          (beginning at the highest frequencies)
1391
         return:       errorcode
1392
1393
**********************************************************************************/
1394
1395
static void FDKaacEnc_crashRecovery(INT nChannels,
1396
                                    PSY_OUT_ELEMENT* psyOutElement,
1397
                                    QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
1398
                                    INT bitsToSave, AUDIO_OBJECT_TYPE aot,
1399
0
                                    UINT syntaxFlags, SCHAR epConfig) {
1400
0
  INT ch;
1401
0
  INT savedBits = 0;
1402
0
  INT sfb, sfbGrp;
1403
0
  INT bitsPerScf[(2)][MAX_GROUPED_SFB];
1404
0
  INT sectionToScf[(2)][MAX_GROUPED_SFB];
1405
0
  INT* sfbOffset;
1406
0
  INT sect, statBitsNew;
1407
0
  QC_OUT_CHANNEL** qcChannel = qcElement->qcOutChannel;
1408
0
  PSY_OUT_CHANNEL** psyChannel = psyOutElement->psyOutChannel;
1409
1410
  /* create a table which converts frq-bins to bit-demand...    [bitsPerScf] */
1411
  /* ...and another one which holds the corresponding sections [sectionToScf] */
1412
0
  for (ch = 0; ch < nChannels; ch++) {
1413
0
    sfbOffset = psyChannel[ch]->sfbOffsets;
1414
1415
0
    for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) {
1416
0
      INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook;
1417
1418
0
      for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart;
1419
0
           sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart +
1420
0
                     qcChannel[ch]->sectionData.huffsection[sect].sfbCnt;
1421
0
           sfb++) {
1422
0
        bitsPerScf[ch][sfb] = 0;
1423
0
        if ((codeBook != CODE_BOOK_PNS_NO) /*&&
1424
0
             (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/) {
1425
0
          INT sfbStartLine = sfbOffset[sfb];
1426
0
          INT noOfLines = sfbOffset[sfb + 1] - sfbStartLine;
1427
0
          bitsPerScf[ch][sfb] = FDKaacEnc_countValues(
1428
0
              &(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook);
1429
0
        }
1430
0
        sectionToScf[ch][sfb] = sect;
1431
0
      }
1432
0
    }
1433
0
  }
1434
1435
  /* LOWER [maxSfb] IN BOTH CHANNELS!! */
1436
  /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ;
1437
   */
1438
1439
0
  for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup - 1; sfb >= 0; sfb--) {
1440
0
    for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt;
1441
0
         sfbGrp += psyChannel[0]->sfbPerGroup) {
1442
0
      for (ch = 0; ch < nChannels; ch++) {
1443
0
        sect = sectionToScf[ch][sfbGrp + sfb];
1444
0
        qcChannel[ch]->sectionData.huffsection[sect].sfbCnt--;
1445
0
        savedBits += bitsPerScf[ch][sfbGrp + sfb];
1446
1447
0
        if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) {
1448
0
          savedBits += (psyChannel[ch]->lastWindowSequence != SHORT_WINDOW)
1449
0
                           ? FDKaacEnc_sideInfoTabLong[0]
1450
0
                           : FDKaacEnc_sideInfoTabShort[0];
1451
0
        }
1452
0
      }
1453
0
    }
1454
1455
    /* ...have enough bits been saved? */
1456
0
    if (savedBits >= bitsToSave) break;
1457
1458
0
  } /* sfb loop */
1459
1460
  /* if not enough bits saved,
1461
     clean whole spectrum and remove side info overhead */
1462
0
  if (sfb == -1) {
1463
0
    sfb = 0;
1464
0
  }
1465
1466
0
  for (ch = 0; ch < nChannels; ch++) {
1467
0
    qcChannel[ch]->sectionData.maxSfbPerGroup = sfb;
1468
0
    psyChannel[ch]->maxSfbPerGroup = sfb;
1469
    /* when no spectrum is coded save tools info in bitstream */
1470
0
    if (sfb == 0) {
1471
0
      FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO));
1472
0
      FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO));
1473
0
    }
1474
0
  }
1475
  /* dynamic bits will be updated in iteration loop */
1476
1477
0
  { /* if stop sfb has changed save bits in side info, e.g. MS or TNS coding */
1478
0
    ELEMENT_INFO elInfo;
1479
1480
0
    FDKmemclear(&elInfo, sizeof(ELEMENT_INFO));
1481
0
    elInfo.nChannelsInEl = nChannels;
1482
0
    elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE;
1483
1484
0
    FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, psyOutElement,
1485
0
                                  psyChannel, syntaxFlags, aot, epConfig,
1486
0
                                  &statBitsNew, 0);
1487
0
  }
1488
1489
0
  savedBits = qcElement->staticBitsUsed - statBitsNew;
1490
1491
  /* update static and dynamic bits */
1492
0
  qcElement->staticBitsUsed -= savedBits;
1493
0
  qcElement->grantedDynBits += savedBits;
1494
1495
0
  qcOut->staticBits -= savedBits;
1496
0
  qcOut->grantedDynBits += savedBits;
1497
0
  qcOut->maxDynBits += savedBits;
1498
0
}
1499
1500
0
void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC) {
1501
0
  int n, i;
1502
1503
0
  if (phQC != NULL) {
1504
0
    for (n = 0; n < (1); n++) {
1505
0
      if (phQC[n] != NULL) {
1506
0
        QC_OUT* hQC = phQC[n];
1507
0
        for (i = 0; i < (8); i++) {
1508
0
        }
1509
1510
0
        for (i = 0; i < ((8)); i++) {
1511
0
          if (hQC->qcElement[i]) FreeRam_aacEnc_QCelement(&hQC->qcElement[i]);
1512
0
        }
1513
1514
0
        FreeRam_aacEnc_QCout(&phQC[n]);
1515
0
      }
1516
0
    }
1517
0
  }
1518
1519
0
  if (phQCstate != NULL) {
1520
0
    if (*phQCstate != NULL) {
1521
0
      QC_STATE* hQCstate = *phQCstate;
1522
1523
0
      if (hQCstate->hAdjThr != NULL) FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr);
1524
1525
0
      if (hQCstate->hBitCounter != NULL)
1526
0
        FDKaacEnc_BCClose(&hQCstate->hBitCounter);
1527
1528
0
      for (i = 0; i < ((8)); i++) {
1529
0
        if (hQCstate->elementBits[i] != NULL) {
1530
0
          FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]);
1531
0
        }
1532
0
      }
1533
0
      FreeRam_aacEnc_QCstate(phQCstate);
1534
0
    }
1535
0
  }
1536
0
}