Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84  /******************************** MPEG Audio Encoder **************************
     85 
     86    Initial author:       M. Werner
     87    contents/description: Bitstream encoder
     88 
     89 ******************************************************************************/
     90 
     91 #include "bitenc.h"
     92 #include "bit_cnt.h"
     93 #include "dyn_bits.h"
     94 #include "qc_data.h"
     95 #include "interface.h"
     96 #include "aacEnc_ram.h"
     97 
     98 
     99 #include "tpenc_lib.h"
    100 
    101 #include "FDK_tools_rom.h"  /* needed for the bitstream syntax tables */
    102 
    103 static const int globalGainOffset = 100;
    104 static const int icsReservedBit   = 0;
    105 static const int noiseOffset      = 90;
    106 
    107 /*****************************************************************************
    108 
    109     functionname: FDKaacEnc_encodeSpectralData
    110     description:  encode spectral data
    111     returns:      the number of written bits
    112     input:
    113     output:
    114 
    115 *****************************************************************************/
    116 static INT FDKaacEnc_encodeSpectralData(INT                    *sfbOffset,
    117                                         SECTION_DATA           *sectionData,
    118                                         SHORT                  *quantSpectrum,
    119                                         HANDLE_FDK_BITSTREAM    hBitStream)
    120 {
    121   INT i,sfb;
    122   INT dbgVal = FDKgetValidBits(hBitStream);
    123 
    124   for(i=0;i<sectionData->noOfSections;i++)
    125   {
    126     if(sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)
    127     {
    128       /* huffencode spectral data for this huffsection */
    129       INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt;
    130       for(sfb=sectionData->huffsection[i].sfbStart; sfb<tmp; sfb++)
    131       {
    132         FDKaacEnc_codeValues(quantSpectrum+sfbOffset[sfb],
    133                              sfbOffset[sfb+1]-sfbOffset[sfb],
    134                              sectionData->huffsection[i].codeBook,
    135                              hBitStream);
    136       }
    137     }
    138   }
    139   return(FDKgetValidBits(hBitStream)-dbgVal);
    140 }
    141 
    142 /*****************************************************************************
    143 
    144     functionname:FDKaacEnc_encodeGlobalGain
    145     description: encodes Global Gain (common scale factor)
    146     returns:     the number of static bits
    147     input:
    148     output:
    149 
    150 *****************************************************************************/
    151 static INT FDKaacEnc_encodeGlobalGain(INT globalGain,
    152                                       INT scalefac,
    153                                       HANDLE_FDK_BITSTREAM hBitStream,
    154                                       INT mdctScale)
    155 {
    156   if (hBitStream != NULL) {
    157     FDKwriteBits(hBitStream,globalGain - scalefac + globalGainOffset-4*(LOG_NORM_PCM-mdctScale),8);
    158   }
    159   return (8);
    160 }
    161 
    162 
    163 /*****************************************************************************
    164 
    165     functionname:FDKaacEnc_encodeIcsInfo
    166     description: encodes Ics Info
    167     returns:     the number of static bits
    168     input:
    169     output:
    170 
    171 *****************************************************************************/
    172 
    173 static INT FDKaacEnc_encodeIcsInfo(INT blockType,
    174                                    INT windowShape,
    175                                    INT groupingMask,
    176                                    INT maxSfbPerGroup,
    177                                    HANDLE_FDK_BITSTREAM  hBitStream,
    178                                    UINT syntaxFlags)
    179 {
    180   INT statBits;
    181 
    182   if (blockType == SHORT_WINDOW) {
    183     statBits = 8 + TRANS_FAC - 1;
    184   } else {
    185     if (syntaxFlags & AC_ELD) {
    186       statBits = 6;
    187     } else
    188     {
    189       statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
    190     }
    191   }
    192 
    193   if (hBitStream != NULL) {
    194 
    195     if (!(syntaxFlags & AC_ELD)){
    196       FDKwriteBits(hBitStream,icsReservedBit,1);
    197       FDKwriteBits(hBitStream,blockType,2);
    198       FDKwriteBits(hBitStream, (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape,1);
    199     }
    200 
    201     switch(blockType){
    202     case LONG_WINDOW:
    203     case START_WINDOW:
    204     case STOP_WINDOW:
    205       FDKwriteBits(hBitStream,maxSfbPerGroup,6);
    206 
    207       if (!(syntaxFlags & (AC_SCALABLE|AC_ELD)) ) { /* If not scalable syntax then ... */
    208         /* No predictor data present */
    209         FDKwriteBits(hBitStream, 0, 1);
    210       }
    211       break;
    212 
    213     case SHORT_WINDOW:
    214       FDKwriteBits(hBitStream,maxSfbPerGroup,4);
    215 
    216       /* Write grouping bits */
    217       FDKwriteBits(hBitStream,groupingMask,TRANS_FAC-1);
    218       break;
    219     }
    220   }
    221 
    222   return (statBits);
    223 }
    224 
    225 /*****************************************************************************
    226 
    227     functionname: FDKaacEnc_encodeSectionData
    228     description:  encode section data (common Huffman codebooks for adjacent
    229                   SFB's)
    230     returns:      none
    231     input:
    232     output:
    233 
    234 *****************************************************************************/
    235 static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
    236                                        HANDLE_FDK_BITSTREAM hBitStream,
    237                                        UINT useVCB11)
    238 {
    239   if (hBitStream != NULL) {
    240     INT sectEscapeVal=0,sectLenBits=0;
    241     INT sectLen;
    242     INT i;
    243     INT dbgVal=FDKgetValidBits(hBitStream);
    244     INT sectCbBits = 4;
    245 
    246     switch(sectionData->blockType)
    247     {
    248     case LONG_WINDOW:
    249     case START_WINDOW:
    250     case STOP_WINDOW:
    251       sectEscapeVal = SECT_ESC_VAL_LONG;
    252       sectLenBits   = SECT_BITS_LONG;
    253       break;
    254 
    255     case SHORT_WINDOW:
    256       sectEscapeVal = SECT_ESC_VAL_SHORT;
    257       sectLenBits   = SECT_BITS_SHORT;
    258       break;
    259     }
    260 
    261     for(i=0;i<sectionData->noOfSections;i++)
    262     {
    263       INT codeBook = sectionData->huffsection[i].codeBook;
    264 
    265       FDKwriteBits(hBitStream,codeBook,sectCbBits);
    266 
    267       {
    268         sectLen = sectionData->huffsection[i].sfbCnt;
    269 
    270         while(sectLen >= sectEscapeVal)
    271         {
    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,
    298                                            INT                    globalGain)
    299 {
    300   if (hBitStream != NULL) {
    301     INT i,j,lastValScf,deltaScf;
    302     INT deltaPns;
    303     INT lastValPns = 0;
    304     INT noisePCMFlag = TRUE;
    305     INT lastValIs;
    306 
    307     INT dbgVal = FDKgetValidBits(hBitStream);
    308 
    309     lastValScf=scalefac[sectionData->firstScf];
    310     lastValPns = globalGain-scalefac[sectionData->firstScf]+globalGainOffset-4*LOG_NORM_PCM-noiseOffset;
    311     lastValIs  = 0;
    312 
    313     for(i=0; i<sectionData->noOfSections; i++){
    314       if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
    315 
    316         if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
    317             (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO))
    318         {
    319           INT sfbStart = sectionData->huffsection[i].sfbStart;
    320           INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
    321           for(j=sfbStart; j<tmp; j++) {
    322             INT deltaIs   = isScale[j]-lastValIs;
    323             lastValIs = isScale[j];
    324             if(FDKaacEnc_codeScalefactorDelta(deltaIs,hBitStream)) {
    325                 return(1);
    326             }
    327           } /* sfb */
    328         }
    329         else if(sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
    330           INT sfbStart = sectionData->huffsection[i].sfbStart;
    331           INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
    332           for(j=sfbStart; j<tmp; j++) {
    333             deltaPns   = noiseNrg[j]-lastValPns;
    334             lastValPns = noiseNrg[j];
    335 
    336             if(noisePCMFlag){
    337               FDKwriteBits(hBitStream,deltaPns+(1<<(PNS_PCM_BITS-1)),PNS_PCM_BITS);
    338               noisePCMFlag = FALSE;
    339             }
    340             else {
    341               if(FDKaacEnc_codeScalefactorDelta(deltaPns,hBitStream)) {
    342                 return(1);
    343               }
    344             }
    345           } /* sfb */
    346         }
    347         else {
    348           INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt;
    349           for(j=sectionData->huffsection[i].sfbStart; j<tmp; j++){
    350             /*
    351               check if we can repeat the last value to save bits
    352             */
    353             if(maxValueInSfb[j] == 0)
    354               deltaScf = 0;
    355             else{
    356               deltaScf = -(scalefac[j]-lastValScf);
    357               lastValScf = scalefac[j];
    358             }
    359             if(FDKaacEnc_codeScalefactorDelta(deltaScf,hBitStream)){
    360               return(1);
    361             }
    362           } /* sfb */
    363         } /* code scalefactor */
    364       } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
    365     } /* section loop */
    366 
    367     return(FDKgetValidBits(hBitStream)-dbgVal);
    368   } /* if (hBitStream != NULL) */
    369 
    370   return (0);
    371 }
    372 
    373 /*****************************************************************************
    374 
    375     functionname:encodeMsInfo
    376     description: encodes MS-Stereo Info
    377     returns:     the number of static bits
    378     input:
    379     output:
    380 
    381 *****************************************************************************/
    382 static INT FDKaacEnc_encodeMSInfo(INT            sfbCnt,
    383                                   INT            grpSfb,
    384                                   INT            maxSfb,
    385                                   INT            msDigest,
    386                                   INT           *jsFlags,
    387                                   HANDLE_FDK_BITSTREAM hBitStream)
    388 {
    389   INT sfb, sfbOff, msBits = 0;
    390 
    391   if (hBitStream != NULL)
    392   {
    393     switch(msDigest)
    394     {
    395     case MS_NONE:
    396       FDKwriteBits(hBitStream,SI_MS_MASK_NONE,2);
    397       msBits += 2;
    398       break;
    399 
    400     case MS_ALL:
    401       FDKwriteBits(hBitStream,SI_MS_MASK_ALL,2);
    402       msBits += 2;
    403       break;
    404 
    405     case MS_SOME:
    406       FDKwriteBits(hBitStream,SI_MS_MASK_SOME,2);
    407       msBits += 2;
    408       for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb)
    409       {
    410         for(sfb=0; sfb<maxSfb; sfb++)
    411         {
    412           if(jsFlags[sfbOff+sfb] & MS_ON){
    413             FDKwriteBits(hBitStream,1,1);
    414           }
    415           else{
    416             FDKwriteBits(hBitStream,0,1);
    417           }
    418           msBits += 1;
    419         }
    420       }
    421       break;
    422     }
    423   }
    424   else {
    425     msBits += 2;
    426     if (msDigest == MS_SOME) {
    427       for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
    428         for(sfb=0; sfb<maxSfb; sfb++) {
    429           msBits += 1;
    430         }
    431       }
    432     }
    433   }
    434   return (msBits);
    435 }
    436 
    437 /*****************************************************************************
    438 
    439     functionname: FDKaacEnc_encodeTnsDataPresent
    440     description:  encode TNS data (filter order, coeffs, ..)
    441     returns:      the number of static bits
    442     input:
    443     output:
    444 
    445 *****************************************************************************/
    446 static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo,
    447                                           INT blockType,
    448                                           HANDLE_FDK_BITSTREAM hBitStream)
    449 {
    450   if ( (hBitStream!=NULL) && (tnsInfo!=NULL) )
    451   {
    452     INT i, tnsPresent = 0;
    453     INT numOfWindows = (blockType==SHORT_WINDOW?TRANS_FAC:1);
    454 
    455     for (i=0; i<numOfWindows; i++) {
    456       if (tnsInfo->numOfFilters[i]!=0) {
    457         tnsPresent=1;
    458         break;
    459       }
    460     }
    461 
    462     if (tnsPresent==0) {
    463       FDKwriteBits(hBitStream,0,1);
    464     } else {
    465       FDKwriteBits(hBitStream,1,1);
    466     }
    467   }
    468   return (1);
    469 }
    470 
    471 /*****************************************************************************
    472 
    473     functionname: FDKaacEnc_encodeTnsData
    474     description:  encode TNS data (filter order, coeffs, ..)
    475     returns:      the number of static bits
    476     input:
    477     output:
    478 
    479 *****************************************************************************/
    480 static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo,
    481                                    INT blockType,
    482                                    HANDLE_FDK_BITSTREAM hBitStream)
    483 {
    484   INT tnsBits = 0;
    485 
    486   if (tnsInfo!=NULL) {
    487 
    488     INT i,j,k;
    489     INT tnsPresent = 0;
    490     INT coefBits;
    491     INT numOfWindows=(blockType==SHORT_WINDOW?TRANS_FAC:1);
    492 
    493     for (i=0; i<numOfWindows; i++) {
    494       if (tnsInfo->numOfFilters[i]!=0) {
    495         tnsPresent=1;
    496       }
    497     }
    498 
    499     if (hBitStream != NULL)
    500     {
    501       if (tnsPresent==1) { /* there is data to be written*/
    502         for (i=0; i<numOfWindows; i++) {
    503           FDKwriteBits(hBitStream,tnsInfo->numOfFilters[i],(blockType==SHORT_WINDOW?1:2));
    504           tnsBits += (blockType==SHORT_WINDOW?1:2);
    505           if (tnsInfo->numOfFilters[i]) {
    506             FDKwriteBits(hBitStream,(tnsInfo->coefRes[i]==4?1:0),1);
    507             tnsBits += 1;
    508           }
    509           for (j=0; j<tnsInfo->numOfFilters[i]; j++) {
    510             FDKwriteBits(hBitStream,tnsInfo->length[i][j],(blockType==SHORT_WINDOW?4:6));
    511             tnsBits += (blockType==SHORT_WINDOW?4:6);
    512             FDK_ASSERT(tnsInfo->order[i][j] <= 12);
    513             FDKwriteBits(hBitStream,tnsInfo->order[i][j],(blockType==SHORT_WINDOW?3:5));
    514             tnsBits += (blockType==SHORT_WINDOW?3:5);
    515             if (tnsInfo->order[i][j]){
    516               FDKwriteBits(hBitStream,tnsInfo->direction[i][j],1);
    517               tnsBits +=1; /*direction*/
    518               if(tnsInfo->coefRes[i] == 4) {
    519                 coefBits = 3;
    520                 for(k=0; k<tnsInfo->order[i][j]; k++) {
    521                   if (tnsInfo->coef[i][j][k]> 3 ||
    522                     tnsInfo->coef[i][j][k]< -4) {
    523                     coefBits = 4;
    524                     break;
    525                   }
    526                 }
    527               } else {
    528                 coefBits = 2;
    529                 for(k=0; k<tnsInfo->order[i][j]; k++) {
    530                   if ( tnsInfo->coef[i][j][k]> 1
    531                     || tnsInfo->coef[i][j][k]< -2) {
    532                     coefBits = 3;
    533                     break;
    534                   }
    535                 }
    536               }
    537               FDKwriteBits(hBitStream,-(coefBits - tnsInfo->coefRes[i]),1); /*coef_compres*/
    538               tnsBits +=1; /*coef_compression */
    539               for (k=0; k<tnsInfo->order[i][j]; k++ ) {
    540                 static const INT rmask[] = {0,1,3,7,15};
    541                 FDKwriteBits(hBitStream,tnsInfo->coef[i][j][k] & rmask[coefBits],coefBits);
    542                 tnsBits += coefBits;
    543               }
    544             }
    545           }
    546         }
    547       }
    548     }
    549     else {
    550       if (tnsPresent != 0) {
    551         for (i=0; i<numOfWindows; i++) {
    552           tnsBits += (blockType==SHORT_WINDOW?1:2);
    553           if (tnsInfo->numOfFilters[i]) {
    554             tnsBits += 1;
    555             for (j=0; j<tnsInfo->numOfFilters[i]; j++) {
    556               tnsBits += (blockType==SHORT_WINDOW?4:6);
    557               tnsBits += (blockType==SHORT_WINDOW?3:5);
    558               if (tnsInfo->order[i][j]) {
    559                 tnsBits +=1; /*direction*/
    560                 tnsBits +=1; /*coef_compression */
    561                 if (tnsInfo->coefRes[i] == 4) {
    562                   coefBits=3;
    563                   for (k=0; k<tnsInfo->order[i][j]; k++) {
    564                     if (tnsInfo->coef[i][j][k]> 3 || tnsInfo->coef[i][j][k]< -4) {
    565                       coefBits = 4;
    566                       break;
    567                     }
    568                   }
    569                 }
    570                 else {
    571                   coefBits = 2;
    572                   for (k=0; k<tnsInfo->order[i][j]; k++) {
    573                     if (tnsInfo->coef[i][j][k]> 1 || tnsInfo->coef[i][j][k]< -2) {
    574                       coefBits = 3;
    575                       break;
    576                     }
    577                   }
    578                 }
    579                 for (k=0; k<tnsInfo->order[i][j]; k++) {
    580                   tnsBits += coefBits;
    581                 }
    582               }
    583             }
    584           }
    585         }
    586       }
    587     }
    588   } /* (tnsInfo!=NULL) */
    589 
    590   return (tnsBits);
    591 }
    592 
    593 /*****************************************************************************
    594 
    595     functionname: FDKaacEnc_encodeGainControlData
    596     description:  unsupported
    597     returns:      none
    598     input:
    599     output:
    600 
    601 *****************************************************************************/
    602 static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream)
    603 {
    604   if (hBitStream != NULL) {
    605     FDKwriteBits(hBitStream,0,1);
    606   }
    607   return (1);
    608 }
    609 
    610 /*****************************************************************************
    611 
    612     functionname: FDKaacEnc_encodePulseData
    613     description:  not supported yet (dummy)
    614     returns:      none
    615     input:
    616     output:
    617 
    618 *****************************************************************************/
    619 static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream)
    620 {
    621   if (hBitStream != NULL) {
    622     FDKwriteBits(hBitStream,0,1);
    623   }
    624   return (1);
    625 }
    626 
    627 
    628 /*****************************************************************************
    629 
    630     functionname: FDKaacEnc_writeExtensionPayload
    631     description:  write extension payload to bitstream
    632     returns:      number of written bits
    633     input:
    634     output:
    635 
    636 *****************************************************************************/
    637 static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM  hBitStream,
    638                                             EXT_PAYLOAD_TYPE      extPayloadType,
    639                                             const UCHAR          *extPayloadData,
    640                                             INT                   extPayloadBits
    641                                           )
    642 {
    643   #define EXT_TYPE_BITS         ( 4 )
    644   #define DATA_EL_VERSION_BITS  ( 4 )
    645   #define FILL_NIBBLE_BITS      ( 4 )
    646 
    647   INT  extBitsUsed = 0;
    648 
    649   if (extPayloadBits >= EXT_TYPE_BITS)
    650   {
    651     UCHAR  fillByte = 0x00;  /* for EXT_FIL and EXT_FILL_DATA */
    652 
    653     if (hBitStream != NULL) {
    654       FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
    655     }
    656     extBitsUsed += EXT_TYPE_BITS;
    657 
    658     switch (extPayloadType) {
    659       case EXT_DYNAMIC_RANGE:
    660       /* case EXT_SAC_DATA: */
    661       case EXT_SBR_DATA:
    662       case EXT_SBR_DATA_CRC:
    663         if (hBitStream != NULL) {
    664           int i, writeBits = extPayloadBits;
    665           for (i=0; writeBits >= 8; i++) {
    666             FDKwriteBits(hBitStream, extPayloadData[i], 8);
    667             writeBits -= 8;
    668           }
    669           if (writeBits > 0) {
    670             FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
    671           }
    672         }
    673         extBitsUsed += extPayloadBits;
    674         break;
    675 
    676       case EXT_DATA_ELEMENT:
    677         {
    678           INT dataElementLength = (extPayloadBits+7)>>3;
    679           INT cnt = dataElementLength;
    680           int loopCounter = 1;
    681 
    682           while (dataElementLength >= 255) {
    683             loopCounter++;
    684             dataElementLength -= 255;
    685           }
    686 
    687           if (hBitStream != NULL) {
    688             int i;
    689             FDKwriteBits(hBitStream, 0x00, DATA_EL_VERSION_BITS);  /* data_element_version = ANC_DATA */
    690 
    691             for (i=1; i<loopCounter; i++) {
    692               FDKwriteBits(hBitStream, 255, 8);
    693             }
    694             FDKwriteBits(hBitStream, dataElementLength, 8);
    695 
    696             for (i=0; i<cnt; i++) {
    697               FDKwriteBits(hBitStream, extPayloadData[i], 8);
    698             }
    699           }
    700           extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter*8) + (cnt*8);
    701         }
    702         break;
    703 
    704       case EXT_FILL_DATA:
    705         fillByte = 0xA5;
    706       case EXT_FIL:
    707       default:
    708         if (hBitStream != NULL) {
    709           int writeBits = extPayloadBits;
    710           FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
    711           writeBits -= 8;  /* acount for the extension type and the fill nibble */
    712           while (writeBits >= 8) {
    713             FDKwriteBits(hBitStream, fillByte, 8);
    714             writeBits -= 8;
    715           }
    716         }
    717         extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
    718         break;
    719     }
    720   }
    721 
    722   return (extBitsUsed);
    723 }
    724 
    725 
    726 /*****************************************************************************
    727 
    728     functionname: FDKaacEnc_writeDataStreamElement
    729     description:  write data stream elements like ancillary data ...
    730     returns:      the amount of used bits
    731     input:
    732     output:
    733 
    734 ******************************************************************************/
    735 static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC  hTpEnc,
    736                                              INT    elementInstanceTag,
    737                                              INT    dataPayloadBytes,
    738                                              UCHAR *dataBuffer,
    739                                              UINT   alignAnchor )
    740 {
    741   #define DATA_BYTE_ALIGN_FLAG      ( 0 )
    742 
    743   #define EL_INSTANCE_TAG_BITS      ( 4 )
    744   #define DATA_BYTE_ALIGN_FLAG_BITS ( 1 )
    745   #define DATA_LEN_COUNT_BITS       ( 8 )
    746   #define DATA_LEN_ESC_COUNT_BITS   ( 8 )
    747 
    748   #define MAX_DATA_ALIGN_BITS       ( 7 )
    749   #define MAX_DSE_DATA_BYTES        ( 510 )
    750 
    751   INT  dseBitsUsed = 0;
    752 
    753   while (dataPayloadBytes > 0)
    754   {
    755     int esc_count = -1;
    756     int cnt = 0;
    757     INT crcReg = -1;
    758 
    759     dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS
    760                 +  DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
    761 
    762     if (DATA_BYTE_ALIGN_FLAG) {
    763       dseBitsUsed += MAX_DATA_ALIGN_BITS;
    764     }
    765 
    766     cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
    767     if ( cnt >= 255 ) {
    768       esc_count = cnt - 255;
    769       dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
    770     }
    771 
    772     dataPayloadBytes -= cnt;
    773     dseBitsUsed += cnt * 8;
    774 
    775     if (hTpEnc != NULL) {
    776       HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
    777       int i;
    778 
    779       FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
    780 
    781       crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
    782 
    783       FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
    784       FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
    785 
    786       /* write length field(s) */
    787       if ( esc_count >= 0 ) {
    788         FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
    789         FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
    790       } else {
    791         FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
    792       }
    793 
    794       if (DATA_BYTE_ALIGN_FLAG) {
    795         INT tmp = (INT)FDKgetValidBits(hBitStream);
    796         FDKbyteAlign(hBitStream, alignAnchor);
    797         /* count actual bits */
    798         dseBitsUsed += (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
    799       }
    800 
    801       /* write payload */
    802       for (i=0; i<cnt; i++) {
    803         FDKwriteBits(hBitStream, dataBuffer[i], 8);
    804       }
    805       transportEnc_CrcEndReg(hTpEnc, crcReg);
    806     }
    807   }
    808 
    809   return (dseBitsUsed);
    810 }
    811 
    812 
    813 /*****************************************************************************
    814 
    815     functionname: FDKaacEnc_writeExtensionData
    816     description:  write extension payload to bitstream
    817     returns:      number of written bits
    818     input:
    819     output:
    820 
    821 *****************************************************************************/
    822 INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC  hTpEnc,
    823                                   QC_OUT_EXTENSION    *pExtension,
    824                                   INT                  elInstanceTag, /* for DSE only */
    825                                   UINT                 alignAnchor,   /* for DSE only */
    826                                   UINT                 syntaxFlags,
    827                                   AUDIO_OBJECT_TYPE    aot,
    828                                   SCHAR                epConfig
    829                                 )
    830 {
    831   #define FILL_EL_COUNT_BITS      ( 4 )
    832   #define FILL_EL_ESC_COUNT_BITS  ( 8 )
    833   #define MAX_FILL_DATA_BYTES     ( 269 )
    834 
    835   HANDLE_FDK_BITSTREAM hBitStream = NULL;
    836   INT payloadBits = pExtension->nPayloadBits;
    837   INT extBitsUsed = 0;
    838 
    839   if (hTpEnc != NULL) {
    840     hBitStream = transportEnc_GetBitstream(hTpEnc);
    841   }
    842 
    843   if (syntaxFlags & (AC_SCALABLE|AC_ER))
    844   {
    845     if ( syntaxFlags & AC_DRM )
    846     { /* CAUTION: The caller has to assure that fill
    847                   data is written before the SBR payload. */
    848       UCHAR *extPayloadData = pExtension->pPayload;
    849 
    850       switch (pExtension->type)
    851       {
    852         case EXT_SBR_DATA:
    853         case EXT_SBR_DATA_CRC:
    854           /* SBR payload is written in reverse */
    855           if (hBitStream != NULL) {
    856             int   i, writeBits = payloadBits;
    857 
    858             FDKpushFor(hBitStream, payloadBits-1);  /* Does a cache sync internally */
    859 
    860             for (i=0; writeBits >= 8; i++) {
    861               FDKwriteBitsBwd(hBitStream, extPayloadData[i], 8);
    862               writeBits -= 8;
    863             }
    864             if (writeBits > 0) {
    865               FDKwriteBitsBwd(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
    866             }
    867 
    868             FDKsyncCacheBwd (hBitStream);
    869             FDKpushFor (hBitStream, payloadBits+1);
    870           }
    871           extBitsUsed += payloadBits;
    872           break;
    873 
    874         case EXT_FILL_DATA:
    875         case EXT_FIL:
    876         default:
    877           if (hBitStream != NULL) {
    878             int writeBits = payloadBits;
    879             while (writeBits >= 8) {
    880               FDKwriteBits(hBitStream, 0x00, 8);
    881               writeBits -= 8;
    882             }
    883             FDKwriteBits(hBitStream, 0x00, writeBits);
    884           }
    885           extBitsUsed += payloadBits;
    886           break;
    887       }
    888     }
    889     else {
    890       if ( (syntaxFlags & AC_ELD) && ((pExtension->type==EXT_SBR_DATA) || (pExtension->type==EXT_SBR_DATA_CRC)) ) {
    891 
    892         if (hBitStream != NULL) {
    893           int i, writeBits = payloadBits;
    894           UCHAR *extPayloadData = pExtension->pPayload;
    895 
    896           for (i=0; writeBits >= 8; i++) {
    897             FDKwriteBits(hBitStream, extPayloadData[i], 8);
    898             writeBits -= 8;
    899           }
    900           if (writeBits > 0) {
    901             FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
    902           }
    903         }
    904         extBitsUsed += payloadBits;
    905       }
    906       else
    907       {
    908         /* ER or scalable syntax -> write extension en bloc */
    909         extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
    910                                                         pExtension->type,
    911                                                         pExtension->pPayload,
    912                                                         payloadBits );
    913       }
    914     }
    915   }
    916   else {
    917     /* We have normal GA bitstream payload (AOT 2,5,29) so pack
    918        the data into a fill elements or DSEs */
    919 
    920     if ( pExtension->type == EXT_DATA_ELEMENT )
    921     {
    922       extBitsUsed += FDKaacEnc_writeDataStreamElement( hTpEnc,
    923                                                        elInstanceTag,
    924                                                        pExtension->nPayloadBits>>3,
    925                                                        pExtension->pPayload,
    926                                                        alignAnchor );
    927     }
    928     else {
    929       while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
    930         INT cnt, esc_count=-1, alignBits=7;
    931 
    932         if ( (pExtension->type == EXT_FILL_DATA) || (pExtension->type == EXT_FIL) )
    933         {
    934           payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
    935           if (payloadBits >= 15*8) {
    936             payloadBits -= FILL_EL_ESC_COUNT_BITS;
    937             esc_count = 0;  /* write esc_count even if cnt becomes smaller 15 */
    938           }
    939           alignBits = 0;
    940         }
    941 
    942         cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3);
    943 
    944         if (cnt >= 15) {
    945           esc_count = cnt - 15 + 1;
    946         }
    947 
    948         if (hBitStream != NULL) {
    949           /* write bitstream */
    950           FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
    951           if (esc_count >= 0) {
    952             FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
    953             FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
    954           } else {
    955             FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
    956           }
    957         }
    958 
    959         extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0);
    960 
    961         cnt = fixMin(cnt*8, payloadBits);  /* convert back to bits */
    962         extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
    963                                                         pExtension->type,
    964                                                         pExtension->pPayload,
    965                                                         cnt );
    966         payloadBits -= cnt;
    967       }
    968     }
    969   }
    970 
    971   return (extBitsUsed);
    972 }
    973 
    974 
    975 /*****************************************************************************
    976 
    977     functionname: FDKaacEnc_ByteAlignment
    978     description:
    979     returns:
    980     input:
    981     output:
    982 
    983 *****************************************************************************/
    984 static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, int alignBits)
    985 {
    986   FDKwriteBits(hBitStream, 0, alignBits);
    987 }
    988 
    989 AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC  hTpEnc,
    990                                                  ELEMENT_INFO        *pElInfo,
    991                                                  QC_OUT_CHANNEL      *qcOutChannel[(2)],
    992                                                  PSY_OUT_ELEMENT     *psyOutElement,
    993                                                  PSY_OUT_CHANNEL     *psyOutChannel[(2)],
    994                                                  UINT                 syntaxFlags,
    995                                                  AUDIO_OBJECT_TYPE    aot,
    996                                                  SCHAR                epConfig,
    997                                                  INT                 *pBitDemand,
    998                                                  UCHAR                minCnt
    999                                                )
   1000 {
   1001   AAC_ENCODER_ERROR error = AAC_ENC_OK;
   1002   HANDLE_FDK_BITSTREAM hBitStream = NULL;
   1003   INT    bitDemand = 0;
   1004   const  element_list_t *list;
   1005   int    i, ch, decision_bit;
   1006   INT    crcReg1 = -1, crcReg2 = -1;
   1007   UCHAR  numberOfChannels;
   1008 
   1009   if (hTpEnc != NULL) {
   1010     /* Get bitstream handle */
   1011     hBitStream = transportEnc_GetBitstream(hTpEnc);
   1012   }
   1013 
   1014   if ( (pElInfo->elType==ID_SCE) || (pElInfo->elType==ID_LFE) ) {
   1015     numberOfChannels = 1;
   1016   } else {
   1017     numberOfChannels = 2;
   1018   }
   1019 
   1020   /* Get channel element sequence table */
   1021   list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0);
   1022   if (list == NULL) {
   1023     error = AAC_ENC_UNSUPPORTED_AOT;
   1024     goto bail;
   1025   }
   1026 
   1027   if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) {
   1028     if (hBitStream != NULL) {
   1029       FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
   1030     }
   1031     bitDemand += EL_ID_BITS;
   1032   }
   1033 
   1034   /* Iterate through sequence table */
   1035   i = 0;
   1036   ch = 0;
   1037   decision_bit = 0;
   1038   do {
   1039     /* some tmp values */
   1040     SECTION_DATA *pChSectionData = NULL;
   1041     INT  *pChScf           = NULL;
   1042     UINT *pChMaxValueInSfb = NULL;
   1043     TNS_INFO *pTnsInfo     = NULL;
   1044     INT   chGlobalGain     = 0;
   1045     INT   chBlockType      = 0;
   1046     INT   chMaxSfbPerGrp   = 0;
   1047     INT   chSfbPerGrp      = 0;
   1048     INT   chSfbCnt         = 0;
   1049     INT   chFirstScf       = 0;
   1050 
   1051     if (minCnt==0) {
   1052       if ( qcOutChannel!=NULL ) {
   1053         pChSectionData   = &(qcOutChannel[ch]->sectionData);
   1054         pChScf           =  qcOutChannel[ch]->scf;
   1055         chGlobalGain     =  qcOutChannel[ch]->globalGain;
   1056         pChMaxValueInSfb =  qcOutChannel[ch]->maxValueInSfb;
   1057         chBlockType      =  pChSectionData->blockType;
   1058         chMaxSfbPerGrp   =  pChSectionData->maxSfbPerGroup;
   1059         chSfbPerGrp      =  pChSectionData->sfbPerGroup;
   1060         chSfbCnt         =  pChSectionData->sfbCnt;
   1061         chFirstScf       =  pChScf[pChSectionData->firstScf];
   1062       }
   1063       else {
   1064         /* get values from PSY */
   1065         chSfbCnt       = psyOutChannel[ch]->sfbCnt;
   1066         chSfbPerGrp    = psyOutChannel[ch]->sfbPerGroup;
   1067         chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
   1068       }
   1069       pTnsInfo = &psyOutChannel[ch]->tnsInfo;
   1070     } /* minCnt==0 */
   1071 
   1072     if ( qcOutChannel==NULL ) {
   1073       chBlockType    = psyOutChannel[ch]->lastWindowSequence;
   1074     }
   1075 
   1076     switch (list->id[i])
   1077     {
   1078     case element_instance_tag:
   1079       /* Write element instance tag */
   1080       if (hBitStream != NULL) {
   1081         FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
   1082       }
   1083       bitDemand += 4;
   1084       break;
   1085 
   1086     case common_window:
   1087       /* Write common window flag */
   1088       decision_bit = psyOutElement->commonWindow;
   1089       if (hBitStream != NULL) {
   1090         FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
   1091       }
   1092       bitDemand += 1;
   1093       break;
   1094 
   1095     case ics_info:
   1096       /* Write individual channel info */
   1097       bitDemand += FDKaacEnc_encodeIcsInfo( chBlockType,
   1098                                             psyOutChannel[ch]->windowShape,
   1099                                             psyOutChannel[ch]->groupingMask,
   1100                                             chMaxSfbPerGrp,
   1101                                             hBitStream,
   1102                                             syntaxFlags);
   1103       break;
   1104 
   1105     case ltp_data_present:
   1106       /* Write LTP data present flag */
   1107       if (hBitStream != NULL) {
   1108         FDKwriteBits(hBitStream, 0, 1);
   1109       }
   1110       bitDemand += 1;
   1111       break;
   1112 
   1113     case ltp_data:
   1114       /* Predictor data not supported.
   1115          Nothing to do here. */
   1116       break;
   1117 
   1118     case ms:
   1119       /* Write MS info */
   1120       bitDemand += FDKaacEnc_encodeMSInfo( chSfbCnt,
   1121                                            chSfbPerGrp,
   1122                                            chMaxSfbPerGrp,
   1123                                            (minCnt==0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
   1124                                            psyOutElement->toolsInfo.msMask,
   1125                                            hBitStream);
   1126       break;
   1127 
   1128     case global_gain:
   1129       bitDemand += FDKaacEnc_encodeGlobalGain( chGlobalGain,
   1130                                                chFirstScf,
   1131                                                hBitStream,
   1132                                                psyOutChannel[ch]->mdctScale );
   1133       break;
   1134 
   1135     case section_data:
   1136       {
   1137         INT siBits = FDKaacEnc_encodeSectionData(pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11)?1:0);
   1138         if (hBitStream != NULL) {
   1139           if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
   1140             error = AAC_ENC_WRITE_SEC_ERROR;
   1141           }
   1142         }
   1143         bitDemand += siBits;
   1144       }
   1145       break;
   1146 
   1147     case scale_factor_data:
   1148       {
   1149         INT sfDataBits = FDKaacEnc_encodeScaleFactorData( pChMaxValueInSfb,
   1150                                                           pChSectionData,
   1151                                                           pChScf,
   1152                                                           hBitStream,
   1153                                                           psyOutChannel[ch]->noiseNrg,
   1154                                                           psyOutChannel[ch]->isScale,
   1155                                                           chGlobalGain );
   1156         if ( (hBitStream != NULL)
   1157           && (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits + qcOutChannel[ch]->sectionData.noiseNrgBits)) ) {
   1158            error = AAC_ENC_WRITE_SCAL_ERROR;
   1159         }
   1160         bitDemand += sfDataBits;
   1161       }
   1162       break;
   1163 
   1164     case esc2_rvlc:
   1165       if (syntaxFlags & AC_ER_RVLC) {
   1166         /* write RVLC data into bitstream (error sens. cat. 2) */
   1167         error = AAC_ENC_UNSUPPORTED_AOT;
   1168       }
   1169       break;
   1170 
   1171     case pulse:
   1172       /* Write pulse data */
   1173       bitDemand += FDKaacEnc_encodePulseData(hBitStream);
   1174       break;
   1175 
   1176     case tns_data_present:
   1177       /* Write TNS data present flag */
   1178       bitDemand += FDKaacEnc_encodeTnsDataPresent(pTnsInfo,
   1179                                                   chBlockType,
   1180                                                   hBitStream);
   1181       break;
   1182     case tns_data:
   1183       /* Write TNS data */
   1184       bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo,
   1185                                            chBlockType,
   1186                                            hBitStream);
   1187       break;
   1188 
   1189     case gain_control_data:
   1190       /* Nothing to do here */
   1191       break;
   1192 
   1193     case gain_control_data_present:
   1194       bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
   1195       break;
   1196 
   1197 
   1198     case esc1_hcr:
   1199       if (syntaxFlags & AC_ER_HCR)
   1200       {
   1201         error = AAC_ENC_UNKNOWN;
   1202       }
   1203       break;
   1204 
   1205     case spectral_data:
   1206       if (hBitStream != NULL)
   1207       {
   1208         INT spectralBits = 0;
   1209 
   1210           spectralBits = FDKaacEnc_encodeSpectralData( psyOutChannel[ch]->sfbOffsets,
   1211                                                        pChSectionData,
   1212                                                        qcOutChannel[ch]->quantSpec,
   1213                                                        hBitStream );
   1214 
   1215         if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
   1216           return AAC_ENC_WRITE_SPEC_ERROR;
   1217         }
   1218         bitDemand += spectralBits;
   1219       }
   1220       break;
   1221 
   1222       /* Non data cases */
   1223     case adtscrc_start_reg1:
   1224       if (hTpEnc != NULL) {
   1225         crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
   1226       }
   1227       break;
   1228     case adtscrc_start_reg2:
   1229       if (hTpEnc != NULL) {
   1230         crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
   1231       }
   1232       break;
   1233     case adtscrc_end_reg1:
   1234     case drmcrc_end_reg:
   1235       if (hTpEnc != NULL) {
   1236         transportEnc_CrcEndReg(hTpEnc, crcReg1);
   1237       }
   1238       break;
   1239     case adtscrc_end_reg2:
   1240       if (hTpEnc != NULL) {
   1241         transportEnc_CrcEndReg(hTpEnc, crcReg2);
   1242       }
   1243       break;
   1244     case drmcrc_start_reg:
   1245       if (hTpEnc != NULL) {
   1246         crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
   1247       }
   1248       break;
   1249     case next_channel:
   1250       ch = (ch + 1) % numberOfChannels;
   1251       break;
   1252     case link_sequence:
   1253       list = list->next[decision_bit];
   1254       i=-1;
   1255       break;
   1256 
   1257     default:
   1258       error = AAC_ENC_UNKNOWN;
   1259       break;
   1260     }
   1261 
   1262     if (error != AAC_ENC_OK) {
   1263       return error;
   1264     }
   1265 
   1266     i++;
   1267 
   1268   } while (list->id[i] != end_of_sequence);
   1269 
   1270 bail:
   1271   if (pBitDemand != NULL) {
   1272     *pBitDemand = bitDemand;
   1273   }
   1274 
   1275   return error;
   1276 }
   1277 
   1278 
   1279 //-----------------------------------------------------------------------------------------------
   1280 
   1281 AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
   1282                                            CHANNEL_MAPPING *channelMapping,
   1283                                            QC_OUT *qcOut,
   1284                                            PSY_OUT* psyOut,
   1285                                            QC_STATE *qcKernel,
   1286                                            AUDIO_OBJECT_TYPE  aot,
   1287                                            UINT  syntaxFlags,
   1288                                            SCHAR  epConfig
   1289                                           )
   1290 {
   1291   HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
   1292   AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
   1293   int   i, n, doByteAlign = 1;
   1294   INT   bitMarkUp;
   1295   INT   frameBits;
   1296   /* Get first bit of raw data block.
   1297      In case of ADTS+PCE, AU would start at PCE.
   1298      This is okay because PCE assures alignment. */
   1299   UINT alignAnchor = FDKgetValidBits(hBs);
   1300 
   1301   frameBits = bitMarkUp = alignAnchor;
   1302 
   1303 
   1304   /* Channel element loop */
   1305   for (i=0; i<channelMapping->nElements; i++) {
   1306 
   1307     ELEMENT_INFO elInfo = channelMapping->elInfo[i];
   1308     INT elementUsedBits = 0;
   1309 
   1310     switch (elInfo.elType)
   1311     {
   1312         case ID_SCE:      /* single channel */
   1313         case ID_CPE:      /* channel pair */
   1314         case ID_LFE:      /* low freq effects channel */
   1315         {
   1316           if ( AAC_ENC_OK != (ErrorStatus = FDKaacEnc_ChannelElementWrite( hTpEnc,
   1317                                                       &elInfo,
   1318                                                        qcOut->qcElement[i]->qcOutChannel,
   1319                                                        psyOut->psyOutElement[i],
   1320                                                        psyOut->psyOutElement[i]->psyOutChannel,
   1321                                                        syntaxFlags,   /* syntaxFlags (ER tools ...) */
   1322                                                        aot,           /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
   1323                                                        epConfig,      /* epConfig -1, 0, 1 */
   1324                                                        NULL,
   1325                                                        0 )) )
   1326           {
   1327             return ErrorStatus;
   1328           }
   1329 
   1330           if ( !(syntaxFlags & AC_ER) )
   1331           {
   1332             /* Write associated extension payload */
   1333             for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
   1334               FDKaacEnc_writeExtensionData( hTpEnc,
   1335                                            &qcOut->qcElement[i]->extension[n],
   1336                                             0,
   1337                                             alignAnchor,
   1338                                             syntaxFlags,
   1339                                             aot,
   1340                                             epConfig );
   1341             }
   1342           }
   1343         }
   1344         break;
   1345 
   1346         /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
   1347         default:
   1348           return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
   1349 
   1350     }   /* switch */
   1351 
   1352     if(elInfo.elType != ID_DSE) {
   1353       elementUsedBits -= bitMarkUp;
   1354       bitMarkUp        = FDKgetValidBits(hBs);
   1355       elementUsedBits += bitMarkUp;
   1356       frameBits       += elementUsedBits;
   1357     }
   1358 
   1359   } /* for (i=0; i<channelMapping.nElements; i++) */
   1360 
   1361   if ( (syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM) )
   1362   {
   1363     UCHAR channelElementExtensionWritten[(8)][(1)]; /* 0: extension not touched, 1: extension already written */
   1364 
   1365     FDKmemclear(channelElementExtensionWritten, sizeof(channelElementExtensionWritten));
   1366 
   1367     if ( syntaxFlags & AC_ELD ) {
   1368 
   1369       for (i=0; i<channelMapping->nElements; i++) {
   1370         for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
   1371 
   1372           if ( (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA)
   1373             || (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA_CRC) )
   1374           {
   1375             /* Write sbr extension payload */
   1376             FDKaacEnc_writeExtensionData( hTpEnc,
   1377                                          &qcOut->qcElement[i]->extension[n],
   1378                                           0,
   1379                                           alignAnchor,
   1380                                           syntaxFlags,
   1381                                           aot,
   1382                                           epConfig );
   1383 
   1384             channelElementExtensionWritten[i][n] = 1;
   1385           } /* SBR */
   1386         } /* n */
   1387       } /* i */
   1388     } /* AC_ELD */
   1389 
   1390     for (i=0; i<channelMapping->nElements; i++) {
   1391       for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
   1392 
   1393         if (channelElementExtensionWritten[i][n]==0)
   1394         {
   1395           /* Write all ramaining extension payloads in element */
   1396           FDKaacEnc_writeExtensionData( hTpEnc,
   1397                                        &qcOut->qcElement[i]->extension[n],
   1398                                         0,
   1399                                         alignAnchor,
   1400                                         syntaxFlags,
   1401                                         aot,
   1402                                         epConfig );
   1403         }
   1404       } /* n */
   1405     } /* i */
   1406   } /* if AC_ER */
   1407 
   1408   /* Extend global extension payload table with fill bits */
   1409   if ( syntaxFlags & AC_DRM )
   1410   {
   1411     /* Exception for Drm */
   1412     for (n = 0; n < qcOut->nExtensions; n++) {
   1413       if ( (qcOut->extension[n].type == EXT_SBR_DATA)
   1414         || (qcOut->extension[n].type == EXT_SBR_DATA_CRC) ) {
   1415         /* SBR data must be the last extension! */
   1416         FDKmemcpy(&qcOut->extension[qcOut->nExtensions], &qcOut->extension[n], sizeof(QC_OUT_EXTENSION));
   1417         break;
   1418       }
   1419     }
   1420     /* Do byte alignment after AAC (+ MPS) payload.
   1421        Assure that MPS has been written as channel assigned extension payload! */
   1422     if (((FDKgetValidBits(hBs)-alignAnchor+(UINT)qcOut->totFillBits)&0x7)!=(UINT)qcOut->alignBits) {
   1423       return AAC_ENC_WRITTEN_BITS_ERROR;
   1424     }
   1425     FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
   1426     doByteAlign = 0;
   1427 
   1428   } /* AC_DRM */
   1429 
   1430   /* Add fill data / stuffing bits */
   1431   n = qcOut->nExtensions;
   1432   qcOut->extension[n].type = EXT_FILL_DATA;
   1433   qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
   1434   qcOut->nExtensions++;
   1435 
   1436   /* Write global extension payload and fill data */
   1437   for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
   1438   {
   1439     FDKaacEnc_writeExtensionData( hTpEnc,
   1440                                  &qcOut->extension[n],
   1441                                   0,
   1442                                   alignAnchor,
   1443                                   syntaxFlags,
   1444                                   aot,
   1445                                   epConfig );
   1446 
   1447     /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */
   1448   }
   1449 
   1450   if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) {
   1451     FDKwriteBits(hBs, ID_END, EL_ID_BITS);
   1452   }
   1453 
   1454   if (doByteAlign) {
   1455     /* Assure byte alignment*/
   1456     if (((alignAnchor-FDKgetValidBits(hBs))&0x7)!=(UINT)qcOut->alignBits) {
   1457       return AAC_ENC_WRITTEN_BITS_ERROR;
   1458     }
   1459 
   1460     FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
   1461   }
   1462 
   1463   frameBits -= bitMarkUp;
   1464   frameBits += FDKgetValidBits(hBs);
   1465 
   1466   transportEnc_EndAccessUnit(hTpEnc, &frameBits);
   1467 
   1468   if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){
   1469     return AAC_ENC_WRITTEN_BITS_ERROR;
   1470   }
   1471 
   1472   return ErrorStatus;
   1473 }
   1474 
   1475