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 - 2012 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->audioMuxVersionA    = 0; /* for future extensions */
    300   hAss->streamMuxConfigBits = 0;
    301 
    302   FDKwriteBits( hBs, hAss->audioMuxVersion, 1 );                   /* audioMuxVersion */
    303   hAss->streamMuxConfigBits += 1;
    304 
    305   if ( hAss->audioMuxVersion == 1 ) {
    306     FDKwriteBits( hBs, hAss->audioMuxVersionA, 1 );                /* audioMuxVersionA */
    307     hAss->streamMuxConfigBits+=1;
    308   }
    309 
    310   if ( hAss->audioMuxVersionA == 0 )
    311   {
    312     if ( hAss->audioMuxVersion == 1 ) {
    313       hAss->streamMuxConfigBits+= transportEnc_LatmWriteValue( hBs, hAss->taraBufferFullness );/* taraBufferFullness */
    314     }
    315     FDKwriteBits( hBs, hAss->allStreamsSameTimeFraming ? 1:0, 1 ); /* allStreamsSameTimeFraming */
    316     FDKwriteBits( hBs, hAss->noSubframes-1, 6 );                   /* Number of Subframes */
    317     FDKwriteBits( hBs, hAss->noProgram-1, 4 );                     /* Number of Programs */
    318 
    319     hAss->streamMuxConfigBits+=11;
    320 
    321     streamIDcnt = 0;
    322     for( prog=0; prog<hAss->noProgram; prog++ ) {
    323       int transLayer = 0;
    324 
    325       FDKwriteBits( hBs, hAss->noLayer[prog]-1, 3 );
    326       hAss->streamMuxConfigBits+=3;
    327 
    328       for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) {
    329         LATM_LAYER_INFO   *p_linfo = &(hAss->m_linfo[prog][layer]);
    330         CODER_CONFIG *p_lci   = hAss->config[prog][layer];
    331 
    332         p_linfo->streamID = -1;
    333 
    334         if( hAss->config[prog][layer] != NULL ) {
    335           int useSameConfig = 0;
    336 
    337           if( transLayer > 0 ) {
    338             FDKwriteBits( hBs, useSameConfig ? 1 : 0, 1 );
    339             hAss->streamMuxConfigBits+=1;
    340           }
    341           if( (useSameConfig == 0) || (transLayer==0) ) {
    342             UINT bits;
    343 
    344             if ( hAss->audioMuxVersion == 1 ) {
    345               FDKpushFor(hBs, 2); /* align to ASC, even if we do not know the length of the "ascLen" field yet */
    346             }
    347 
    348             bits = FDKgetValidBits( hBs );
    349 
    350             transportEnc_writeASC(
    351                     hBs,
    352                     hAss->config[prog][layer],
    353                     cb
    354                     );
    355 
    356             bits = FDKgetValidBits( hBs ) - bits;
    357 
    358             if ( hAss->audioMuxVersion == 1 ) {
    359               FDKpushBack(hBs, bits+2);
    360               hAss->streamMuxConfigBits += transportEnc_LatmWriteValue( hBs, bits );
    361               transportEnc_writeASC(
    362                       hBs,
    363                       hAss->config[prog][layer],
    364                       cb
    365                       );
    366             }
    367 
    368             hAss->streamMuxConfigBits += bits; /* 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           case AOT_RSVD50:
    388             p_linfo->frameLengthType = 0;
    389 
    390             FDKwriteBits( hBs, p_linfo->frameLengthType, 3 );                        /* frameLengthType */
    391             FDKwriteBits( hBs, bufferFullness, 8 );                           /* bufferFullness */
    392             hAss->streamMuxConfigBits+=11;
    393 
    394             if ( !hAss->allStreamsSameTimeFraming ) {
    395               CODER_CONFIG *p_lci_prev = hAss->config[prog][layer-1];
    396               if ( ((p_lci->aot == AOT_AAC_SCAL) || (p_lci->aot == AOT_ER_AAC_SCAL)) &&
    397                    ((p_lci_prev->aot == AOT_CELP) || (p_lci_prev->aot == AOT_ER_CELP)) ) {
    398                 FDKwriteBits( hBs, coreFrameOffset, 6 );                      /* coreFrameOffset */
    399                 hAss->streamMuxConfigBits+=6;
    400               }
    401             }
    402             break;
    403 
    404           case AOT_TWIN_VQ:
    405             p_linfo->frameLengthType = 1;
    406             tmp = ( (p_lci->bitsFrame+7) >> 3 ) - 20;                            /* transmission frame length in bytes */
    407             if( (tmp < 0) ) {
    408               return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH;
    409             }
    410             FDKwriteBits( hBs, p_linfo->frameLengthType, 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, 3 );          /* frameLengthType */
    420             hAss->streamMuxConfigBits+=3;
    421             {
    422               int i;
    423               for( i=0; i<62; i++ ) {
    424                 if( celpFrameLengthTable[i] == p_lci->bitsFrame )
    425                   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, 3 );          /* frameLengthType */
    440             hAss->streamMuxConfigBits+=3;
    441             {
    442               int i;
    443 
    444               if( p_lci->bitsFrame == 40 ) {
    445                 i = 0;
    446               } else if( p_lci->bitsFrame == 80 ) {
    447                 i = 1;
    448               } else {
    449                 return TRANSPORTENC_INVALID_FRAME_BITS;
    450               }
    451               FDKwriteBits( hBs, i, 1 );                                /* HVXCframeLengthTableIndex */
    452               hAss->streamMuxConfigBits+=1;
    453             }
    454             p_linfo->frameLengthBits = p_lci->bitsFrame;
    455             break;
    456 
    457           case AOT_NULL_OBJECT:
    458           default:
    459             return TRANSPORTENC_INVALID_AOT;
    460           }
    461         }
    462       }
    463     }
    464 
    465     FDKwriteBits( hBs, (hAss->otherDataLenBytes>0) ? 1:0, 1 );      /* otherDataPresent */
    466     hAss->streamMuxConfigBits+=1;
    467 
    468     if( hAss->otherDataLenBytes > 0 ) {
    469 
    470       INT otherDataLenTmp = hAss->otherDataLenBytes;
    471       INT escCnt = 0;
    472       INT otherDataLenEsc = 1;
    473 
    474       while(otherDataLenTmp) {
    475         otherDataLenTmp >>= 8;
    476         escCnt ++;
    477       }
    478 
    479       do {
    480         otherDataLenTmp = (hAss->otherDataLenBytes>>(escCnt*8)) & 0xFF;
    481         escCnt--;
    482         otherDataLenEsc = escCnt>0;
    483 
    484         FDKwriteBits( hBs, otherDataLenEsc, 1 );
    485         FDKwriteBits( hBs, otherDataLenTmp, 8 );
    486         hAss->streamMuxConfigBits+=9;
    487       } while(otherDataLenEsc);
    488     }
    489 
    490     {
    491       USHORT crcCheckPresent=0;
    492       USHORT crcCheckSum=0;
    493 
    494       FDKwriteBits( hBs, crcCheckPresent, 1 );               /* crcCheckPresent */
    495       hAss->streamMuxConfigBits+=1;
    496       if ( crcCheckPresent ){
    497         FDKwriteBits( hBs, crcCheckSum, 8 );                 /* crcCheckSum */
    498         hAss->streamMuxConfigBits+=8;
    499       }
    500     }
    501 
    502   } else {  /* if ( audioMuxVersionA == 0 ) */
    503 
    504     /* for future extensions */
    505 
    506   }
    507 
    508   return TRANSPORTENC_OK;
    509 }
    510 
    511 
    512 static TRANSPORTENC_ERROR
    513 WriteAuPayloadLengthInfo( HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits )
    514 {
    515   int restBytes;
    516 
    517   if( AuLengthBits % 8 )
    518     return TRANSPORTENC_INVALID_AU_LENGTH;
    519 
    520   while( AuLengthBits >= 255*8 ) {
    521     FDKwriteBits( hBitStream, 255, 8 );  /* 255 shows incomplete AU */
    522     AuLengthBits -= (255*8);
    523   }
    524 
    525   restBytes = (AuLengthBits) >> 3;
    526   FDKwriteBits( hBitStream, restBytes, 8 );
    527 
    528   return TRANSPORTENC_OK;
    529 }
    530 
    531 static
    532 TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes( HANDLE_LATM_STREAM hAss,
    533                                                       INT noSubframes_next)    /* nr of access units / payloads within a latm frame */
    534 {
    535   /* sanity chk */
    536   if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) {
    537     return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES;
    538   }
    539 
    540   hAss->noSubframes_next = noSubframes_next;
    541 
    542   /* if at start then we can take over the value immediately, otherwise we have to wait for the next SMC */
    543   if ( (hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0) ) {
    544     hAss->noSubframes = noSubframes_next;
    545   }
    546 
    547   return TRANSPORTENC_OK;
    548 }
    549 
    550 static
    551 int allStreamsSameTimeFraming( HANDLE_LATM_STREAM hAss, UCHAR noProgram, UCHAR noLayer[] /* return */ )
    552 {
    553   int prog, layer;
    554 
    555   signed int lastNoSamples   = -1;
    556   signed int minFrameSamples = FDK_INT_MAX;
    557   signed int maxFrameSamples = 0;
    558 
    559   signed int highestSamplingRate = -1;
    560 
    561   for( prog=0; prog<noProgram; prog++ ) {
    562     noLayer[prog] = 0;
    563 
    564     for( layer=0; layer<LATM_MAX_LAYERS; layer++ )
    565     {
    566       if( hAss->config[prog][layer] != NULL )
    567       {
    568         INT hsfSamplesFrame;
    569 
    570         noLayer[prog]++;
    571 
    572         if( highestSamplingRate < 0 )
    573           highestSamplingRate = hAss->config[prog][layer]->samplingRate;
    574 
    575         hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame  * highestSamplingRate / hAss->config[prog][layer]->samplingRate;
    576 
    577         if( hsfSamplesFrame <= minFrameSamples ) minFrameSamples = hsfSamplesFrame;
    578         if( hsfSamplesFrame >= maxFrameSamples ) maxFrameSamples = hsfSamplesFrame;
    579 
    580         if( lastNoSamples == -1 ) {
    581           lastNoSamples                             = hsfSamplesFrame;
    582         } else {
    583           if( hsfSamplesFrame != lastNoSamples ) {
    584             return 0;
    585           }
    586         }
    587       }
    588     }
    589   }
    590 
    591   return 1;
    592 }
    593 
    594 /**
    595  * Initialize LATM/LOAS Stream and add layer 0 at program 0.
    596  */
    597 static
    598 TRANSPORTENC_ERROR transportEnc_InitLatmStream( HANDLE_LATM_STREAM hAss,
    599                                                 int                fractDelayPresent,
    600                                                 signed int         muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */
    601                                                 UINT               audioMuxVersion,
    602                                                 TRANSPORT_TYPE     tt
    603                                               )
    604 {
    605   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
    606 
    607   if (hAss == NULL)
    608     return TRANSPORTENC_INVALID_PARAMETER;
    609 
    610   hAss->tt = tt;
    611 
    612   hAss->noProgram = 1;
    613 
    614   hAss->audioMuxVersion = audioMuxVersion;
    615 
    616   /* Fill noLayer array using hAss->config */
    617   hAss->allStreamsSameTimeFraming = allStreamsSameTimeFraming( hAss, hAss->noProgram, hAss->noLayer );
    618   /* Only allStreamsSameTimeFraming==1 is supported */
    619   FDK_ASSERT(hAss->allStreamsSameTimeFraming);
    620 
    621   hAss->fractDelayPresent = fractDelayPresent;
    622   hAss->otherDataLenBytes = 0;
    623 
    624   hAss->varMode = LATMVAR_SIMPLE_SEQUENCE;
    625 
    626   /* initialize counters */
    627   hAss->subFrameCnt                  = 0;
    628   hAss->noSubframes                  = DEFAULT_LATM_NR_OF_SUBFRAMES;
    629   hAss->noSubframes_next             = DEFAULT_LATM_NR_OF_SUBFRAMES;
    630 
    631   /* sync layer related */
    632   hAss->audioMuxLengthBytes     = 0;
    633 
    634   hAss->latmFrameCounter        = 0;
    635   hAss->muxConfigPeriod = muxConfigPeriod;
    636 
    637   return ErrorStatus;
    638 }
    639 
    640 
    641 /**
    642  *
    643  */
    644 UINT transportEnc_LatmCountTotalBitDemandHeader ( HANDLE_LATM_STREAM hAss , unsigned int streamDataLength )
    645 {
    646   UINT bitDemand = 0;
    647 
    648   switch (hAss->tt) {
    649   case TT_MP4_LOAS:
    650   case TT_MP4_LATM_MCP0:
    651   case TT_MP4_LATM_MCP1:
    652     if (hAss->subFrameCnt == 0) {
    653       bitDemand  = transportEnc_LatmCountFixBitDemandHeader ( hAss );
    654     }
    655     bitDemand += transportEnc_LatmCountVarBitDemandHeader ( hAss , streamDataLength /*- bitDemand*/);
    656     break;
    657   default:
    658     break;
    659   }
    660 
    661   return bitDemand;
    662 }
    663 
    664 static TRANSPORTENC_ERROR
    665 AdvanceAudioMuxElement (
    666         HANDLE_LATM_STREAM   hAss,
    667         HANDLE_FDK_BITSTREAM hBs,
    668         int                  auBits,
    669         int                  bufferFullness,
    670         CSTpCallBacks    *cb
    671         )
    672 {
    673   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
    674   int insertMuxSetup;
    675 
    676   /* Insert setup data to assemble Buffer */
    677   if (hAss->subFrameCnt == 0)
    678   {
    679     if (hAss->muxConfigPeriod > 0) {
    680       insertMuxSetup = (hAss->latmFrameCounter == 0);
    681     } else  {
    682       insertMuxSetup = 0;
    683     }
    684 
    685     if (hAss->tt != TT_MP4_LATM_MCP0) {
    686       if( insertMuxSetup ) {
    687         FDKwriteBits( hBs, 0, 1 );  /* useSameStreamMux useNewStreamMux */
    688         CreateStreamMuxConfig(hAss, hBs, bufferFullness, cb);
    689         if (ErrorStatus != TRANSPORTENC_OK)
    690           return ErrorStatus;
    691       } else {
    692         FDKwriteBits( hBs, 1, 1 );   /* useSameStreamMux */
    693       }
    694     }
    695   }
    696 
    697   /* PayloadLengthInfo */
    698   {
    699     int prog, layer;
    700 
    701     for (prog = 0; prog < hAss->noProgram; prog++) {
    702       for (layer = 0; layer < hAss->noLayer[prog]; layer++) {
    703         ErrorStatus = WriteAuPayloadLengthInfo( hBs, auBits );
    704         if (ErrorStatus != TRANSPORTENC_OK)
    705           return ErrorStatus;
    706       }
    707     }
    708   }
    709   /* At this point comes the access unit. */
    710 
    711   return TRANSPORTENC_OK;
    712 }
    713 
    714 TRANSPORTENC_ERROR
    715 transportEnc_LatmWrite (
    716         HANDLE_LATM_STREAM    hAss,
    717         HANDLE_FDK_BITSTREAM  hBs,
    718         int                   auBits,
    719         int                   bufferFullness,
    720         CSTpCallBacks     *cb
    721         )
    722 {
    723   TRANSPORTENC_ERROR ErrorStatus;
    724 
    725   if (hAss->subFrameCnt == 0) {
    726     /* Start new frame */
    727     FDKresetBitbuffer(hBs, BS_WRITER);
    728   }
    729 
    730   hAss->latmSubframeStart = FDKgetValidBits(hBs);
    731 
    732   /* Insert syncword and syncword distance
    733      - only if loas
    734      - we must update the syncword distance (=audiomuxlengthbytes) later
    735    */
    736   if( hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0)
    737   {
    738     /* Start new LOAS frame */
    739     FDKwriteBits( hBs, 0x2B7, 11 );
    740     hAss->audioMuxLengthBytes = 0;
    741     hAss->audioMuxLengthBytesPos = FDKgetValidBits( hBs );  /* store read pointer position */
    742     FDKwriteBits( hBs, hAss->audioMuxLengthBytes, 13 );
    743   }
    744 
    745   ErrorStatus = AdvanceAudioMuxElement(
    746           hAss,
    747           hBs,
    748           auBits,
    749           bufferFullness,
    750           cb
    751           );
    752 
    753   if (ErrorStatus != TRANSPORTENC_OK)
    754     return ErrorStatus;
    755 
    756   return ErrorStatus;
    757 }
    758 
    759 void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM    hAss,
    760                                          int                  *bits)
    761 {
    762   /* Substract bits from possible previous subframe */
    763   *bits -= hAss->latmSubframeStart;
    764   /* Add fill bits */
    765   if (hAss->subFrameCnt == 0)
    766     *bits += hAss->fillBits;
    767 }
    768 
    769 
    770 void transportEnc_LatmGetFrame(HANDLE_LATM_STREAM    hAss,
    771                                HANDLE_FDK_BITSTREAM  hBs,
    772                                int                  *bytes)
    773 {
    774 
    775   hAss->subFrameCnt++;
    776   if (hAss->subFrameCnt >= hAss->noSubframes)
    777   {
    778 
    779     /* Add LOAS frame length if required. */
    780     if (hAss->tt == TT_MP4_LOAS)
    781     {
    782       int latmBytes;
    783 
    784       latmBytes = (FDKgetValidBits(hBs)+7) >> 3;
    785 
    786       /* write length info into assembler buffer */
    787       hAss->audioMuxLengthBytes = latmBytes - 3; /* 3=Syncword + length */
    788       {
    789         FDK_BITSTREAM tmpBuf;
    790 
    791         FDKinitBitStream( &tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER ) ;
    792         FDKpushFor( &tmpBuf, hAss->audioMuxLengthBytesPos );
    793         FDKwriteBits( &tmpBuf, hAss->audioMuxLengthBytes, 13 );
    794         FDKsyncCache( &tmpBuf );
    795       }
    796     }
    797 
    798     /* Write AudioMuxElement byte alignment fill bits */
    799     FDKwriteBits(hBs, 0, hAss->fillBits);
    800 
    801     FDK_ASSERT( (FDKgetValidBits(hBs) % 8) == 0);
    802 
    803     hAss->subFrameCnt = 0;
    804 
    805     FDKsyncCache(hBs);
    806     *bytes = (FDKgetValidBits(hBs) + 7)>>3;
    807     //FDKfetchBuffer(hBs, buffer, (UINT*)bytes);
    808 
    809     if (hAss->muxConfigPeriod > 0)
    810     {
    811       hAss->latmFrameCounter++;
    812 
    813       if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) {
    814         hAss->latmFrameCounter = 0;
    815         hAss->noSubframes = hAss->noSubframes_next;
    816       }
    817     }
    818   } else {
    819     /* No data this time */
    820     *bytes = 0;
    821   }
    822 }
    823 
    824 /**
    825  * Init LATM/LOAS
    826  */
    827 TRANSPORTENC_ERROR transportEnc_Latm_Init(
    828         HANDLE_LATM_STREAM  hAss,
    829         HANDLE_FDK_BITSTREAM hBs,
    830         CODER_CONFIG  *layerConfig,
    831         UINT audioMuxVersion,
    832         TRANSPORT_TYPE tt,
    833         CSTpCallBacks *cb
    834         )
    835 {
    836   TRANSPORTENC_ERROR ErrorStatus;
    837   int fractDelayPresent = 0;
    838   int prog, layer;
    839 
    840   int setupDataDistanceFrames = layerConfig->headerPeriod;
    841 
    842   FDK_ASSERT(setupDataDistanceFrames>=0);
    843 
    844   for (prog=0; prog<LATM_MAX_PROGRAMS; prog++) {
    845     for (layer=0; layer<LATM_MAX_LAYERS; layer++) {
    846       hAss->config[prog][layer] = NULL;
    847       hAss->m_linfo[prog][layer].streamID = -1;
    848     }
    849   }
    850 
    851   hAss->config[0][0] = layerConfig;
    852   hAss->m_linfo[0][0].streamID = 0;
    853 
    854   ErrorStatus = transportEnc_InitLatmStream( hAss,
    855                                              fractDelayPresent,
    856                                              setupDataDistanceFrames,
    857                                              (audioMuxVersion)?1:0,
    858                                              tt
    859                                              );
    860   if (ErrorStatus != TRANSPORTENC_OK)
    861     goto bail;
    862 
    863   ErrorStatus = transportEnc_LatmSetNrOfSubframes(
    864                                                    hAss,
    865                                                    layerConfig->nSubFrames
    866                                                   );
    867   if (ErrorStatus != TRANSPORTENC_OK)
    868     goto bail;
    869 
    870   /* Get the size of the StreamMuxConfig somehow */
    871   AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb);
    872   //CreateStreamMuxConfig(hAss, hBs, 0);
    873 
    874 bail:
    875   return ErrorStatus;
    876 }
    877 
    878 
    879 
    880 
    881 
    882 
    883