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