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 /**************************** SBR encoder library ******************************
     96 
     97    Author(s):   N. Rettelbach
     98 
     99    Description: Parametric Stereo bitstream encoder
    100 
    101 *******************************************************************************/
    102 
    103 #include "ps_bitenc.h"
    104 
    105 #include "ps_main.h"
    106 
    107 static inline UCHAR FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream,
    108                                            UINT value,
    109                                            const UINT numberOfBits) {
    110   /* hBitStream == NULL happens here intentionally */
    111   if (hBitStream != NULL) {
    112     FDKwriteBits(hBitStream, value, numberOfBits);
    113   }
    114   return numberOfBits;
    115 }
    116 
    117 #define SI_SBR_EXTENSION_SIZE_BITS 4
    118 #define SI_SBR_EXTENSION_ESC_COUNT_BITS 8
    119 #define SI_SBR_EXTENSION_ID_BITS 2
    120 #define EXTENSION_ID_PS_CODING 2
    121 #define PS_EXT_ID_V0 0
    122 
    123 static const INT iidDeltaCoarse_Offset = 14;
    124 static const INT iidDeltaCoarse_MaxVal = 28;
    125 static const INT iidDeltaFine_Offset = 30;
    126 static const INT iidDeltaFine_MaxVal = 60;
    127 
    128 /* PS Stereo Huffmantable: iidDeltaFreqCoarse */
    129 static const UINT iidDeltaFreqCoarse_Length[] = {
    130     17, 17, 17, 17, 16, 15, 13, 10, 9,  7,  6,  5,  4,  3, 1,
    131     3,  4,  5,  6,  6,  8,  11, 13, 14, 14, 15, 17, 18, 18};
    132 static const UINT iidDeltaFreqCoarse_Code[] = {
    133     0x0001fffb, 0x0001fffc, 0x0001fffd, 0x0001fffa, 0x0000fffc, 0x00007ffc,
    134     0x00001ffd, 0x000003fe, 0x000001fe, 0x0000007e, 0x0000003c, 0x0000001d,
    135     0x0000000d, 0x00000005, 0000000000, 0x00000004, 0x0000000c, 0x0000001c,
    136     0x0000003d, 0x0000003e, 0x000000fe, 0x000007fe, 0x00001ffc, 0x00003ffc,
    137     0x00003ffd, 0x00007ffd, 0x0001fffe, 0x0003fffe, 0x0003ffff};
    138 
    139 /* PS Stereo Huffmantable: iidDeltaFreqFine */
    140 static const UINT iidDeltaFreqFine_Length[] = {
    141     18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15,
    142     14, 14, 13, 12, 12, 11, 10, 10, 8,  7,  6,  5,  4,  3,  1,  3,
    143     4,  5,  6,  7,  8,  9,  10, 11, 11, 12, 13, 14, 14, 15, 16, 16,
    144     17, 17, 18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
    145 static const UINT iidDeltaFreqFine_Code[] = {
    146     0x0001feb4, 0x0001feb5, 0x0001fd76, 0x0001fd77, 0x0001fd74, 0x0001fd75,
    147     0x0001fe8a, 0x0001fe8b, 0x0001fe88, 0x0000fe80, 0x0001feb6, 0x0000fe82,
    148     0x0000feb8, 0x00007f42, 0x00007fae, 0x00003faf, 0x00001fd1, 0x00001fe9,
    149     0x00000fe9, 0x000007ea, 0x000007fb, 0x000003fb, 0x000001fb, 0x000001ff,
    150     0x0000007c, 0x0000003c, 0x0000001c, 0x0000000c, 0000000000, 0x00000001,
    151     0x00000001, 0x00000002, 0x00000001, 0x0000000d, 0x0000001d, 0x0000003d,
    152     0x0000007d, 0x000000fc, 0x000001fc, 0x000003fc, 0x000003f4, 0x000007eb,
    153     0x00000fea, 0x00001fea, 0x00001fd6, 0x00003fd0, 0x00007faf, 0x00007f43,
    154     0x0000feb9, 0x0000fe83, 0x0001feb7, 0x0000fe81, 0x0001fe89, 0x0001fe8e,
    155     0x0001fe8f, 0x0001fe8c, 0x0001fe8d, 0x0001feb2, 0x0001feb3, 0x0001feb0,
    156     0x0001feb1};
    157 
    158 /* PS Stereo Huffmantable: iidDeltaTimeCoarse */
    159 static const UINT iidDeltaTimeCoarse_Length[] = {
    160     19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8,  6,  4,  2, 1,
    161     3,  5,  7,  9,  11, 13, 14, 17, 19, 20, 20, 20, 20, 20};
    162 static const UINT iidDeltaTimeCoarse_Code[] = {
    163     0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9, 0x000ffffa,
    164     0x0001fffd, 0x00007ffe, 0x00000ffe, 0x000003fe, 0x000000fe, 0x0000003e,
    165     0x0000000e, 0x00000002, 0000000000, 0x00000006, 0x0000001e, 0x0000007e,
    166     0x000001fe, 0x000007fe, 0x00001ffe, 0x00003ffe, 0x0001fffc, 0x0007fff8,
    167     0x000ffffb, 0x000ffffc, 0x000ffffd, 0x000ffffe, 0x000fffff};
    168 
    169 /* PS Stereo Huffmantable: iidDeltaTimeFine */
    170 static const UINT iidDeltaTimeFine_Length[] = {
    171     16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14,
    172     14, 13, 13, 13, 12, 12, 11, 10, 9,  9,  7,  6,  5,  3,  1,  2,
    173     5,  6,  7,  8,  9,  10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
    174     15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
    175 static const UINT iidDeltaTimeFine_Code[] = {
    176     0x00004ed4, 0x00004ed5, 0x00004ece, 0x00004ecf, 0x00004ecc, 0x00004ed6,
    177     0x00004ed8, 0x00004f46, 0x00004f60, 0x00002718, 0x00002719, 0x00002764,
    178     0x00002765, 0x0000276d, 0x000027b1, 0x000013b7, 0x000013d6, 0x000009c7,
    179     0x000009e9, 0x000009ed, 0x000004ee, 0x000004f7, 0x00000278, 0x00000139,
    180     0x0000009a, 0x0000009f, 0x00000020, 0x00000011, 0x0000000a, 0x00000003,
    181     0x00000001, 0000000000, 0x0000000b, 0x00000012, 0x00000021, 0x0000004c,
    182     0x0000009b, 0x0000013a, 0x00000279, 0x00000270, 0x000004ef, 0x000004e2,
    183     0x000009ea, 0x000009d8, 0x000013d7, 0x000013d0, 0x000027b2, 0x000027a2,
    184     0x0000271a, 0x0000271b, 0x00004f66, 0x00004f67, 0x00004f61, 0x00004f47,
    185     0x00004ed9, 0x00004ed7, 0x00004ecd, 0x00004ed2, 0x00004ed3, 0x00004ed0,
    186     0x00004ed1};
    187 
    188 static const INT iccDelta_Offset = 7;
    189 static const INT iccDelta_MaxVal = 14;
    190 /* PS Stereo Huffmantable: iccDeltaFreq */
    191 static const UINT iccDeltaFreq_Length[] = {14, 14, 12, 10, 7, 5,  3, 1,
    192                                            2,  4,  6,  8,  9, 11, 13};
    193 static const UINT iccDeltaFreq_Code[] = {
    194     0x00003fff, 0x00003ffe, 0x00000ffe, 0x000003fe, 0x0000007e,
    195     0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e,
    196     0x0000003e, 0x000000fe, 0x000001fe, 0x000007fe, 0x00001ffe};
    197 
    198 /* PS Stereo Huffmantable: iccDeltaTime */
    199 static const UINT iccDeltaTime_Length[] = {14, 13, 11, 9, 7,  5,  3, 1,
    200                                            2,  4,  6,  8, 10, 12, 14};
    201 static const UINT iccDeltaTime_Code[] = {
    202     0x00003ffe, 0x00001ffe, 0x000007fe, 0x000001fe, 0x0000007e,
    203     0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e,
    204     0x0000003e, 0x000000fe, 0x000003fe, 0x00000ffe, 0x00003fff};
    205 
    206 static const INT ipdDelta_Offset = 0;
    207 static const INT ipdDelta_MaxVal = 7;
    208 /* PS Stereo Huffmantable: ipdDeltaFreq */
    209 static const UINT ipdDeltaFreq_Length[] = {1, 3, 4, 4, 4, 4, 4, 4};
    210 static const UINT ipdDeltaFreq_Code[] = {0x00000001, 0000000000, 0x00000006,
    211                                          0x00000004, 0x00000002, 0x00000003,
    212                                          0x00000005, 0x00000007};
    213 
    214 /* PS Stereo Huffmantable: ipdDeltaTime */
    215 static const UINT ipdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3};
    216 static const UINT ipdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000002,
    217                                          0x00000003, 0x00000002, 0000000000,
    218                                          0x00000003, 0x00000003};
    219 
    220 static const INT opdDelta_Offset = 0;
    221 static const INT opdDelta_MaxVal = 7;
    222 /* PS Stereo Huffmantable: opdDeltaFreq */
    223 static const UINT opdDeltaFreq_Length[] = {1, 3, 4, 4, 5, 5, 4, 3};
    224 static const UINT opdDeltaFreq_Code[] = {
    225     0x00000001, 0x00000001, 0x00000006, 0x00000004,
    226     0x0000000f, 0x0000000e, 0x00000005, 0000000000,
    227 };
    228 
    229 /* PS Stereo Huffmantable: opdDeltaTime */
    230 static const UINT opdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3};
    231 static const UINT opdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000001,
    232                                          0x00000007, 0x00000006, 0000000000,
    233                                          0x00000002, 0x00000003};
    234 
    235 static INT getNoBands(const INT mode) {
    236   INT noBands = 0;
    237 
    238   switch (mode) {
    239     case 0:
    240     case 3: /* coarse */
    241       noBands = PS_BANDS_COARSE;
    242       break;
    243     case 1:
    244     case 4: /* mid */
    245       noBands = PS_BANDS_MID;
    246       break;
    247     case 2:
    248     case 5:  /* fine not supported */
    249     default: /* coarse as default */
    250       noBands = PS_BANDS_COARSE;
    251   }
    252 
    253   return noBands;
    254 }
    255 
    256 static INT getIIDRes(INT iidMode) {
    257   if (iidMode < 3)
    258     return PS_IID_RES_COARSE;
    259   else
    260     return PS_IID_RES_FINE;
    261 }
    262 
    263 static INT encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val,
    264                            const INT nBands, const UINT *codeTable,
    265                            const UINT *lengthTable, const INT tableOffset,
    266                            const INT maxVal, INT *error) {
    267   INT bitCnt = 0;
    268   INT lastVal = 0;
    269   INT band;
    270 
    271   for (band = 0; band < nBands; band++) {
    272     INT delta = (val[band] - lastVal) + tableOffset;
    273     lastVal = val[band];
    274     if ((delta > maxVal) || (delta < 0)) {
    275       *error = 1;
    276       delta = delta > 0 ? maxVal : 0;
    277     }
    278     bitCnt +=
    279         FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
    280   }
    281 
    282   return bitCnt;
    283 }
    284 
    285 static INT encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val,
    286                            const INT *valLast, const INT nBands,
    287                            const UINT *codeTable, const UINT *lengthTable,
    288                            const INT tableOffset, const INT maxVal,
    289                            INT *error) {
    290   INT bitCnt = 0;
    291   INT band;
    292 
    293   for (band = 0; band < nBands; band++) {
    294     INT delta = (val[band] - valLast[band]) + tableOffset;
    295     if ((delta > maxVal) || (delta < 0)) {
    296       *error = 1;
    297       delta = delta > 0 ? maxVal : 0;
    298     }
    299     bitCnt +=
    300         FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
    301   }
    302 
    303   return bitCnt;
    304 }
    305 
    306 INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iidVal,
    307                         const INT *iidValLast, const INT nBands,
    308                         const PS_IID_RESOLUTION res, const PS_DELTA mode,
    309                         INT *error) {
    310   const UINT *codeTable;
    311   const UINT *lengthTable;
    312   INT bitCnt = 0;
    313 
    314   bitCnt = 0;
    315 
    316   switch (mode) {
    317     case PS_DELTA_FREQ:
    318       switch (res) {
    319         case PS_IID_RES_COARSE:
    320           codeTable = iidDeltaFreqCoarse_Code;
    321           lengthTable = iidDeltaFreqCoarse_Length;
    322           bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
    323                                     lengthTable, iidDeltaCoarse_Offset,
    324                                     iidDeltaCoarse_MaxVal, error);
    325           break;
    326         case PS_IID_RES_FINE:
    327           codeTable = iidDeltaFreqFine_Code;
    328           lengthTable = iidDeltaFreqFine_Length;
    329           bitCnt +=
    330               encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, lengthTable,
    331                               iidDeltaFine_Offset, iidDeltaFine_MaxVal, error);
    332           break;
    333         default:
    334           *error = 1;
    335       }
    336       break;
    337 
    338     case PS_DELTA_TIME:
    339       switch (res) {
    340         case PS_IID_RES_COARSE:
    341           codeTable = iidDeltaTimeCoarse_Code;
    342           lengthTable = iidDeltaTimeCoarse_Length;
    343           bitCnt += encodeDeltaTime(
    344               hBitBuf, iidVal, iidValLast, nBands, codeTable, lengthTable,
    345               iidDeltaCoarse_Offset, iidDeltaCoarse_MaxVal, error);
    346           break;
    347         case PS_IID_RES_FINE:
    348           codeTable = iidDeltaTimeFine_Code;
    349           lengthTable = iidDeltaTimeFine_Length;
    350           bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands,
    351                                     codeTable, lengthTable, iidDeltaFine_Offset,
    352                                     iidDeltaFine_MaxVal, error);
    353           break;
    354         default:
    355           *error = 1;
    356       }
    357       break;
    358 
    359     default:
    360       *error = 1;
    361   }
    362 
    363   return bitCnt;
    364 }
    365 
    366 INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal,
    367                         const INT *iccValLast, const INT nBands,
    368                         const PS_DELTA mode, INT *error) {
    369   const UINT *codeTable;
    370   const UINT *lengthTable;
    371   INT bitCnt = 0;
    372 
    373   switch (mode) {
    374     case PS_DELTA_FREQ:
    375       codeTable = iccDeltaFreq_Code;
    376       lengthTable = iccDeltaFreq_Length;
    377       bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable, lengthTable,
    378                                 iccDelta_Offset, iccDelta_MaxVal, error);
    379       break;
    380 
    381     case PS_DELTA_TIME:
    382       codeTable = iccDeltaTime_Code;
    383       lengthTable = iccDeltaTime_Length;
    384 
    385       bitCnt +=
    386           encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable,
    387                           lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
    388       break;
    389 
    390     default:
    391       *error = 1;
    392   }
    393 
    394   return bitCnt;
    395 }
    396 
    397 INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal,
    398                         const INT *ipdValLast, const INT nBands,
    399                         const PS_DELTA mode, INT *error) {
    400   const UINT *codeTable;
    401   const UINT *lengthTable;
    402   INT bitCnt = 0;
    403 
    404   switch (mode) {
    405     case PS_DELTA_FREQ:
    406       codeTable = ipdDeltaFreq_Code;
    407       lengthTable = ipdDeltaFreq_Length;
    408       bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable, lengthTable,
    409                                 ipdDelta_Offset, ipdDelta_MaxVal, error);
    410       break;
    411 
    412     case PS_DELTA_TIME:
    413       codeTable = ipdDeltaTime_Code;
    414       lengthTable = ipdDeltaTime_Length;
    415 
    416       bitCnt +=
    417           encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable,
    418                           lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
    419       break;
    420 
    421     default:
    422       *error = 1;
    423   }
    424 
    425   return bitCnt;
    426 }
    427 
    428 INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal,
    429                         const INT *opdValLast, const INT nBands,
    430                         const PS_DELTA mode, INT *error) {
    431   const UINT *codeTable;
    432   const UINT *lengthTable;
    433   INT bitCnt = 0;
    434 
    435   switch (mode) {
    436     case PS_DELTA_FREQ:
    437       codeTable = opdDeltaFreq_Code;
    438       lengthTable = opdDeltaFreq_Length;
    439       bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable, lengthTable,
    440                                 opdDelta_Offset, opdDelta_MaxVal, error);
    441       break;
    442 
    443     case PS_DELTA_TIME:
    444       codeTable = opdDeltaTime_Code;
    445       lengthTable = opdDeltaTime_Length;
    446 
    447       bitCnt +=
    448           encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable,
    449                           lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
    450       break;
    451 
    452     default:
    453       *error = 1;
    454   }
    455 
    456   return bitCnt;
    457 }
    458 
    459 static INT encodeIpdOpd(HANDLE_PS_OUT psOut, HANDLE_FDK_BITSTREAM hBitBuf) {
    460   INT bitCnt = 0;
    461   INT error = 0;
    462   INT env;
    463 
    464   FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1);
    465 
    466   if (psOut->enableIpdOpd == 1) {
    467     INT *ipdLast = psOut->ipdLast;
    468     INT *opdLast = psOut->opdLast;
    469 
    470     for (env = 0; env < psOut->nEnvelopes; env++) {
    471       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIPD[env], 1);
    472       bitCnt += FDKsbrEnc_EncodeIpd(hBitBuf, psOut->ipd[env], ipdLast,
    473                                     getNoBands(psOut->iidMode),
    474                                     psOut->deltaIPD[env], &error);
    475 
    476       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaOPD[env], 1);
    477       bitCnt += FDKsbrEnc_EncodeOpd(hBitBuf, psOut->opd[env], opdLast,
    478                                     getNoBands(psOut->iidMode),
    479                                     psOut->deltaOPD[env], &error);
    480     }
    481     /* reserved bit */
    482     bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, 1);
    483   }
    484 
    485   return bitCnt;
    486 }
    487 
    488 static INT getEnvIdx(const INT nEnvelopes, const INT frameClass) {
    489   INT envIdx = 0;
    490 
    491   switch (nEnvelopes) {
    492     case 0:
    493       envIdx = 0;
    494       break;
    495 
    496     case 1:
    497       if (frameClass == 0)
    498         envIdx = 1;
    499       else
    500         envIdx = 0;
    501       break;
    502 
    503     case 2:
    504       if (frameClass == 0)
    505         envIdx = 2;
    506       else
    507         envIdx = 1;
    508       break;
    509 
    510     case 3:
    511       envIdx = 2;
    512       break;
    513 
    514     case 4:
    515       envIdx = 3;
    516       break;
    517 
    518     default:
    519       /* unsupported number of envelopes */
    520       envIdx = 0;
    521   }
    522 
    523   return envIdx;
    524 }
    525 
    526 static INT encodePSExtension(const HANDLE_PS_OUT psOut,
    527                              HANDLE_FDK_BITSTREAM hBitBuf) {
    528   INT bitCnt = 0;
    529 
    530   if (psOut->enableIpdOpd == 1) {
    531     INT ipdOpdBits = 0;
    532     INT extSize = (2 + encodeIpdOpd(psOut, NULL) + 7) >> 3;
    533 
    534     if (extSize < 15) {
    535       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, extSize, 4);
    536     } else {
    537       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 15, 4);
    538       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize - 15), 8);
    539     }
    540 
    541     /* write ipd opd data */
    542     ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2);
    543     ipdOpdBits += encodeIpdOpd(psOut, hBitBuf);
    544 
    545     /* byte align the ipd opd data  */
    546     if (ipdOpdBits % 8)
    547       ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8 - (ipdOpdBits % 8)));
    548 
    549     bitCnt += ipdOpdBits;
    550   }
    551 
    552   return (bitCnt);
    553 }
    554 
    555 INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
    556                                HANDLE_FDK_BITSTREAM hBitBuf) {
    557   INT psExtEnable = 0;
    558   INT bitCnt = 0;
    559   INT error = 0;
    560   INT env;
    561 
    562   if (psOut != NULL) {
    563     /* PS HEADER */
    564     bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enablePSHeader, 1);
    565 
    566     if (psOut->enablePSHeader) {
    567       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIID, 1);
    568       if (psOut->enableIID) {
    569         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iidMode, 3);
    570       }
    571       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableICC, 1);
    572       if (psOut->enableICC) {
    573         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iccMode, 3);
    574       }
    575       if (psOut->enableIpdOpd) {
    576         psExtEnable = 1;
    577       }
    578       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psExtEnable, 1);
    579     }
    580 
    581     /* Frame class, number of envelopes */
    582     bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameClass, 1);
    583     bitCnt += FDKsbrEnc_WriteBits_ps(
    584         hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2);
    585 
    586     if (psOut->frameClass == 1) {
    587       for (env = 0; env < psOut->nEnvelopes; env++) {
    588         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameBorder[env], 5);
    589       }
    590     }
    591 
    592     if (psOut->enableIID == 1) {
    593       INT *iidLast = psOut->iidLast;
    594       for (env = 0; env < psOut->nEnvelopes; env++) {
    595         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIID[env], 1);
    596         bitCnt += FDKsbrEnc_EncodeIid(
    597             hBitBuf, psOut->iid[env], iidLast, getNoBands(psOut->iidMode),
    598             (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode), psOut->deltaIID[env],
    599             &error);
    600 
    601         iidLast = psOut->iid[env];
    602       }
    603     }
    604 
    605     if (psOut->enableICC == 1) {
    606       INT *iccLast = psOut->iccLast;
    607       for (env = 0; env < psOut->nEnvelopes; env++) {
    608         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaICC[env], 1);
    609         bitCnt += FDKsbrEnc_EncodeIcc(hBitBuf, psOut->icc[env], iccLast,
    610                                       getNoBands(psOut->iccMode),
    611                                       psOut->deltaICC[env], &error);
    612 
    613         iccLast = psOut->icc[env];
    614       }
    615     }
    616 
    617     if (psExtEnable != 0) {
    618       bitCnt += encodePSExtension(psOut, hBitBuf);
    619     }
    620 
    621   } /* if(psOut != NULL) */
    622 
    623   return bitCnt;
    624 }
    625