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 Transport Encoder  ************************
     85 
     86    Author(s): Manuel Jander
     87    Description: MPEG Transport encode
     88 
     89 ******************************************************************************/
     90 
     91 #include "tpenc_lib.h"
     92 
     93 /* library info */
     94 #include "version"
     95 
     96 #define MODULE_NAME "transportEnc"
     97 
     98 #include "tpenc_asc.h"
     99 #include "conv_string.h"
    100 
    101 #include "tpenc_adts.h"
    102 
    103 #include "tpenc_adif.h"
    104 
    105 #include "tpenc_latm.h"
    106 
    107 
    108 
    109 typedef struct {
    110   int curSubFrame;
    111   int nSubFrames;
    112   int prevBits;
    113 } RAWPACKETS_INFO;
    114 
    115 struct TRANSPORTENC
    116 {
    117   CODER_CONFIG config;
    118   TRANSPORT_TYPE transportFmt;          /*!< MPEG4 transport type. */
    119 
    120   FDK_BITSTREAM bitStream;
    121   UCHAR *bsBuffer;
    122   INT bsBufferSize;
    123 
    124   INT pceFrameCounter;                  /*!< Indicates frame period when PCE must be written in raw_data_block.
    125                                              -1 means not to write a PCE in raw_dat_block. */
    126   union {
    127     STRUCT_ADTS adts;
    128 
    129     ADIF_INFO adif;
    130 
    131     LATM_STREAM latm;
    132 
    133     RAWPACKETS_INFO raw;
    134 
    135 
    136 
    137   } writer;
    138 
    139   CSTpCallBacks callbacks;
    140 };
    141 
    142 typedef struct _TRANSPORTENC_STRUCT TRANSPORTENC_STRUCT;
    143 
    144 
    145 /*
    146  * MEMORY Declaration
    147  */
    148 
    149 C_ALLOC_MEM(Ram_TransportEncoder, TRANSPORTENC, 1)
    150 
    151 TRANSPORTENC_ERROR transportEnc_Open( HANDLE_TRANSPORTENC *phTpEnc )
    152 {
    153   HANDLE_TRANSPORTENC hTpEnc = GetRam_TransportEncoder(0);
    154 
    155   if ( hTpEnc == NULL ) {
    156     return TRANSPORTENC_INVALID_PARAMETER;
    157   }
    158 
    159   *phTpEnc = hTpEnc;
    160   return TRANSPORTENC_OK;
    161 }
    162 
    163 /**
    164  * \brief  Get frame period of PCE in raw_data_block.
    165  *
    166  *  - Write PCE only if necessary. PCE can be part of the ASC if chConfig==0 whererfore
    167  *    no additonal PCE will be written in raw_data_block.
    168  * - A matrixMixdown coefficient can only be written if chConfig is 5.0 or 5.1.
    169  * - The PCE repetition rate in raw_data_block can be controlled via headerPeriod parameter.
    170  *
    171  * \param channelConfig         Channel Configuration derived from Channel Mode
    172  * \param transportFmt          Format of the transport to be written.
    173  * \param headerPeriod          Chosen PCE frame repetition rate.
    174  * \param matrixMixdownA        Indicates if a valid Matrix Mixdown coefficient is available.
    175  *
    176  * \return  PCE frame repetition rate. -1 means no PCE present in raw_data_block.
    177  */
    178 static INT getPceRepetitionRate(
    179         const int            channelConfig,
    180         const TRANSPORT_TYPE transportFmt,
    181         const int            headerPeriod,
    182         const int            matrixMixdownA
    183         )
    184 {
    185   INT pceFrameCounter = -1; /* variable to be returned */
    186 
    187   if (headerPeriod>0) {
    188     switch ( channelConfig ) {
    189       case 0:
    190         switch (transportFmt) {
    191           case TT_MP4_ADTS:
    192           case TT_MP4_LATM_MCP0:
    193           case TT_MP4_RAW:
    194             pceFrameCounter = headerPeriod;
    195             break;
    196           case TT_MP4_ADIF:                  /* ADIF header comprises PCE */
    197           case TT_MP4_LOAS:                  /* PCE in ASC if chChonfig==0 */
    198           case TT_MP4_LATM_MCP1:             /* PCE in ASC if chChonfig==0 */
    199           case TT_DRM:                       /* PCE not allowed in DRM */
    200           default:
    201             pceFrameCounter = -1;            /* no PCE in raw_data_block */
    202         }
    203         break;
    204       case 5: /* MODE_1_2_2 */
    205       case 6: /* MODE_1_2_2_1 */
    206         /* matrixMixdownCoefficient can only be written if 5.0 and 5.1 config present. */
    207         if (matrixMixdownA!=0) {
    208           switch (transportFmt) {
    209             case TT_MP4_ADIF:                /* ADIF header comprises PCE */
    210             case TT_MP4_ADTS:
    211             case TT_MP4_LOAS:                /* no PCE in ASC because chConfig!=0 */
    212             case TT_MP4_LATM_MCP1:           /* no PCE in ASC because chConfig!=0 */
    213             case TT_MP4_LATM_MCP0:
    214             case TT_MP4_RAW:
    215               pceFrameCounter = headerPeriod;
    216               break;
    217             case TT_DRM:                     /* PCE not allowed in DRM */
    218             default:
    219               pceFrameCounter = -1;          /* no PCE in raw_data_block */
    220           } /* switch transportFmt */
    221         } /* if matrixMixdownA!=0 */
    222         break;
    223       default:
    224         pceFrameCounter = -1;                /* no PCE in raw_data_block */
    225     } /* switch getChannelConfig() */
    226   } /* if headerPeriod>0  */
    227   else {
    228     pceFrameCounter = -1;                    /* no PCE in raw_data_block */
    229   }
    230 
    231   return pceFrameCounter;
    232 }
    233 
    234 TRANSPORTENC_ERROR transportEnc_Init(
    235         HANDLE_TRANSPORTENC hTpEnc,
    236         UCHAR             *bsBuffer,
    237         INT                bsBufferSize,
    238         TRANSPORT_TYPE     transportFmt,
    239         CODER_CONFIG      *cconfig,
    240         UINT               flags
    241         )
    242 {
    243   /* Copy configuration structure */
    244   FDKmemcpy(&hTpEnc->config, cconfig, sizeof(CODER_CONFIG));
    245 
    246   /* Init transportEnc struct. */
    247   hTpEnc->transportFmt = transportFmt;
    248 
    249   hTpEnc->bsBuffer = bsBuffer;
    250   hTpEnc->bsBufferSize = bsBufferSize;
    251 
    252   FDKinitBitStream(&hTpEnc->bitStream, hTpEnc->bsBuffer, hTpEnc->bsBufferSize, 0, BS_WRITER);
    253 
    254   switch (transportFmt) {
    255 
    256   case TT_MP4_ADIF:
    257     /* Sanity checks */
    258     if ( (hTpEnc->config.aot != AOT_AAC_LC)
    259        ||(hTpEnc->config.samplesPerFrame != 1024))
    260     {
    261       return TRANSPORTENC_INVALID_PARAMETER;
    262     }
    263     hTpEnc->writer.adif.headerWritten = 0;
    264     hTpEnc->writer.adif.samplingRate = hTpEnc->config.samplingRate;
    265     hTpEnc->writer.adif.bitRate = hTpEnc->config.bitRate;
    266     hTpEnc->writer.adif.profile = ((int)hTpEnc->config.aot) - 1;
    267     hTpEnc->writer.adif.cm = hTpEnc->config.channelMode;
    268     hTpEnc->writer.adif.bVariableRate = 0;
    269     hTpEnc->writer.adif.instanceTag = 0;
    270     break;
    271 
    272   case TT_MP4_ADTS:
    273     /* Sanity checks */
    274     if ( ( hTpEnc->config.aot != AOT_AAC_LC)
    275        ||(hTpEnc->config.samplesPerFrame != 1024) )
    276     {
    277       return TRANSPORTENC_INVALID_PARAMETER;
    278     }
    279     if ( adtsWrite_Init(&hTpEnc->writer.adts, &hTpEnc->config) != 0) {
    280       return TRANSPORTENC_INVALID_PARAMETER;
    281     }
    282     break;
    283 
    284   case TT_MP4_LOAS:
    285   case TT_MP4_LATM_MCP0:
    286   case TT_MP4_LATM_MCP1:
    287     {
    288       TRANSPORTENC_ERROR error;
    289 
    290       error = transportEnc_Latm_Init(
    291                 &hTpEnc->writer.latm,
    292                 &hTpEnc->bitStream,
    293                 &hTpEnc->config,
    294                  flags & TP_FLAG_LATM_AMV,
    295                  transportFmt,
    296                 &hTpEnc->callbacks
    297                  );
    298       if (error != TRANSPORTENC_OK) {
    299         return error;
    300       }
    301     }
    302     break;
    303 
    304   case TT_MP4_RAW:
    305     hTpEnc->writer.raw.curSubFrame = 0;
    306     hTpEnc->writer.raw.nSubFrames = hTpEnc->config.nSubFrames;
    307     break;
    308 
    309 
    310 
    311   default:
    312     return TRANSPORTENC_INVALID_PARAMETER;
    313   }
    314 
    315   /* pceFrameCounter indicates if PCE must be written in raw_data_block. */
    316   hTpEnc->pceFrameCounter = getPceRepetitionRate(
    317                     getChannelConfig(hTpEnc->config.channelMode),
    318                     transportFmt,
    319                     hTpEnc->config.headerPeriod,
    320                     hTpEnc->config.matrixMixdownA);
    321 
    322   return TRANSPORTENC_OK;
    323 }
    324 
    325 HANDLE_FDK_BITSTREAM transportEnc_GetBitstream( HANDLE_TRANSPORTENC hTp )
    326 {
    327   return &hTp->bitStream;
    328 }
    329 
    330 int transportEnc_RegisterSbrCallback( HANDLE_TRANSPORTENC hTpEnc, const cbSbr_t cbSbr, void* user_data)
    331 {
    332   if (hTpEnc == NULL) {
    333     return -1;
    334   }
    335   hTpEnc->callbacks.cbSbr = cbSbr;
    336   hTpEnc->callbacks.cbSbrData = user_data;
    337   return 0;
    338 }
    339 
    340 
    341 TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(
    342                                                HANDLE_TRANSPORTENC hTp,
    343                                                INT frameUsedBits,
    344                                                int bufferFullness,
    345                                                int ncc
    346                                               )
    347 {
    348   TRANSPORTENC_ERROR err = TRANSPORTENC_OK;
    349 
    350   if (!hTp) {
    351     return TRANSPORTENC_INVALID_PARAMETER;
    352   }
    353   HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream;
    354 
    355   /* In case of writing PCE in raw_data_block frameUsedBits must be adapted. */
    356   if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    357     frameUsedBits += transportEnc_GetPCEBits(hTp->config.channelMode, hTp->config.matrixMixdownA, 3); /* Consider 3 bits ID signalling in alignment */
    358   }
    359 
    360   switch (hTp->transportFmt) {
    361     case TT_MP4_ADIF:
    362       FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0, BS_WRITER);
    363       adifWrite_EncodeHeader(
    364              &hTp->writer.adif,
    365               hBs,
    366               bufferFullness
    367               );
    368       break;
    369     case TT_MP4_ADTS:
    370       bufferFullness /= ncc;                          /* Number of Considered Channels */
    371       bufferFullness /= 32;
    372       bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
    373       adtsWrite_EncodeHeader(
    374              &hTp->writer.adts,
    375              &hTp->bitStream,
    376               bufferFullness,
    377               frameUsedBits
    378               );
    379       break;
    380     case TT_MP4_LOAS:
    381     case TT_MP4_LATM_MCP0:
    382     case TT_MP4_LATM_MCP1:
    383       bufferFullness /= ncc;                         /* Number of Considered Channels */
    384       bufferFullness /= 32;
    385       bufferFullness = FDKmin(0xFF, bufferFullness); /* Signal variable rate */
    386       transportEnc_LatmWrite(
    387              &hTp->writer.latm,
    388               hBs,
    389               frameUsedBits,
    390               bufferFullness,
    391              &hTp->callbacks
    392               );
    393     break;
    394     case TT_MP4_RAW:
    395       if (hTp->writer.raw.curSubFrame >= hTp->writer.raw.nSubFrames) {
    396         hTp->writer.raw.curSubFrame = 0;
    397         FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0, BS_WRITER);
    398       }
    399       hTp->writer.raw.prevBits = FDKgetValidBits(hBs);
    400       break;
    401     default:
    402       err = TRANSPORTENC_UNSUPPORTED_FORMAT;
    403       break;
    404   }
    405 
    406   /* Write PCE in raw_data_block if required */
    407   if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    408     INT crcIndex = 0;
    409     /* Align inside PCE with repsect to the first bit of the raw_data_block() */
    410     UINT alignAnchor = FDKgetValidBits(&hTp->bitStream);
    411 
    412     /* Write PCE element ID bits */
    413     FDKwriteBits(&hTp->bitStream, ID_PCE, 3);
    414 
    415     if ( (hTp->transportFmt==TT_MP4_ADTS) && !hTp->writer.adts.protection_absent) {
    416       crcIndex = adtsWrite_CrcStartReg(&hTp->writer.adts, &hTp->bitStream, 0);
    417     }
    418 
    419     /* Write PCE as first raw_data_block element */
    420     transportEnc_writePCE(&hTp->bitStream, hTp->config.channelMode, hTp->config.samplingRate, 0, 1, hTp->config.matrixMixdownA, hTp->config.flags & CC_PSEUDO_SURROUND, alignAnchor);
    421 
    422     if ( (hTp->transportFmt==TT_MP4_ADTS) && !hTp->writer.adts.protection_absent) {
    423       adtsWrite_CrcEndReg(&hTp->writer.adts, &hTp->bitStream, crcIndex);
    424     }
    425     hTp->pceFrameCounter = 0; /* reset pce frame counter */
    426   }
    427 
    428   if (hTp->pceFrameCounter!=-1) {
    429     hTp->pceFrameCounter++; /* Update pceFrameCounter only if PCE writing is active. */
    430   }
    431 
    432   return err;
    433 }
    434 
    435 
    436 TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp, int *bits)
    437 {
    438   switch (hTp->transportFmt) {
    439     case TT_MP4_LATM_MCP0:
    440     case TT_MP4_LATM_MCP1:
    441     case TT_MP4_LOAS:
    442       transportEnc_LatmAdjustSubframeBits(&hTp->writer.latm, bits);
    443       break;
    444     case TT_MP4_ADTS:
    445       adtsWrite_EndRawDataBlock(&hTp->writer.adts, &hTp->bitStream, bits);
    446       break;
    447     case TT_MP4_ADIF:
    448       /* Substract ADIF header from AU bits, not to be considered. */
    449       *bits -= adifWrite_GetHeaderBits(&hTp->writer.adif);
    450       hTp->writer.adif.headerWritten = 1;
    451       break;
    452     case TT_MP4_RAW:
    453       *bits -= hTp->writer.raw.prevBits;
    454       break;
    455     default:
    456       break;
    457   }
    458 
    459   return TRANSPORTENC_OK;
    460 }
    461 
    462 TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc, int *nbytes)
    463 {
    464   HANDLE_FDK_BITSTREAM hBs = &hTpEnc->bitStream;
    465 
    466   switch (hTpEnc->transportFmt) {
    467     case TT_MP4_LATM_MCP0:
    468     case TT_MP4_LATM_MCP1:
    469     case TT_MP4_LOAS:
    470       *nbytes = hTpEnc->bsBufferSize;
    471       transportEnc_LatmGetFrame(&hTpEnc->writer.latm, hBs, nbytes);
    472       break;
    473     case TT_MP4_ADTS:
    474       if (hTpEnc->writer.adts.currentBlock >= hTpEnc->writer.adts.num_raw_blocks+1) {
    475         *nbytes = (FDKgetValidBits(hBs) + 7)>>3;
    476         hTpEnc->writer.adts.currentBlock = 0;
    477       } else {
    478         *nbytes = 0;
    479       }
    480       break;
    481     case TT_MP4_ADIF:
    482       FDK_ASSERT((INT)FDKgetValidBits(hBs) >= 0);
    483       *nbytes = (FDKgetValidBits(hBs) + 7)>>3;
    484       break;
    485     case TT_MP4_RAW:
    486       FDKsyncCache(hBs);
    487       hTpEnc->writer.raw.curSubFrame++;
    488       *nbytes = ((FDKgetValidBits(hBs)-hTpEnc->writer.raw.prevBits) + 7)>>3;
    489       break;
    490     default:
    491       break;
    492   }
    493 
    494   return TRANSPORTENC_OK;
    495 }
    496 
    497 INT transportEnc_GetStaticBits( HANDLE_TRANSPORTENC hTp, int auBits )
    498 {
    499   INT nbits = 0, nPceBits = 0;
    500 
    501   /* Write PCE within raw_data_block in transport lib. */
    502   if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    503     nPceBits = transportEnc_GetPCEBits(hTp->config.channelMode, hTp->config.matrixMixdownA, 3); /* Consider 3 bits ID signalling in alignment */
    504     auBits += nPceBits; /* Adapt required raw_data_block bit consumtpion for AU length information e.g. in LATM/LOAS configuration. */
    505   }
    506 
    507   switch (hTp->transportFmt) {
    508     case TT_MP4_ADIF:
    509     case TT_MP4_RAW:
    510       nbits = 0; /* Do not consider the ADIF header into the total bitrate */
    511       break;
    512     case TT_MP4_ADTS:
    513       nbits = adtsWrite_GetHeaderBits(&hTp->writer.adts);
    514       break;
    515     case TT_MP4_LOAS:
    516     case TT_MP4_LATM_MCP0:
    517     case TT_MP4_LATM_MCP1:
    518       nbits = transportEnc_LatmCountTotalBitDemandHeader( &hTp->writer.latm, auBits );
    519       break;
    520     default:
    521       nbits = 0;
    522       break;
    523   }
    524 
    525   /* PCE is written in the transport library therefore the bit consumption is part of the transport static bits. */
    526   nbits += nPceBits;
    527 
    528   return nbits;
    529 }
    530 
    531 void transportEnc_Close(HANDLE_TRANSPORTENC *phTp)
    532 {
    533   if (phTp != NULL)
    534   {
    535     if (*phTp != NULL) {
    536       FreeRam_TransportEncoder(phTp);
    537     }
    538   }
    539 }
    540 
    541 int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits)
    542 {
    543   int crcReg = 0;
    544 
    545   switch (hTpEnc->transportFmt) {
    546   case TT_MP4_ADTS:
    547     crcReg = adtsWrite_CrcStartReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, mBits);
    548     break;
    549   default:
    550     break;
    551   }
    552 
    553   return crcReg;
    554 }
    555 
    556 void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg)
    557 {
    558   switch (hTpEnc->transportFmt) {
    559   case TT_MP4_ADTS:
    560     adtsWrite_CrcEndReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, reg);
    561     break;
    562   default:
    563     break;
    564   }
    565 }
    566 
    567 
    568 TRANSPORTENC_ERROR transportEnc_GetConf(HANDLE_TRANSPORTENC  hTpEnc,
    569                                         CODER_CONFIG        *cc,
    570                                         FDK_BITSTREAM       *dataBuffer,
    571                                         UINT                *confType)
    572 {
    573   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
    574   HANDLE_LATM_STREAM hLatmConfig = &hTpEnc->writer.latm;
    575 
    576   *confType = 0; /* set confType variable to default */
    577 
    578   /* write StreamMuxConfig or AudioSpecificConfig depending on format used */
    579   switch (hTpEnc->transportFmt)
    580   {
    581     case TT_MP4_LATM_MCP0:
    582     case TT_MP4_LATM_MCP1:
    583     case TT_MP4_LOAS:
    584       tpErr = CreateStreamMuxConfig(hLatmConfig, dataBuffer, 0, &hTpEnc->callbacks);
    585       *confType = 1; /* config is SMC */
    586       break;
    587     default:
    588       if (transportEnc_writeASC(dataBuffer, cc, &hTpEnc->callbacks) != 0) {
    589         tpErr = TRANSPORTENC_UNKOWN_ERROR;
    590       }
    591   }
    592 
    593   return tpErr;
    594 
    595 }
    596 
    597 TRANSPORTENC_ERROR transportEnc_GetLibInfo( LIB_INFO *info )
    598 {
    599   int i;
    600 
    601   if (info == NULL) {
    602     return TRANSPORTENC_INVALID_PARAMETER;
    603   }
    604   /* search for next free tab */
    605   for (i = 0; i < FDK_MODULE_LAST; i++) {
    606     if (info[i].module_id == FDK_NONE) break;
    607   }
    608   if (i == FDK_MODULE_LAST) {
    609     return TRANSPORTENC_UNKOWN_ERROR;
    610   }
    611   info += i;
    612 
    613   info->module_id = FDK_TPENC;
    614   info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
    615   LIB_VERSION_STRING(info);
    616   info->build_date = __DATE__;
    617   info->build_time = __TIME__;
    618   info->title = TP_LIB_TITLE;
    619 
    620   /* Set flags */
    621   info->flags = 0
    622     | CAPF_ADIF
    623     | CAPF_ADTS
    624     | CAPF_LATM
    625     | CAPF_LOAS
    626     | CAPF_RAWPACKETS
    627     ;
    628 
    629   return TRANSPORTENC_OK;
    630 }
    631 
    632