Coverage Report

Created: 2025-07-11 06:50

/src/aac/libAACenc/src/bitenc.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 - 2018 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: Bitstream encoder
100
101
*******************************************************************************/
102
103
#include "bitenc.h"
104
#include "bit_cnt.h"
105
#include "dyn_bits.h"
106
#include "qc_data.h"
107
#include "interface.h"
108
#include "aacEnc_ram.h"
109
110
#include "tpenc_lib.h"
111
112
#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */
113
114
static const int globalGainOffset = 100;
115
static const int icsReservedBit = 0;
116
static const int noiseOffset = 90;
117
118
/*****************************************************************************
119
120
    functionname: FDKaacEnc_encodeSpectralData
121
    description:  encode spectral data
122
    returns:      the number of written bits
123
    input:
124
    output:
125
126
*****************************************************************************/
127
static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset,
128
                                        SECTION_DATA *sectionData,
129
                                        SHORT *quantSpectrum,
130
0
                                        HANDLE_FDK_BITSTREAM hBitStream) {
131
0
  INT i, sfb;
132
0
  INT dbgVal = FDKgetValidBits(hBitStream);
133
134
0
  for (i = 0; i < sectionData->noOfSections; i++) {
135
0
    if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) {
136
      /* huffencode spectral data for this huffsection */
137
0
      INT tmp = sectionData->huffsection[i].sfbStart +
138
0
                sectionData->huffsection[i].sfbCnt;
139
0
      for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) {
140
0
        FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb],
141
0
                             sfbOffset[sfb + 1] - sfbOffset[sfb],
142
0
                             sectionData->huffsection[i].codeBook, hBitStream);
143
0
      }
144
0
    }
145
0
  }
146
0
  return (FDKgetValidBits(hBitStream) - dbgVal);
147
0
}
148
149
/*****************************************************************************
150
151
    functionname:FDKaacEnc_encodeGlobalGain
152
    description: encodes Global Gain (common scale factor)
153
    returns:     the number of static bits
154
    input:
155
    output:
156
157
*****************************************************************************/
158
static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac,
159
                                      HANDLE_FDK_BITSTREAM hBitStream,
160
0
                                      INT mdctScale) {
161
0
  if (hBitStream != NULL) {
162
0
    FDKwriteBits(hBitStream,
163
0
                 globalGain - scalefac + globalGainOffset -
164
0
                     4 * (LOG_NORM_PCM - mdctScale),
165
0
                 8);
166
0
  }
167
0
  return (8);
168
0
}
169
170
/*****************************************************************************
171
172
    functionname:FDKaacEnc_encodeIcsInfo
173
    description: encodes Ics Info
174
    returns:     the number of static bits
175
    input:
176
    output:
177
178
*****************************************************************************/
179
180
static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape,
181
                                   INT groupingMask, INT maxSfbPerGroup,
182
                                   HANDLE_FDK_BITSTREAM hBitStream,
183
0
                                   UINT syntaxFlags) {
184
0
  INT statBits;
185
186
0
  if (blockType == SHORT_WINDOW) {
187
0
    statBits = 8 + TRANS_FAC - 1;
188
0
  } else {
189
0
    if (syntaxFlags & AC_ELD) {
190
0
      statBits = 6;
191
0
    } else {
192
0
      statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
193
0
    }
194
0
  }
195
196
0
  if (hBitStream != NULL) {
197
0
    if (!(syntaxFlags & AC_ELD)) {
198
0
      FDKwriteBits(hBitStream, icsReservedBit, 1);
199
0
      FDKwriteBits(hBitStream, blockType, 2);
200
0
      FDKwriteBits(hBitStream,
201
0
                   (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1);
202
0
    }
203
204
0
    switch (blockType) {
205
0
      case LONG_WINDOW:
206
0
      case START_WINDOW:
207
0
      case STOP_WINDOW:
208
0
        FDKwriteBits(hBitStream, maxSfbPerGroup, 6);
209
210
0
        if (!(syntaxFlags &
211
0
              (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */
212
          /* No predictor data present */
213
0
          FDKwriteBits(hBitStream, 0, 1);
214
0
        }
215
0
        break;
216
217
0
      case SHORT_WINDOW:
218
0
        FDKwriteBits(hBitStream, maxSfbPerGroup, 4);
219
220
        /* Write grouping bits */
221
0
        FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1);
222
0
        break;
223
0
    }
224
0
  }
225
226
0
  return (statBits);
227
0
}
228
229
/*****************************************************************************
230
231
    functionname: FDKaacEnc_encodeSectionData
232
    description:  encode section data (common Huffman codebooks for adjacent
233
                  SFB's)
234
    returns:      none
235
    input:
236
    output:
237
238
*****************************************************************************/
239
static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
240
                                       HANDLE_FDK_BITSTREAM hBitStream,
241
0
                                       UINT useVCB11) {
242
0
  if (hBitStream != NULL) {
243
0
    INT sectEscapeVal = 0, sectLenBits = 0;
244
0
    INT sectLen;
245
0
    INT i;
246
0
    INT dbgVal = FDKgetValidBits(hBitStream);
247
0
    INT sectCbBits = 4;
248
249
0
    switch (sectionData->blockType) {
250
0
      case LONG_WINDOW:
251
0
      case START_WINDOW:
252
0
      case STOP_WINDOW:
253
0
        sectEscapeVal = SECT_ESC_VAL_LONG;
254
0
        sectLenBits = SECT_BITS_LONG;
255
0
        break;
256
257
0
      case SHORT_WINDOW:
258
0
        sectEscapeVal = SECT_ESC_VAL_SHORT;
259
0
        sectLenBits = SECT_BITS_SHORT;
260
0
        break;
261
0
    }
262
263
0
    for (i = 0; i < sectionData->noOfSections; i++) {
264
0
      INT codeBook = sectionData->huffsection[i].codeBook;
265
266
0
      FDKwriteBits(hBitStream, codeBook, sectCbBits);
267
268
0
      {
269
0
        sectLen = sectionData->huffsection[i].sfbCnt;
270
271
0
        while (sectLen >= sectEscapeVal) {
272
0
          FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits);
273
0
          sectLen -= sectEscapeVal;
274
0
        }
275
0
        FDKwriteBits(hBitStream, sectLen, sectLenBits);
276
0
      }
277
0
    }
278
0
    return (FDKgetValidBits(hBitStream) - dbgVal);
279
0
  }
280
0
  return (0);
281
0
}
282
283
/*****************************************************************************
284
285
    functionname: FDKaacEnc_encodeScaleFactorData
286
    description:  encode DPCM coded scale factors
287
    returns:      none
288
    input:
289
    output:
290
291
*****************************************************************************/
292
static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb,
293
                                           SECTION_DATA *sectionData,
294
                                           INT *scalefac,
295
                                           HANDLE_FDK_BITSTREAM hBitStream,
296
                                           INT *RESTRICT noiseNrg,
297
0
                                           const INT *isScale, INT globalGain) {
298
0
  if (hBitStream != NULL) {
299
0
    INT i, j, lastValScf, deltaScf;
300
0
    INT deltaPns;
301
0
    INT lastValPns = 0;
302
0
    INT noisePCMFlag = TRUE;
303
0
    INT lastValIs;
304
305
0
    INT dbgVal = FDKgetValidBits(hBitStream);
306
307
0
    lastValScf = scalefac[sectionData->firstScf];
308
0
    lastValPns = globalGain - scalefac[sectionData->firstScf] +
309
0
                 globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset;
310
0
    lastValIs = 0;
311
312
0
    for (i = 0; i < sectionData->noOfSections; i++) {
313
0
      if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
314
0
        if ((sectionData->huffsection[i].codeBook ==
315
0
             CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
316
0
            (sectionData->huffsection[i].codeBook ==
317
0
             CODE_BOOK_IS_IN_PHASE_NO)) {
318
0
          INT sfbStart = sectionData->huffsection[i].sfbStart;
319
0
          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
320
0
          for (j = sfbStart; j < tmp; j++) {
321
0
            INT deltaIs = isScale[j] - lastValIs;
322
0
            lastValIs = isScale[j];
323
0
            if (FDKaacEnc_codeScalefactorDelta(deltaIs, hBitStream)) {
324
0
              return (1);
325
0
            }
326
0
          } /* sfb */
327
0
        } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
328
0
          INT sfbStart = sectionData->huffsection[i].sfbStart;
329
0
          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
330
0
          for (j = sfbStart; j < tmp; j++) {
331
0
            deltaPns = noiseNrg[j] - lastValPns;
332
0
            lastValPns = noiseNrg[j];
333
334
0
            if (noisePCMFlag) {
335
0
              FDKwriteBits(hBitStream, deltaPns + (1 << (PNS_PCM_BITS - 1)),
336
0
                           PNS_PCM_BITS);
337
0
              noisePCMFlag = FALSE;
338
0
            } else {
339
0
              if (FDKaacEnc_codeScalefactorDelta(deltaPns, hBitStream)) {
340
0
                return (1);
341
0
              }
342
0
            }
343
0
          } /* sfb */
344
0
        } else {
345
0
          INT tmp = sectionData->huffsection[i].sfbStart +
346
0
                    sectionData->huffsection[i].sfbCnt;
347
0
          for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
348
            /*
349
              check if we can repeat the last value to save bits
350
            */
351
0
            if (maxValueInSfb[j] == 0)
352
0
              deltaScf = 0;
353
0
            else {
354
0
              deltaScf = -(scalefac[j] - lastValScf);
355
0
              lastValScf = scalefac[j];
356
0
            }
357
0
            if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) {
358
0
              return (1);
359
0
            }
360
0
          } /* sfb */
361
0
        }   /* code scalefactor */
362
0
      }     /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
363
0
    }       /* section loop */
364
365
0
    return (FDKgetValidBits(hBitStream) - dbgVal);
366
0
  } /* if (hBitStream != NULL) */
367
368
0
  return (0);
369
0
}
370
371
/*****************************************************************************
372
373
    functionname:encodeMsInfo
374
    description: encodes MS-Stereo Info
375
    returns:     the number of static bits
376
    input:
377
    output:
378
379
*****************************************************************************/
380
static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb,
381
                                  INT msDigest, INT *jsFlags,
382
0
                                  HANDLE_FDK_BITSTREAM hBitStream) {
383
0
  INT sfb, sfbOff, msBits = 0;
384
385
0
  if (hBitStream != NULL) {
386
0
    switch (msDigest) {
387
0
      case MS_NONE:
388
0
        FDKwriteBits(hBitStream, SI_MS_MASK_NONE, 2);
389
0
        msBits += 2;
390
0
        break;
391
392
0
      case MS_ALL:
393
0
        FDKwriteBits(hBitStream, SI_MS_MASK_ALL, 2);
394
0
        msBits += 2;
395
0
        break;
396
397
0
      case MS_SOME:
398
0
        FDKwriteBits(hBitStream, SI_MS_MASK_SOME, 2);
399
0
        msBits += 2;
400
0
        for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
401
0
          for (sfb = 0; sfb < maxSfb; sfb++) {
402
0
            if (jsFlags[sfbOff + sfb] & MS_ON) {
403
0
              FDKwriteBits(hBitStream, 1, 1);
404
0
            } else {
405
0
              FDKwriteBits(hBitStream, 0, 1);
406
0
            }
407
0
            msBits += 1;
408
0
          }
409
0
        }
410
0
        break;
411
0
    }
412
0
  } else {
413
0
    msBits += 2;
414
0
    if (msDigest == MS_SOME) {
415
0
      for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
416
0
        for (sfb = 0; sfb < maxSfb; sfb++) {
417
0
          msBits += 1;
418
0
        }
419
0
      }
420
0
    }
421
0
  }
422
0
  return (msBits);
423
0
}
424
425
/*****************************************************************************
426
427
    functionname: FDKaacEnc_encodeTnsDataPresent
428
    description:  encode TNS data (filter order, coeffs, ..)
429
    returns:      the number of static bits
430
    input:
431
    output:
432
433
*****************************************************************************/
434
static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, INT blockType,
435
0
                                          HANDLE_FDK_BITSTREAM hBitStream) {
436
0
  if ((hBitStream != NULL) && (tnsInfo != NULL)) {
437
0
    INT i, tnsPresent = 0;
438
0
    INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
439
440
0
    for (i = 0; i < numOfWindows; i++) {
441
0
      if (tnsInfo->numOfFilters[i] != 0) {
442
0
        tnsPresent = 1;
443
0
        break;
444
0
      }
445
0
    }
446
447
0
    if (tnsPresent == 0) {
448
0
      FDKwriteBits(hBitStream, 0, 1);
449
0
    } else {
450
0
      FDKwriteBits(hBitStream, 1, 1);
451
0
    }
452
0
  }
453
0
  return (1);
454
0
}
455
456
/*****************************************************************************
457
458
    functionname: FDKaacEnc_encodeTnsData
459
    description:  encode TNS data (filter order, coeffs, ..)
460
    returns:      the number of static bits
461
    input:
462
    output:
463
464
*****************************************************************************/
465
static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType,
466
0
                                   HANDLE_FDK_BITSTREAM hBitStream) {
467
0
  INT tnsBits = 0;
468
469
0
  if (tnsInfo != NULL) {
470
0
    INT i, j, k;
471
0
    INT tnsPresent = 0;
472
0
    INT coefBits;
473
0
    INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
474
475
0
    for (i = 0; i < numOfWindows; i++) {
476
0
      if (tnsInfo->numOfFilters[i] != 0) {
477
0
        tnsPresent = 1;
478
0
      }
479
0
    }
480
481
0
    if (hBitStream != NULL) {
482
0
      if (tnsPresent == 1) { /* there is data to be written*/
483
0
        for (i = 0; i < numOfWindows; i++) {
484
0
          FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i],
485
0
                       (blockType == SHORT_WINDOW ? 1 : 2));
486
0
          tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
487
0
          if (tnsInfo->numOfFilters[i]) {
488
0
            FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1);
489
0
            tnsBits += 1;
490
0
          }
491
0
          for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
492
0
            FDKwriteBits(hBitStream, tnsInfo->length[i][j],
493
0
                         (blockType == SHORT_WINDOW ? 4 : 6));
494
0
            tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
495
0
            FDK_ASSERT(tnsInfo->order[i][j] <= 12);
496
0
            FDKwriteBits(hBitStream, tnsInfo->order[i][j],
497
0
                         (blockType == SHORT_WINDOW ? 3 : 5));
498
0
            tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
499
0
            if (tnsInfo->order[i][j]) {
500
0
              FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1);
501
0
              tnsBits += 1; /*direction*/
502
0
              if (tnsInfo->coefRes[i] == 4) {
503
0
                coefBits = 3;
504
0
                for (k = 0; k < tnsInfo->order[i][j]; k++) {
505
0
                  if (tnsInfo->coef[i][j][k] > 3 ||
506
0
                      tnsInfo->coef[i][j][k] < -4) {
507
0
                    coefBits = 4;
508
0
                    break;
509
0
                  }
510
0
                }
511
0
              } else {
512
0
                coefBits = 2;
513
0
                for (k = 0; k < tnsInfo->order[i][j]; k++) {
514
0
                  if (tnsInfo->coef[i][j][k] > 1 ||
515
0
                      tnsInfo->coef[i][j][k] < -2) {
516
0
                    coefBits = 3;
517
0
                    break;
518
0
                  }
519
0
                }
520
0
              }
521
0
              FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]),
522
0
                           1); /*coef_compres*/
523
0
              tnsBits += 1;    /*coef_compression */
524
0
              for (k = 0; k < tnsInfo->order[i][j]; k++) {
525
0
                static const INT rmask[] = {0, 1, 3, 7, 15};
526
0
                FDKwriteBits(hBitStream,
527
0
                             tnsInfo->coef[i][j][k] & rmask[coefBits],
528
0
                             coefBits);
529
0
                tnsBits += coefBits;
530
0
              }
531
0
            }
532
0
          }
533
0
        }
534
0
      }
535
0
    } else {
536
0
      if (tnsPresent != 0) {
537
0
        for (i = 0; i < numOfWindows; i++) {
538
0
          tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
539
0
          if (tnsInfo->numOfFilters[i]) {
540
0
            tnsBits += 1;
541
0
            for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
542
0
              tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
543
0
              tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
544
0
              if (tnsInfo->order[i][j]) {
545
0
                tnsBits += 1; /*direction*/
546
0
                tnsBits += 1; /*coef_compression */
547
0
                if (tnsInfo->coefRes[i] == 4) {
548
0
                  coefBits = 3;
549
0
                  for (k = 0; k < tnsInfo->order[i][j]; k++) {
550
0
                    if (tnsInfo->coef[i][j][k] > 3 ||
551
0
                        tnsInfo->coef[i][j][k] < -4) {
552
0
                      coefBits = 4;
553
0
                      break;
554
0
                    }
555
0
                  }
556
0
                } else {
557
0
                  coefBits = 2;
558
0
                  for (k = 0; k < tnsInfo->order[i][j]; k++) {
559
0
                    if (tnsInfo->coef[i][j][k] > 1 ||
560
0
                        tnsInfo->coef[i][j][k] < -2) {
561
0
                      coefBits = 3;
562
0
                      break;
563
0
                    }
564
0
                  }
565
0
                }
566
0
                for (k = 0; k < tnsInfo->order[i][j]; k++) {
567
0
                  tnsBits += coefBits;
568
0
                }
569
0
              }
570
0
            }
571
0
          }
572
0
        }
573
0
      }
574
0
    }
575
0
  } /* (tnsInfo!=NULL) */
576
577
0
  return (tnsBits);
578
0
}
579
580
/*****************************************************************************
581
582
    functionname: FDKaacEnc_encodeGainControlData
583
    description:  unsupported
584
    returns:      none
585
    input:
586
    output:
587
588
*****************************************************************************/
589
0
static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) {
590
0
  if (hBitStream != NULL) {
591
0
    FDKwriteBits(hBitStream, 0, 1);
592
0
  }
593
0
  return (1);
594
0
}
595
596
/*****************************************************************************
597
598
    functionname: FDKaacEnc_encodePulseData
599
    description:  not supported yet (dummy)
600
    returns:      none
601
    input:
602
    output:
603
604
*****************************************************************************/
605
0
static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) {
606
0
  if (hBitStream != NULL) {
607
0
    FDKwriteBits(hBitStream, 0, 1);
608
0
  }
609
0
  return (1);
610
0
}
611
612
/*****************************************************************************
613
614
    functionname: FDKaacEnc_writeExtensionPayload
615
    description:  write extension payload to bitstream
616
    returns:      number of written bits
617
    input:
618
    output:
619
620
*****************************************************************************/
621
static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,
622
                                           EXT_PAYLOAD_TYPE extPayloadType,
623
                                           const UCHAR *extPayloadData,
624
0
                                           INT extPayloadBits) {
625
0
#define EXT_TYPE_BITS (4)
626
0
#define DATA_EL_VERSION_BITS (4)
627
0
#define FILL_NIBBLE_BITS (4)
628
629
0
  INT extBitsUsed = 0;
630
631
0
  if (extPayloadBits >= EXT_TYPE_BITS) {
632
0
    UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
633
634
0
    if (hBitStream != NULL) {
635
0
      FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
636
0
    }
637
0
    extBitsUsed += EXT_TYPE_BITS;
638
639
0
    switch (extPayloadType) {
640
      /* case EXT_SAC_DATA: */
641
0
      case EXT_LDSAC_DATA:
642
0
        if (hBitStream != NULL) {
643
0
          FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */
644
0
        }
645
0
        extBitsUsed += 4;
646
0
        FDK_FALLTHROUGH;
647
0
      case EXT_DYNAMIC_RANGE:
648
0
      case EXT_SBR_DATA:
649
0
      case EXT_SBR_DATA_CRC:
650
0
        if (hBitStream != NULL) {
651
0
          int i, writeBits = extPayloadBits;
652
0
          for (i = 0; writeBits >= 8; i++) {
653
0
            FDKwriteBits(hBitStream, *extPayloadData++, 8);
654
0
            writeBits -= 8;
655
0
          }
656
0
          if (writeBits > 0) {
657
0
            FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits),
658
0
                         writeBits);
659
0
          }
660
0
        }
661
0
        extBitsUsed += extPayloadBits;
662
0
        break;
663
664
0
      case EXT_DATA_ELEMENT: {
665
0
        INT dataElementLength = (extPayloadBits + 7) >> 3;
666
0
        INT cnt = dataElementLength;
667
0
        int loopCounter = 1;
668
669
0
        while (dataElementLength >= 255) {
670
0
          loopCounter++;
671
0
          dataElementLength -= 255;
672
0
        }
673
674
0
        if (hBitStream != NULL) {
675
0
          int i;
676
0
          FDKwriteBits(
677
0
              hBitStream, 0x00,
678
0
              DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */
679
680
0
          for (i = 1; i < loopCounter; i++) {
681
0
            FDKwriteBits(hBitStream, 255, 8);
682
0
          }
683
0
          FDKwriteBits(hBitStream, dataElementLength, 8);
684
685
0
          for (i = 0; i < cnt; i++) {
686
0
            FDKwriteBits(hBitStream, extPayloadData[i], 8);
687
0
          }
688
0
        }
689
0
        extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8);
690
0
      } break;
691
692
0
      case EXT_FILL_DATA:
693
0
        fillByte = 0xA5;
694
0
        FDK_FALLTHROUGH;
695
0
      case EXT_FIL:
696
0
      default:
697
0
        if (hBitStream != NULL) {
698
0
          int writeBits = extPayloadBits;
699
0
          FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
700
0
          writeBits -=
701
0
              8; /* acount for the extension type and the fill nibble */
702
0
          while (writeBits >= 8) {
703
0
            FDKwriteBits(hBitStream, fillByte, 8);
704
0
            writeBits -= 8;
705
0
          }
706
0
        }
707
0
        extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
708
0
        break;
709
0
    }
710
0
  }
711
712
0
  return (extBitsUsed);
713
0
}
714
715
/*****************************************************************************
716
717
    functionname: FDKaacEnc_writeDataStreamElement
718
    description:  write data stream elements like ancillary data ...
719
    returns:      the amount of used bits
720
    input:
721
    output:
722
723
******************************************************************************/
724
static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,
725
                                            INT elementInstanceTag,
726
                                            INT dataPayloadBytes,
727
                                            UCHAR *dataBuffer,
728
0
                                            UINT alignAnchor) {
729
0
#define DATA_BYTE_ALIGN_FLAG (0)
730
731
0
#define EL_INSTANCE_TAG_BITS (4)
732
0
#define DATA_BYTE_ALIGN_FLAG_BITS (1)
733
0
#define DATA_LEN_COUNT_BITS (8)
734
0
#define DATA_LEN_ESC_COUNT_BITS (8)
735
736
0
#define MAX_DATA_ALIGN_BITS (7)
737
0
#define MAX_DSE_DATA_BYTES (510)
738
739
0
  INT dseBitsUsed = 0;
740
741
0
  while (dataPayloadBytes > 0) {
742
0
    int esc_count = -1;
743
0
    int cnt = 0;
744
0
    INT crcReg = -1;
745
746
0
    dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS +
747
0
                   DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
748
749
0
    if (DATA_BYTE_ALIGN_FLAG) {
750
0
      dseBitsUsed += MAX_DATA_ALIGN_BITS;
751
0
    }
752
753
0
    cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
754
0
    if (cnt >= 255) {
755
0
      esc_count = cnt - 255;
756
0
      dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
757
0
    }
758
759
0
    dataPayloadBytes -= cnt;
760
0
    dseBitsUsed += cnt * 8;
761
762
0
    if (hTpEnc != NULL) {
763
0
      HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
764
0
      int i;
765
766
0
      FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
767
768
0
      crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
769
770
0
      FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
771
0
      FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
772
773
      /* write length field(s) */
774
0
      if (esc_count >= 0) {
775
0
        FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
776
0
        FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
777
0
      } else {
778
0
        FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
779
0
      }
780
781
0
      if (DATA_BYTE_ALIGN_FLAG) {
782
0
        INT tmp = (INT)FDKgetValidBits(hBitStream);
783
0
        FDKbyteAlign(hBitStream, alignAnchor);
784
        /* count actual bits */
785
0
        dseBitsUsed +=
786
0
            (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
787
0
      }
788
789
      /* write payload */
790
0
      for (i = 0; i < cnt; i++) {
791
0
        FDKwriteBits(hBitStream, dataBuffer[i], 8);
792
0
      }
793
0
      transportEnc_CrcEndReg(hTpEnc, crcReg);
794
0
    }
795
0
  }
796
797
0
  return (dseBitsUsed);
798
0
}
799
800
/*****************************************************************************
801
802
    functionname: FDKaacEnc_writeExtensionData
803
    description:  write extension payload to bitstream
804
    returns:      number of written bits
805
    input:
806
    output:
807
808
*****************************************************************************/
809
INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
810
                                 QC_OUT_EXTENSION *pExtension,
811
                                 INT elInstanceTag, /* for DSE only */
812
                                 UINT alignAnchor,  /* for DSE only */
813
                                 UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
814
0
                                 SCHAR epConfig) {
815
0
#define FILL_EL_COUNT_BITS (4)
816
0
#define FILL_EL_ESC_COUNT_BITS (8)
817
0
#define MAX_FILL_DATA_BYTES (269)
818
819
0
  HANDLE_FDK_BITSTREAM hBitStream = NULL;
820
0
  INT payloadBits = pExtension->nPayloadBits;
821
0
  INT extBitsUsed = 0;
822
823
0
  if (hTpEnc != NULL) {
824
0
    hBitStream = transportEnc_GetBitstream(hTpEnc);
825
0
  }
826
827
0
  if (syntaxFlags & (AC_SCALABLE | AC_ER)) {
828
0
    {
829
0
      if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) ||
830
0
                                     (pExtension->type == EXT_SBR_DATA_CRC))) {
831
0
        if (hBitStream != NULL) {
832
0
          int i, writeBits = payloadBits;
833
0
          UCHAR *extPayloadData = pExtension->pPayload;
834
835
0
          for (i = 0; writeBits >= 8; i++) {
836
0
            FDKwriteBits(hBitStream, extPayloadData[i], 8);
837
0
            writeBits -= 8;
838
0
          }
839
0
          if (writeBits > 0) {
840
0
            FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits),
841
0
                         writeBits);
842
0
          }
843
0
        }
844
0
        extBitsUsed += payloadBits;
845
0
      } else {
846
        /* ER or scalable syntax -> write extension en bloc */
847
0
        extBitsUsed += FDKaacEnc_writeExtensionPayload(
848
0
            hBitStream, pExtension->type, pExtension->pPayload, payloadBits);
849
0
      }
850
0
    }
851
0
  } else {
852
    /* We have normal GA bitstream payload (AOT 2,5,29) so pack
853
       the data into a fill elements or DSEs */
854
855
0
    if (pExtension->type == EXT_DATA_ELEMENT) {
856
0
      extBitsUsed += FDKaacEnc_writeDataStreamElement(
857
0
          hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3,
858
0
          pExtension->pPayload, alignAnchor);
859
0
    } else {
860
0
      while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
861
0
        INT cnt, esc_count = -1, alignBits = 7;
862
863
0
        if ((pExtension->type == EXT_FILL_DATA) ||
864
0
            (pExtension->type == EXT_FIL)) {
865
0
          payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
866
0
          if (payloadBits >= 15 * 8) {
867
0
            payloadBits -= FILL_EL_ESC_COUNT_BITS;
868
0
            esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
869
0
          }
870
0
          alignBits = 0;
871
0
        }
872
873
0
        cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3);
874
875
0
        if (cnt >= 15) {
876
0
          esc_count = cnt - 15 + 1;
877
0
        }
878
879
0
        if (hBitStream != NULL) {
880
          /* write bitstream */
881
0
          FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
882
0
          if (esc_count >= 0) {
883
0
            FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
884
0
            FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
885
0
          } else {
886
0
            FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
887
0
          }
888
0
        }
889
890
0
        extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS +
891
0
                       ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0);
892
893
0
        cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */
894
0
        extBitsUsed += FDKaacEnc_writeExtensionPayload(
895
0
            hBitStream, pExtension->type, pExtension->pPayload, cnt);
896
0
        payloadBits -= cnt;
897
0
      }
898
0
    }
899
0
  }
900
901
0
  return (extBitsUsed);
902
0
}
903
904
/*****************************************************************************
905
906
    functionname: FDKaacEnc_ByteAlignment
907
    description:
908
    returns:
909
    input:
910
    output:
911
912
*****************************************************************************/
913
static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,
914
0
                                    int alignBits) {
915
0
  FDKwriteBits(hBitStream, 0, alignBits);
916
0
}
917
918
AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
919
    HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
920
    QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
921
    PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
922
0
    AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) {
923
0
  AAC_ENCODER_ERROR error = AAC_ENC_OK;
924
0
  HANDLE_FDK_BITSTREAM hBitStream = NULL;
925
0
  INT bitDemand = 0;
926
0
  const element_list_t *list;
927
0
  int i, ch, decision_bit;
928
0
  INT crcReg1 = -1, crcReg2 = -1;
929
0
  UCHAR numberOfChannels;
930
931
0
  if (hTpEnc != NULL) {
932
    /* Get bitstream handle */
933
0
    hBitStream = transportEnc_GetBitstream(hTpEnc);
934
0
  }
935
936
0
  if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) {
937
0
    numberOfChannels = 1;
938
0
  } else {
939
0
    numberOfChannels = 2;
940
0
  }
941
942
  /* Get channel element sequence table */
943
0
  list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0);
944
0
  if (list == NULL) {
945
0
    error = AAC_ENC_UNSUPPORTED_AOT;
946
0
    goto bail;
947
0
  }
948
949
0
  if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
950
0
    if (hBitStream != NULL) {
951
0
      FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
952
0
    }
953
0
    bitDemand += EL_ID_BITS;
954
0
  }
955
956
  /* Iterate through sequence table */
957
0
  i = 0;
958
0
  ch = 0;
959
0
  decision_bit = 0;
960
0
  do {
961
    /* some tmp values */
962
0
    SECTION_DATA *pChSectionData = NULL;
963
0
    INT *pChScf = NULL;
964
0
    UINT *pChMaxValueInSfb = NULL;
965
0
    TNS_INFO *pTnsInfo = NULL;
966
0
    INT chGlobalGain = 0;
967
0
    INT chBlockType = 0;
968
0
    INT chMaxSfbPerGrp = 0;
969
0
    INT chSfbPerGrp = 0;
970
0
    INT chSfbCnt = 0;
971
0
    INT chFirstScf = 0;
972
973
0
    if (minCnt == 0) {
974
0
      if (qcOutChannel != NULL) {
975
0
        pChSectionData = &(qcOutChannel[ch]->sectionData);
976
0
        pChScf = qcOutChannel[ch]->scf;
977
0
        chGlobalGain = qcOutChannel[ch]->globalGain;
978
0
        pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb;
979
0
        chBlockType = pChSectionData->blockType;
980
0
        chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup;
981
0
        chSfbPerGrp = pChSectionData->sfbPerGroup;
982
0
        chSfbCnt = pChSectionData->sfbCnt;
983
0
        chFirstScf = pChScf[pChSectionData->firstScf];
984
0
      } else {
985
        /* get values from PSY */
986
0
        chSfbCnt = psyOutChannel[ch]->sfbCnt;
987
0
        chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup;
988
0
        chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
989
0
      }
990
0
      pTnsInfo = &psyOutChannel[ch]->tnsInfo;
991
0
    } /* minCnt==0 */
992
993
0
    if (qcOutChannel == NULL) {
994
0
      chBlockType = psyOutChannel[ch]->lastWindowSequence;
995
0
    }
996
997
0
    switch (list->id[i]) {
998
0
      case element_instance_tag:
999
        /* Write element instance tag */
1000
0
        if (hBitStream != NULL) {
1001
0
          FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
1002
0
        }
1003
0
        bitDemand += 4;
1004
0
        break;
1005
1006
0
      case common_window:
1007
        /* Write common window flag */
1008
0
        decision_bit = psyOutElement->commonWindow;
1009
0
        if (hBitStream != NULL) {
1010
0
          FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
1011
0
        }
1012
0
        bitDemand += 1;
1013
0
        break;
1014
1015
0
      case ics_info:
1016
        /* Write individual channel info */
1017
0
        bitDemand +=
1018
0
            FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape,
1019
0
                                    psyOutChannel[ch]->groupingMask,
1020
0
                                    chMaxSfbPerGrp, hBitStream, syntaxFlags);
1021
0
        break;
1022
1023
0
      case ltp_data_present:
1024
        /* Write LTP data present flag */
1025
0
        if (hBitStream != NULL) {
1026
0
          FDKwriteBits(hBitStream, 0, 1);
1027
0
        }
1028
0
        bitDemand += 1;
1029
0
        break;
1030
1031
0
      case ltp_data:
1032
        /* Predictor data not supported.
1033
           Nothing to do here. */
1034
0
        break;
1035
1036
0
      case ms:
1037
        /* Write MS info */
1038
0
        bitDemand += FDKaacEnc_encodeMSInfo(
1039
0
            chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp,
1040
0
            (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
1041
0
            psyOutElement->toolsInfo.msMask, hBitStream);
1042
0
        break;
1043
1044
0
      case global_gain:
1045
0
        bitDemand += FDKaacEnc_encodeGlobalGain(
1046
0
            chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale);
1047
0
        break;
1048
1049
0
      case section_data: {
1050
0
        INT siBits = FDKaacEnc_encodeSectionData(
1051
0
            pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
1052
0
        if (hBitStream != NULL) {
1053
0
          if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
1054
0
            error = AAC_ENC_WRITE_SEC_ERROR;
1055
0
          }
1056
0
        }
1057
0
        bitDemand += siBits;
1058
0
      } break;
1059
1060
0
      case scale_factor_data: {
1061
0
        INT sfDataBits = FDKaacEnc_encodeScaleFactorData(
1062
0
            pChMaxValueInSfb, pChSectionData, pChScf, hBitStream,
1063
0
            psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale,
1064
0
            chGlobalGain);
1065
0
        if ((hBitStream != NULL) &&
1066
0
            (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits +
1067
0
                            qcOutChannel[ch]->sectionData.noiseNrgBits))) {
1068
0
          error = AAC_ENC_WRITE_SCAL_ERROR;
1069
0
        }
1070
0
        bitDemand += sfDataBits;
1071
0
      } break;
1072
1073
0
      case esc2_rvlc:
1074
0
        if (syntaxFlags & AC_ER_RVLC) {
1075
          /* write RVLC data into bitstream (error sens. cat. 2) */
1076
0
          error = AAC_ENC_UNSUPPORTED_AOT;
1077
0
        }
1078
0
        break;
1079
1080
0
      case pulse:
1081
        /* Write pulse data */
1082
0
        bitDemand += FDKaacEnc_encodePulseData(hBitStream);
1083
0
        break;
1084
1085
0
      case tns_data_present:
1086
        /* Write TNS data present flag */
1087
0
        bitDemand +=
1088
0
            FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream);
1089
0
        break;
1090
0
      case tns_data:
1091
        /* Write TNS data */
1092
0
        bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream);
1093
0
        break;
1094
1095
0
      case gain_control_data:
1096
        /* Nothing to do here */
1097
0
        break;
1098
1099
0
      case gain_control_data_present:
1100
0
        bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
1101
0
        break;
1102
1103
0
      case esc1_hcr:
1104
0
        if (syntaxFlags & AC_ER_HCR) {
1105
0
          error = AAC_ENC_UNKNOWN;
1106
0
        }
1107
0
        break;
1108
1109
0
      case spectral_data:
1110
0
        if (hBitStream != NULL) {
1111
0
          INT spectralBits = 0;
1112
1113
0
          spectralBits = FDKaacEnc_encodeSpectralData(
1114
0
              psyOutChannel[ch]->sfbOffsets, pChSectionData,
1115
0
              qcOutChannel[ch]->quantSpec, hBitStream);
1116
1117
0
          if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
1118
0
            return AAC_ENC_WRITE_SPEC_ERROR;
1119
0
          }
1120
0
          bitDemand += spectralBits;
1121
0
        }
1122
0
        break;
1123
1124
        /* Non data cases */
1125
0
      case adtscrc_start_reg1:
1126
0
        if (hTpEnc != NULL) {
1127
0
          crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
1128
0
        }
1129
0
        break;
1130
0
      case adtscrc_start_reg2:
1131
0
        if (hTpEnc != NULL) {
1132
0
          crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
1133
0
        }
1134
0
        break;
1135
0
      case adtscrc_end_reg1:
1136
0
      case drmcrc_end_reg:
1137
0
        if (hTpEnc != NULL) {
1138
0
          transportEnc_CrcEndReg(hTpEnc, crcReg1);
1139
0
        }
1140
0
        break;
1141
0
      case adtscrc_end_reg2:
1142
0
        if (hTpEnc != NULL) {
1143
0
          transportEnc_CrcEndReg(hTpEnc, crcReg2);
1144
0
        }
1145
0
        break;
1146
0
      case drmcrc_start_reg:
1147
0
        if (hTpEnc != NULL) {
1148
0
          crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
1149
0
        }
1150
0
        break;
1151
0
      case next_channel:
1152
0
        ch = (ch + 1) % numberOfChannels;
1153
0
        break;
1154
0
      case link_sequence:
1155
0
        list = list->next[decision_bit];
1156
0
        i = -1;
1157
0
        break;
1158
1159
0
      default:
1160
0
        error = AAC_ENC_UNKNOWN;
1161
0
        break;
1162
0
    }
1163
1164
0
    if (error != AAC_ENC_OK) {
1165
0
      return error;
1166
0
    }
1167
1168
0
    i++;
1169
1170
0
  } while (list->id[i] != end_of_sequence);
1171
1172
0
bail:
1173
0
  if (pBitDemand != NULL) {
1174
0
    *pBitDemand = bitDemand;
1175
0
  }
1176
1177
0
  return error;
1178
0
}
1179
1180
//-----------------------------------------------------------------------------------------------
1181
1182
AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
1183
                                           CHANNEL_MAPPING *channelMapping,
1184
                                           QC_OUT *qcOut, PSY_OUT *psyOut,
1185
                                           QC_STATE *qcKernel,
1186
                                           AUDIO_OBJECT_TYPE aot,
1187
0
                                           UINT syntaxFlags, SCHAR epConfig) {
1188
0
  HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
1189
0
  AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
1190
0
  int i, n, doByteAlign = 1;
1191
0
  INT bitMarkUp;
1192
0
  INT frameBits;
1193
  /* Get first bit of raw data block.
1194
     In case of ADTS+PCE, AU would start at PCE.
1195
     This is okay because PCE assures alignment. */
1196
0
  UINT alignAnchor = FDKgetValidBits(hBs);
1197
1198
0
  frameBits = bitMarkUp = alignAnchor;
1199
1200
  /* Channel element loop */
1201
0
  for (i = 0; i < channelMapping->nElements; i++) {
1202
0
    ELEMENT_INFO elInfo = channelMapping->elInfo[i];
1203
0
    INT elementUsedBits = 0;
1204
1205
0
    switch (elInfo.elType) {
1206
0
      case ID_SCE: /* single channel */
1207
0
      case ID_CPE: /* channel pair */
1208
0
      case ID_LFE: /* low freq effects channel */
1209
0
      {
1210
0
        if (AAC_ENC_OK !=
1211
0
            (ErrorStatus = FDKaacEnc_ChannelElementWrite(
1212
0
                 hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel,
1213
0
                 psyOut->psyOutElement[i],
1214
0
                 psyOut->psyOutElement[i]->psyOutChannel,
1215
0
                 syntaxFlags, /* syntaxFlags (ER tools ...) */
1216
0
                 aot,         /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
1217
0
                 epConfig,    /* epConfig -1, 0, 1 */
1218
0
                 NULL, 0))) {
1219
0
          return ErrorStatus;
1220
0
        }
1221
1222
0
        if (!(syntaxFlags & AC_ER)) {
1223
          /* Write associated extension payload */
1224
0
          for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1225
0
            FDKaacEnc_writeExtensionData(
1226
0
                hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
1227
0
                syntaxFlags, aot, epConfig);
1228
0
          }
1229
0
        }
1230
0
      } break;
1231
1232
      /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
1233
0
      default:
1234
0
        return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
1235
1236
0
    } /* switch */
1237
1238
0
    if (elInfo.elType != ID_DSE) {
1239
0
      elementUsedBits -= bitMarkUp;
1240
0
      bitMarkUp = FDKgetValidBits(hBs);
1241
0
      elementUsedBits += bitMarkUp;
1242
0
      frameBits += elementUsedBits;
1243
0
    }
1244
1245
0
  } /* for (i=0; i<channelMapping.nElements; i++) */
1246
1247
0
  if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) {
1248
0
    UCHAR channelElementExtensionWritten[((8))][(
1249
0
        1)]; /* 0: extension not touched, 1: extension already written */
1250
1251
0
    FDKmemclear(channelElementExtensionWritten,
1252
0
                sizeof(channelElementExtensionWritten));
1253
1254
0
    if (syntaxFlags & AC_ELD) {
1255
0
      for (i = 0; i < channelMapping->nElements; i++) {
1256
0
        for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1257
0
          if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) ||
1258
0
              (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) {
1259
            /* Write sbr extension payload */
1260
0
            FDKaacEnc_writeExtensionData(
1261
0
                hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
1262
0
                syntaxFlags, aot, epConfig);
1263
1264
0
            channelElementExtensionWritten[i][n] = 1;
1265
0
          } /* SBR */
1266
0
        }   /* n */
1267
0
      }     /* i */
1268
0
    }       /* AC_ELD */
1269
1270
0
    for (i = 0; i < channelMapping->nElements; i++) {
1271
0
      for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1272
0
        if (channelElementExtensionWritten[i][n] == 0) {
1273
          /* Write all ramaining extension payloads in element */
1274
0
          FDKaacEnc_writeExtensionData(hTpEnc,
1275
0
                                       &qcOut->qcElement[i]->extension[n], 0,
1276
0
                                       alignAnchor, syntaxFlags, aot, epConfig);
1277
0
        }
1278
0
      } /* n */
1279
0
    }   /* i */
1280
0
  }     /* if AC_ER */
1281
1282
  /* Extend global extension payload table with fill bits */
1283
0
  n = qcOut->nExtensions;
1284
1285
  /* Add fill data / stuffing bits */
1286
0
  qcOut->extension[n].type = EXT_FILL_DATA;
1287
0
  qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
1288
0
  qcOut->nExtensions++;
1289
1290
  /* Write global extension payload and fill data */
1291
0
  for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) {
1292
0
    FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor,
1293
0
                                 syntaxFlags, aot, epConfig);
1294
1295
    /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
1296
     */
1297
0
  }
1298
1299
0
  if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
1300
0
    FDKwriteBits(hBs, ID_END, EL_ID_BITS);
1301
0
  }
1302
1303
0
  if (doByteAlign) {
1304
    /* Assure byte alignment*/
1305
0
    if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) {
1306
0
      return AAC_ENC_WRITTEN_BITS_ERROR;
1307
0
    }
1308
1309
0
    FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
1310
0
  }
1311
1312
0
  frameBits -= bitMarkUp;
1313
0
  frameBits += FDKgetValidBits(hBs);
1314
1315
0
  transportEnc_EndAccessUnit(hTpEnc, &frameBits);
1316
1317
0
  if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) {
1318
0
    return AAC_ENC_WRITTEN_BITS_ERROR;
1319
0
  }
1320
1321
0
  return ErrorStatus;
1322
0
}