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 /******************* MPEG transport format encoder library *********************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 #include "tpenc_latm.h"
    104 
    105 #include "genericStds.h"
    106 
    107 static const short celpFrameLengthTable[64] = {
    108     154, 170, 186, 147, 156, 165, 114, 120, 186, 126, 132, 138, 142,
    109     146, 154, 166, 174, 182, 190, 198, 206, 210, 214, 110, 114, 118,
    110     120, 122, 218, 230, 242, 254, 266, 278, 286, 294, 318, 342, 358,
    111     374, 390, 406, 422, 136, 142, 148, 154, 160, 166, 170, 174, 186,
    112     198, 206, 214, 222, 230, 238, 216, 160, 280, 338, 0,   0};
    113 
    114 /*******
    115  write value to transport stream
    116  first two bits define the size of the value itself
    117  then the value itself, with a size of 0-3 bytes
    118 *******/
    119 static UINT transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs, int value) {
    120   UCHAR valueBytes = 4;
    121   unsigned int bitsWritten = 0;
    122   int i;
    123 
    124   if (value < (1 << 8)) {
    125     valueBytes = 1;
    126   } else if (value < (1 << 16)) {
    127     valueBytes = 2;
    128   } else if (value < (1 << 24)) {
    129     valueBytes = 3;
    130   } else {
    131     valueBytes = 4;
    132   }
    133 
    134   FDKwriteBits(hBs, valueBytes - 1, 2); /* size of value in Bytes */
    135   for (i = 0; i < valueBytes; i++) {
    136     /* write most significant Byte first */
    137     FDKwriteBits(hBs, (UCHAR)(value >> ((valueBytes - 1 - i) << 3)), 8);
    138   }
    139 
    140   bitsWritten = (valueBytes << 3) + 2;
    141 
    142   return bitsWritten;
    143 }
    144 
    145 static UINT transportEnc_LatmCountFixBitDemandHeader(HANDLE_LATM_STREAM hAss) {
    146   int bitDemand = 0;
    147   int insertSetupData = 0;
    148 
    149   /* only if start of new latm frame */
    150   if (hAss->subFrameCnt == 0) {
    151     /* AudioSyncStream */
    152 
    153     if (hAss->tt == TT_MP4_LOAS) {
    154       bitDemand += 11; /* syncword */
    155       bitDemand += 13; /* audioMuxLengthBytes */
    156     }
    157 
    158     /* AudioMuxElement*/
    159 
    160     /* AudioMuxElement::Stream Mux Config */
    161     if (hAss->muxConfigPeriod > 0) {
    162       insertSetupData = (hAss->latmFrameCounter == 0);
    163     } else {
    164       insertSetupData = 0;
    165     }
    166 
    167     if (hAss->tt != TT_MP4_LATM_MCP0) {
    168       /* AudioMuxElement::useSameStreamMux Flag */
    169       bitDemand += 1;
    170 
    171       if (insertSetupData) {
    172         bitDemand += hAss->streamMuxConfigBits;
    173       }
    174     }
    175 
    176     /* AudioMuxElement::otherDataBits */
    177     bitDemand += hAss->otherDataLenBits;
    178 
    179     /* AudioMuxElement::ByteAlign */
    180     if (bitDemand % 8) {
    181       hAss->fillBits = 8 - (bitDemand % 8);
    182       bitDemand += hAss->fillBits;
    183     } else {
    184       hAss->fillBits = 0;
    185     }
    186   }
    187 
    188   return bitDemand;
    189 }
    190 
    191 static UINT transportEnc_LatmCountVarBitDemandHeader(
    192     HANDLE_LATM_STREAM hAss, unsigned int streamDataLength) {
    193   int bitDemand = 0;
    194   int prog, layer;
    195 
    196   /* Payload Length Info*/
    197   if (hAss->allStreamsSameTimeFraming) {
    198     for (prog = 0; prog < hAss->noProgram; prog++) {
    199       for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
    200         LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
    201 
    202         if (p_linfo->streamID >= 0) {
    203           switch (p_linfo->frameLengthType) {
    204             case 0:
    205               if (streamDataLength > 0) {
    206                 streamDataLength -= bitDemand;
    207                 while (streamDataLength >= (255 << 3)) {
    208                   bitDemand += 8;
    209                   streamDataLength -= (255 << 3);
    210                 }
    211                 bitDemand += 8;
    212               }
    213               break;
    214 
    215             case 1:
    216             case 4:
    217             case 6:
    218               bitDemand += 2;
    219               break;
    220 
    221             default:
    222               return 0;
    223           }
    224         }
    225       }
    226     }
    227   } else {
    228     /* there are many possibilities to use this mechanism.  */
    229     switch (hAss->varMode) {
    230       case LATMVAR_SIMPLE_SEQUENCE: {
    231         /* Use the sequence generated by the encoder */
    232         // int streamCntPosition = transportEnc_SetWritePointer(
    233         // hAss->hAssemble, 0 );  int streamCntPosition = FDKgetValidBits(
    234         // hAss->hAssemble );
    235         bitDemand += 4;
    236 
    237         hAss->varStreamCnt = 0;
    238         for (prog = 0; prog < hAss->noProgram; prog++) {
    239           for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
    240             LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
    241 
    242             if (p_linfo->streamID >= 0) {
    243               bitDemand += 4; /* streamID */
    244               switch (p_linfo->frameLengthType) {
    245                 case 0:
    246                   streamDataLength -= bitDemand;
    247                   while (streamDataLength >= (255 << 3)) {
    248                     bitDemand += 8;
    249                     streamDataLength -= (255 << 3);
    250                   }
    251 
    252                   bitDemand += 8;
    253                   break;
    254                   /*bitDemand += 1; endFlag
    255                   break;*/
    256 
    257                 case 1:
    258                 case 4:
    259                 case 6:
    260 
    261                   break;
    262 
    263                 default:
    264                   return 0;
    265               }
    266               hAss->varStreamCnt++;
    267             }
    268           }
    269         }
    270         bitDemand += 4;
    271         // transportEnc_UpdateBitstreamField( hAss->hAssemble,
    272         // streamCntPosition, hAss->varStreamCnt-1, 4 );  UINT pos =
    273         // streamCntPosition-FDKgetValidBits(hAss->hAssemble);  FDKpushBack(
    274         // hAss->hAssemble,  pos);  FDKwriteBits( hAss->hAssemble,
    275         // hAss->varStreamCnt-1, 4);  FDKpushFor( hAss->hAssemble, pos-4);
    276       } break;
    277 
    278       default:
    279         return 0;
    280     }
    281   }
    282 
    283   return bitDemand;
    284 }
    285 
    286 TRANSPORTENC_ERROR
    287 CreateStreamMuxConfig(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
    288                       int bufferFullness, CSTpCallBacks *cb) {
    289   INT streamIDcnt, tmp;
    290   int layer, prog;
    291 
    292   USHORT coreFrameOffset = 0;
    293 
    294   hAss->taraBufferFullness = 0xFF;
    295   hAss->audioMuxVersionA = 0; /* for future extensions */
    296   hAss->streamMuxConfigBits = 0;
    297 
    298   FDKwriteBits(hBs, hAss->audioMuxVersion, 1); /* audioMuxVersion */
    299   hAss->streamMuxConfigBits += 1;
    300 
    301   if (hAss->audioMuxVersion == 1) {
    302     FDKwriteBits(hBs, hAss->audioMuxVersionA, 1); /* audioMuxVersionA */
    303     hAss->streamMuxConfigBits += 1;
    304   }
    305 
    306   if (hAss->audioMuxVersionA == 0) {
    307     if (hAss->audioMuxVersion == 1) {
    308       hAss->streamMuxConfigBits += transportEnc_LatmWriteValue(
    309           hBs, hAss->taraBufferFullness); /* taraBufferFullness */
    310     }
    311     FDKwriteBits(hBs, hAss->allStreamsSameTimeFraming ? 1 : 0,
    312                  1);                             /* allStreamsSameTimeFraming */
    313     FDKwriteBits(hBs, hAss->noSubframes - 1, 6); /* Number of Subframes */
    314     FDKwriteBits(hBs, hAss->noProgram - 1, 4);   /* Number of Programs */
    315 
    316     hAss->streamMuxConfigBits += 11;
    317 
    318     streamIDcnt = 0;
    319     for (prog = 0; prog < hAss->noProgram; prog++) {
    320       int transLayer = 0;
    321 
    322       FDKwriteBits(hBs, hAss->noLayer[prog] - 1, 3);
    323       hAss->streamMuxConfigBits += 3;
    324 
    325       for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
    326         LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
    327         CODER_CONFIG *p_lci = hAss->config[prog][layer];
    328 
    329         p_linfo->streamID = -1;
    330 
    331         if (hAss->config[prog][layer] != NULL) {
    332           int useSameConfig = 0;
    333 
    334           if (transLayer > 0) {
    335             FDKwriteBits(hBs, useSameConfig ? 1 : 0, 1);
    336             hAss->streamMuxConfigBits += 1;
    337           }
    338           if ((useSameConfig == 0) || (transLayer == 0)) {
    339             const UINT alignAnchor = FDKgetValidBits(hBs);
    340 
    341             if (0 !=
    342                 (transportEnc_writeASC(hBs, hAss->config[prog][layer], cb))) {
    343               return TRANSPORTENC_UNKOWN_ERROR;
    344             }
    345 
    346             if (hAss->audioMuxVersion == 1) {
    347               UINT ascLen = transportEnc_LatmWriteValue(hBs, 0);
    348               FDKbyteAlign(hBs, alignAnchor);
    349               ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen;
    350               FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor);
    351 
    352               transportEnc_LatmWriteValue(hBs, ascLen);
    353 
    354               if (0 !=
    355                   (transportEnc_writeASC(hBs, hAss->config[prog][layer], cb))) {
    356                 return TRANSPORTENC_UNKOWN_ERROR;
    357               }
    358 
    359               FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */
    360             }
    361 
    362             hAss->streamMuxConfigBits +=
    363                 FDKgetValidBits(hBs) -
    364                 alignAnchor; /* add asc length to smc summary */
    365           }
    366           transLayer++;
    367 
    368           if (!hAss->allStreamsSameTimeFraming) {
    369             if (streamIDcnt >= LATM_MAX_STREAM_ID)
    370               return TRANSPORTENC_INVALID_CONFIG;
    371           }
    372           p_linfo->streamID = streamIDcnt++;
    373 
    374           switch (p_lci->aot) {
    375             case AOT_AAC_MAIN:
    376             case AOT_AAC_LC:
    377             case AOT_AAC_SSR:
    378             case AOT_AAC_LTP:
    379             case AOT_AAC_SCAL:
    380             case AOT_ER_AAC_LD:
    381             case AOT_ER_AAC_ELD:
    382             case AOT_USAC:
    383               p_linfo->frameLengthType = 0;
    384 
    385               FDKwriteBits(hBs, p_linfo->frameLengthType,
    386                            3);                      /* frameLengthType */
    387               FDKwriteBits(hBs, bufferFullness, 8); /* bufferFullness */
    388               hAss->streamMuxConfigBits += 11;
    389 
    390               if (!hAss->allStreamsSameTimeFraming) {
    391                 CODER_CONFIG *p_lci_prev = hAss->config[prog][layer - 1];
    392                 if (((p_lci->aot == AOT_AAC_SCAL) ||
    393                      (p_lci->aot == AOT_ER_AAC_SCAL)) &&
    394                     ((p_lci_prev->aot == AOT_CELP) ||
    395                      (p_lci_prev->aot == AOT_ER_CELP))) {
    396                   FDKwriteBits(hBs, coreFrameOffset, 6); /* coreFrameOffset */
    397                   hAss->streamMuxConfigBits += 6;
    398                 }
    399               }
    400               break;
    401 
    402             case AOT_TWIN_VQ:
    403               p_linfo->frameLengthType = 1;
    404               tmp = ((p_lci->bitsFrame + 7) >> 3) -
    405                     20; /* transmission frame length in bytes */
    406               if ((tmp < 0)) {
    407                 return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH;
    408               }
    409               FDKwriteBits(hBs, p_linfo->frameLengthType,
    410                            3); /* frameLengthType */
    411               FDKwriteBits(hBs, tmp, 9);
    412               hAss->streamMuxConfigBits += 12;
    413 
    414               p_linfo->frameLengthBits = (tmp + 20) << 3;
    415               break;
    416 
    417             case AOT_CELP:
    418               p_linfo->frameLengthType = 4;
    419               FDKwriteBits(hBs, p_linfo->frameLengthType,
    420                            3); /* frameLengthType */
    421               hAss->streamMuxConfigBits += 3;
    422               {
    423                 int i;
    424                 for (i = 0; i < 62; i++) {
    425                   if (celpFrameLengthTable[i] == p_lci->bitsFrame) break;
    426                 }
    427                 if (i >= 62) {
    428                   return TRANSPORTENC_INVALID_CELP_FRAME_LENGTH;
    429                 }
    430 
    431                 FDKwriteBits(hBs, i, 6); /* CELPframeLengthTabelIndex */
    432                 hAss->streamMuxConfigBits += 6;
    433               }
    434               p_linfo->frameLengthBits = p_lci->bitsFrame;
    435               break;
    436 
    437             case AOT_HVXC:
    438               p_linfo->frameLengthType = 6;
    439               FDKwriteBits(hBs, p_linfo->frameLengthType,
    440                            3); /* frameLengthType */
    441               hAss->streamMuxConfigBits += 3;
    442               {
    443                 int i;
    444 
    445                 if (p_lci->bitsFrame == 40) {
    446                   i = 0;
    447                 } else if (p_lci->bitsFrame == 80) {
    448                   i = 1;
    449                 } else {
    450                   return TRANSPORTENC_INVALID_FRAME_BITS;
    451                 }
    452                 FDKwriteBits(hBs, i, 1); /* HVXCframeLengthTableIndex */
    453                 hAss->streamMuxConfigBits += 1;
    454               }
    455               p_linfo->frameLengthBits = p_lci->bitsFrame;
    456               break;
    457 
    458             case AOT_NULL_OBJECT:
    459             default:
    460               return TRANSPORTENC_INVALID_AOT;
    461           }
    462         }
    463       }
    464     }
    465 
    466     FDKwriteBits(hBs, (hAss->otherDataLenBits > 0) ? 1 : 0,
    467                  1); /* otherDataPresent */
    468     hAss->streamMuxConfigBits += 1;
    469 
    470     if (hAss->otherDataLenBits > 0) {
    471       FDKwriteBits(hBs, 0, 1);
    472       FDKwriteBits(hBs, hAss->otherDataLenBits, 8);
    473       hAss->streamMuxConfigBits += 9;
    474     }
    475 
    476     FDKwriteBits(hBs, 0, 1); /* crcCheckPresent=0 */
    477     hAss->streamMuxConfigBits += 1;
    478 
    479   } else { /* if ( audioMuxVersionA == 0 ) */
    480 
    481     /* for future extensions */
    482   }
    483 
    484   return TRANSPORTENC_OK;
    485 }
    486 
    487 static TRANSPORTENC_ERROR WriteAuPayloadLengthInfo(
    488     HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits) {
    489   int restBytes;
    490 
    491   if (AuLengthBits % 8) return TRANSPORTENC_INVALID_AU_LENGTH;
    492 
    493   while (AuLengthBits >= 255 * 8) {
    494     FDKwriteBits(hBitStream, 255, 8); /* 255 shows incomplete AU */
    495     AuLengthBits -= (255 * 8);
    496   }
    497 
    498   restBytes = (AuLengthBits) >> 3;
    499   FDKwriteBits(hBitStream, restBytes, 8);
    500 
    501   return TRANSPORTENC_OK;
    502 }
    503 
    504 static TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes(
    505     HANDLE_LATM_STREAM hAss, INT noSubframes_next) /* nr of access units /
    506                                                       payloads within a latm
    507                                                       frame */
    508 {
    509   /* sanity chk */
    510   if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) {
    511     return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES;
    512   }
    513 
    514   hAss->noSubframes_next = noSubframes_next;
    515 
    516   /* if at start then we can take over the value immediately, otherwise we have
    517    * to wait for the next SMC */
    518   if ((hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0)) {
    519     hAss->noSubframes = noSubframes_next;
    520   }
    521 
    522   return TRANSPORTENC_OK;
    523 }
    524 
    525 static int allStreamsSameTimeFraming(HANDLE_LATM_STREAM hAss, UCHAR noProgram,
    526                                      UCHAR noLayer[] /* return */) {
    527   int prog, layer;
    528 
    529   signed int lastNoSamples = -1;
    530   signed int minFrameSamples = FDK_INT_MAX;
    531   signed int maxFrameSamples = 0;
    532 
    533   signed int highestSamplingRate = -1;
    534 
    535   for (prog = 0; prog < noProgram; prog++) {
    536     noLayer[prog] = 0;
    537 
    538     for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
    539       if (hAss->config[prog][layer] != NULL) {
    540         INT hsfSamplesFrame;
    541 
    542         noLayer[prog]++;
    543 
    544         if (highestSamplingRate < 0)
    545           highestSamplingRate = hAss->config[prog][layer]->samplingRate;
    546 
    547         hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame *
    548                           highestSamplingRate /
    549                           hAss->config[prog][layer]->samplingRate;
    550 
    551         if (hsfSamplesFrame <= minFrameSamples)
    552           minFrameSamples = hsfSamplesFrame;
    553         if (hsfSamplesFrame >= maxFrameSamples)
    554           maxFrameSamples = hsfSamplesFrame;
    555 
    556         if (lastNoSamples == -1) {
    557           lastNoSamples = hsfSamplesFrame;
    558         } else {
    559           if (hsfSamplesFrame != lastNoSamples) {
    560             return 0;
    561           }
    562         }
    563       }
    564     }
    565   }
    566 
    567   return 1;
    568 }
    569 
    570 /**
    571  * Initialize LATM/LOAS Stream and add layer 0 at program 0.
    572  */
    573 static TRANSPORTENC_ERROR transportEnc_InitLatmStream(
    574     HANDLE_LATM_STREAM hAss, int fractDelayPresent,
    575     signed int
    576         muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */
    577     UINT audioMuxVersion, TRANSPORT_TYPE tt) {
    578   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
    579 
    580   if (hAss == NULL) return TRANSPORTENC_INVALID_PARAMETER;
    581 
    582   hAss->tt = tt;
    583 
    584   hAss->noProgram = 1;
    585 
    586   hAss->audioMuxVersion = audioMuxVersion;
    587 
    588   /* Fill noLayer array using hAss->config */
    589   hAss->allStreamsSameTimeFraming =
    590       allStreamsSameTimeFraming(hAss, hAss->noProgram, hAss->noLayer);
    591   /* Only allStreamsSameTimeFraming==1 is supported */
    592   FDK_ASSERT(hAss->allStreamsSameTimeFraming);
    593 
    594   hAss->fractDelayPresent = fractDelayPresent;
    595   hAss->otherDataLenBits = 0;
    596 
    597   hAss->varMode = LATMVAR_SIMPLE_SEQUENCE;
    598 
    599   /* initialize counters */
    600   hAss->subFrameCnt = 0;
    601   hAss->noSubframes = DEFAULT_LATM_NR_OF_SUBFRAMES;
    602   hAss->noSubframes_next = DEFAULT_LATM_NR_OF_SUBFRAMES;
    603 
    604   /* sync layer related */
    605   hAss->audioMuxLengthBytes = 0;
    606 
    607   hAss->latmFrameCounter = 0;
    608   hAss->muxConfigPeriod = muxConfigPeriod;
    609 
    610   return ErrorStatus;
    611 }
    612 
    613 /**
    614  *
    615  */
    616 UINT transportEnc_LatmCountTotalBitDemandHeader(HANDLE_LATM_STREAM hAss,
    617                                                 unsigned int streamDataLength) {
    618   UINT bitDemand = 0;
    619 
    620   switch (hAss->tt) {
    621     case TT_MP4_LOAS:
    622     case TT_MP4_LATM_MCP0:
    623     case TT_MP4_LATM_MCP1:
    624       if (hAss->subFrameCnt == 0) {
    625         bitDemand = transportEnc_LatmCountFixBitDemandHeader(hAss);
    626       }
    627       bitDemand += transportEnc_LatmCountVarBitDemandHeader(
    628           hAss, streamDataLength /*- bitDemand*/);
    629       break;
    630     default:
    631       break;
    632   }
    633 
    634   return bitDemand;
    635 }
    636 
    637 static TRANSPORTENC_ERROR AdvanceAudioMuxElement(HANDLE_LATM_STREAM hAss,
    638                                                  HANDLE_FDK_BITSTREAM hBs,
    639                                                  int auBits, int bufferFullness,
    640                                                  CSTpCallBacks *cb) {
    641   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
    642   int insertMuxSetup;
    643 
    644   /* Insert setup data to assemble Buffer */
    645   if (hAss->subFrameCnt == 0) {
    646     if (hAss->muxConfigPeriod > 0) {
    647       insertMuxSetup = (hAss->latmFrameCounter == 0);
    648     } else {
    649       insertMuxSetup = 0;
    650     }
    651 
    652     if (hAss->tt != TT_MP4_LATM_MCP0) {
    653       if (insertMuxSetup) {
    654         FDKwriteBits(hBs, 0, 1); /* useSameStreamMux useNewStreamMux */
    655         if (TRANSPORTENC_OK != (ErrorStatus = CreateStreamMuxConfig(
    656                                     hAss, hBs, bufferFullness, cb))) {
    657           return ErrorStatus;
    658         }
    659       } else {
    660         FDKwriteBits(hBs, 1, 1); /* useSameStreamMux */
    661       }
    662     }
    663   }
    664 
    665   /* PayloadLengthInfo */
    666   {
    667     int prog, layer;
    668 
    669     for (prog = 0; prog < hAss->noProgram; prog++) {
    670       for (layer = 0; layer < hAss->noLayer[prog]; layer++) {
    671         ErrorStatus = WriteAuPayloadLengthInfo(hBs, auBits);
    672         if (ErrorStatus != TRANSPORTENC_OK) return ErrorStatus;
    673       }
    674     }
    675   }
    676   /* At this point comes the access unit. */
    677 
    678   return TRANSPORTENC_OK;
    679 }
    680 
    681 TRANSPORTENC_ERROR
    682 transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
    683                        int auBits, int bufferFullness, CSTpCallBacks *cb) {
    684   TRANSPORTENC_ERROR ErrorStatus;
    685 
    686   if (hAss->subFrameCnt == 0) {
    687     /* Start new frame */
    688     FDKresetBitbuffer(hBs, BS_WRITER);
    689   }
    690 
    691   hAss->latmSubframeStart = FDKgetValidBits(hBs);
    692 
    693   /* Insert syncword and syncword distance
    694      - only if loas
    695      - we must update the syncword distance (=audiomuxlengthbytes) later
    696    */
    697   if (hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0) {
    698     /* Start new LOAS frame */
    699     FDKwriteBits(hBs, 0x2B7, 11);
    700     hAss->audioMuxLengthBytes = 0;
    701     hAss->audioMuxLengthBytesPos =
    702         FDKgetValidBits(hBs); /* store read pointer position */
    703     FDKwriteBits(hBs, hAss->audioMuxLengthBytes, 13);
    704   }
    705 
    706   ErrorStatus = AdvanceAudioMuxElement(hAss, hBs, auBits, bufferFullness, cb);
    707 
    708   if (ErrorStatus != TRANSPORTENC_OK) return ErrorStatus;
    709 
    710   return ErrorStatus;
    711 }
    712 
    713 void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss, int *bits) {
    714   /* Substract bits from possible previous subframe */
    715   *bits -= hAss->latmSubframeStart;
    716   /* Add fill bits */
    717   if (hAss->subFrameCnt == 0) {
    718     *bits += hAss->otherDataLenBits;
    719     *bits += hAss->fillBits;
    720   }
    721 }
    722 
    723 TRANSPORTENC_ERROR transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,
    724                                              HANDLE_FDK_BITSTREAM hBs,
    725                                              int *pBytes) {
    726   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
    727 
    728   hAss->subFrameCnt++;
    729   if (hAss->subFrameCnt >= hAss->noSubframes) {
    730     /* Add LOAS frame length if required. */
    731     if (hAss->tt == TT_MP4_LOAS) {
    732       FDK_BITSTREAM tmpBuf;
    733 
    734       /* Determine frame length info */
    735       hAss->audioMuxLengthBytes =
    736           ((FDKgetValidBits(hBs) + hAss->otherDataLenBits + 7) >> 3) -
    737           3; /* 3=Syncword + length */
    738 
    739       /* Check frame length info */
    740       if (hAss->audioMuxLengthBytes >= (1 << 13)) {
    741         ErrorStatus = TRANSPORTENC_INVALID_AU_LENGTH;
    742         goto bail;
    743       }
    744 
    745       /* Write length info into assembler buffer */
    746       FDKinitBitStream(&tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0,
    747                        BS_WRITER);
    748       FDKpushFor(&tmpBuf, hAss->audioMuxLengthBytesPos);
    749       FDKwriteBits(&tmpBuf, hAss->audioMuxLengthBytes, 13);
    750       FDKsyncCache(&tmpBuf);
    751     }
    752 
    753     /* Write AudioMuxElement other data bits */
    754     FDKwriteBits(hBs, 0, hAss->otherDataLenBits);
    755 
    756     /* Write AudioMuxElement byte alignment fill bits */
    757     FDKwriteBits(hBs, 0, hAss->fillBits);
    758 
    759     FDK_ASSERT((FDKgetValidBits(hBs) % 8) == 0);
    760 
    761     hAss->subFrameCnt = 0;
    762 
    763     FDKsyncCache(hBs);
    764     *pBytes = (FDKgetValidBits(hBs) + 7) >> 3;
    765 
    766     if (hAss->muxConfigPeriod > 0) {
    767       hAss->latmFrameCounter++;
    768 
    769       if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) {
    770         hAss->latmFrameCounter = 0;
    771         hAss->noSubframes = hAss->noSubframes_next;
    772       }
    773     }
    774   } else {
    775     /* No data this time */
    776     *pBytes = 0;
    777   }
    778 
    779 bail:
    780   return ErrorStatus;
    781 }
    782 
    783 /**
    784  * Init LATM/LOAS
    785  */
    786 TRANSPORTENC_ERROR transportEnc_Latm_Init(HANDLE_LATM_STREAM hAss,
    787                                           HANDLE_FDK_BITSTREAM hBs,
    788                                           CODER_CONFIG *layerConfig,
    789                                           UINT audioMuxVersion,
    790                                           TRANSPORT_TYPE tt,
    791                                           CSTpCallBacks *cb) {
    792   TRANSPORTENC_ERROR ErrorStatus;
    793   int fractDelayPresent = 0;
    794   int prog, layer;
    795 
    796   int setupDataDistanceFrames = layerConfig->headerPeriod;
    797 
    798   FDK_ASSERT(setupDataDistanceFrames >= 0);
    799 
    800   for (prog = 0; prog < LATM_MAX_PROGRAMS; prog++) {
    801     for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
    802       hAss->config[prog][layer] = NULL;
    803       hAss->m_linfo[prog][layer].streamID = -1;
    804     }
    805   }
    806 
    807   hAss->config[0][0] = layerConfig;
    808   hAss->m_linfo[0][0].streamID = 0;
    809 
    810   ErrorStatus = transportEnc_InitLatmStream(hAss, fractDelayPresent,
    811                                             setupDataDistanceFrames,
    812                                             (audioMuxVersion) ? 1 : 0, tt);
    813   if (ErrorStatus != TRANSPORTENC_OK) goto bail;
    814 
    815   ErrorStatus =
    816       transportEnc_LatmSetNrOfSubframes(hAss, layerConfig->nSubFrames);
    817   if (ErrorStatus != TRANSPORTENC_OK) goto bail;
    818 
    819   /* Get the size of the StreamMuxConfig somehow */
    820   if (TRANSPORTENC_OK !=
    821       (ErrorStatus = AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb))) {
    822     goto bail;
    823   }
    824 
    825   // CreateStreamMuxConfig(hAss, hBs, 0);
    826 
    827 bail:
    828   return ErrorStatus;
    829 }
    830 
    831 TRANSPORTENC_ERROR transportEnc_LatmAddOtherDataBits(HANDLE_LATM_STREAM hAss,
    832                                                      const int otherDataBits) {
    833   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
    834 
    835   if ((hAss->otherDataLenBits != 0) || (otherDataBits % 8 != 0)) {
    836     /* This implementation allows to add other data bits only once.
    837        To keep existing alignment only whole bytes are allowed. */
    838     ErrorStatus = TRANSPORTENC_UNKOWN_ERROR;
    839   } else {
    840     /* Ensure correct addional bits in payload. */
    841     if (hAss->tt == TT_MP4_LATM_MCP0) {
    842       hAss->otherDataLenBits = otherDataBits;
    843     } else {
    844       hAss->otherDataLenBits = otherDataBits - 9;
    845       hAss->streamMuxConfigBits += 9;
    846     }
    847   }
    848 
    849   return ErrorStatus;
    850 }
    851