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