Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten
      5 Forschung e.V. All rights reserved.
      6 
      7  1.    INTRODUCTION
      8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
      9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
     10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
     11 a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
     14 general perceptual audio codecs. AAC-ELD is considered the best-performing
     15 full-bandwidth communications codec by independent studies and is widely
     16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
     17 specifications.
     18 
     19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
     20 those of Fraunhofer) may be obtained through Via Licensing
     21 (www.vialicensing.com) or through the respective patent owners individually for
     22 the purpose of encoding or decoding bit streams in products that are compliant
     23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
     24 Android devices already license these patent claims through Via Licensing or
     25 directly from the patent owners, and therefore FDK AAC Codec software may
     26 already be covered under those patent licenses when it is used for those
     27 licensed purposes only.
     28 
     29 Commercially-licensed AAC software libraries, including floating-point versions
     30 with enhanced sound quality, are also available from Fraunhofer. Users are
     31 encouraged to check the Fraunhofer website for additional applications
     32 information and documentation.
     33 
     34 2.    COPYRIGHT LICENSE
     35 
     36 Redistribution and use in source and binary forms, with or without modification,
     37 are permitted without payment of copyright license fees provided that you
     38 satisfy the following conditions:
     39 
     40 You must retain the complete text of this software license in redistributions of
     41 the FDK AAC Codec or your modifications thereto in source code form.
     42 
     43 You must retain the complete text of this software license in the documentation
     44 and/or other materials provided with redistributions of the FDK AAC Codec or
     45 your modifications thereto in binary form. You must make available free of
     46 charge copies of the complete source code of the FDK AAC Codec and your
     47 modifications thereto to recipients of copies in binary form.
     48 
     49 The name of Fraunhofer may not be used to endorse or promote products derived
     50 from this library without prior written permission.
     51 
     52 You may not charge copyright license fees for anyone to use, copy or distribute
     53 the FDK AAC Codec software or your modifications thereto.
     54 
     55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
     56 that you changed the software and the date of any change. For modified versions
     57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
     58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
     59 AAC Codec Library for Android."
     60 
     61 3.    NO PATENT LICENSE
     62 
     63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
     64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
     65 Fraunhofer provides no warranty of patent non-infringement with respect to this
     66 software.
     67 
     68 You may use this FDK AAC Codec software or modifications thereto only for
     69 purposes that are authorized by appropriate patent licenses.
     70 
     71 4.    DISCLAIMER
     72 
     73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
     74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
     75 including but not limited to the implied warranties of merchantability and
     76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
     78 or consequential damages, including but not limited to procurement of substitute
     79 goods or services; loss of use, data, or profits, or business interruption,
     80 however caused and on any theory of liability, whether in contract, strict
     81 liability, or tort (including negligence), arising in any way out of the use of
     82 this software, even if advised of the possibility of such damage.
     83 
     84 5.    CONTACT INFORMATION
     85 
     86 Fraunhofer Institute for Integrated Circuits IIS
     87 Attention: Audio and Multimedia Departments - FDK AAC LL
     88 Am Wolfsmantel 33
     89 91058 Erlangen, Germany
     90 
     91 www.iis.fraunhofer.de/amm
     92 amm-info (at) iis.fraunhofer.de
     93 ----------------------------------------------------------------------------- */
     94 
     95 /******************* MPEG transport format decoder library *********************
     96 
     97    Author(s):   Manuel Jander
     98 
     99    Description: MPEG Transport decoder
    100 
    101 *******************************************************************************/
    102 
    103 #include "tpdec_lib.h"
    104 
    105 /* library version */
    106 #include "tp_version.h"
    107 
    108 #include "tp_data.h"
    109 
    110 #include "tpdec_adts.h"
    111 
    112 #include "tpdec_adif.h"
    113 
    114 #include "tpdec_latm.h"
    115 
    116 #include "tpdec_drm.h"
    117 
    118 #include "FDK_crc.h"
    119 
    120 #define MODULE_NAME "transportDec"
    121 
    122 typedef union {
    123   STRUCT_ADTS adts;
    124 
    125   CAdifHeader adif;
    126 
    127   CLatmDemux latm;
    128 
    129   STRUCT_DRM drm;
    130 
    131 } transportdec_parser_t;
    132 
    133 #define MHAS_CONFIG_PRESENT 0x001
    134 #define MHAS_UI_PRESENT 0x002
    135 
    136 struct TRANSPORTDEC {
    137   TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */
    138 
    139   CSTpCallBacks callbacks; /*!< Struct holding callback and its data */
    140 
    141   FDK_BITSTREAM bitStream[1]; /* Bitstream reader */
    142   UCHAR *bsBuffer;            /* Internal bitstreamd data buffer */
    143 
    144   transportdec_parser_t parser; /* Format specific parser structs. */
    145 
    146   CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last
    147                                              config found. One additional
    148                                              CSAudioSpecificConfig is used
    149                                              temporarily for parsing. */
    150   CCtrlCFGChange ctrlCFGChange[(1 * 1)];  /* Controls config change */
    151 
    152   UINT globalFramePos;      /* Global transport frame reference bit position. */
    153   UINT accessUnitAnchor[1]; /* Current access unit start bit position. */
    154   INT auLength[1];          /* Length of current access unit. */
    155   INT numberOfRawDataBlocks; /* Current number of raw data blocks contained
    156                                 remaining from the current transport frame. */
    157   UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
    158   UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame
    159                                    loss estimation */
    160   INT remainder; /* Reminder in division during lost access unit estimation. */
    161   INT missingAccessUnits; /* Estimated missing access units. */
    162   UINT burstPeriod;       /* Data burst period in mili seconds. */
    163   UINT holdOffFrames;     /* Amount of frames that were already hold off due to
    164                              buffer fullness condition not being met. */
    165   UINT flags;             /* Flags. */
    166   INT targetLayout;       /* CICP target layout. */
    167   UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and
    168                                      length (bytes) of loudnessInfoSet within
    169                                      rsv603daConfig.  */
    170 };
    171 
    172 /* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
    173 #define TPDEC_SYNCOK 1
    174 #define TPDEC_MINIMIZE_DELAY 2
    175 #define TPDEC_IGNORE_BUFFERFULLNESS 4
    176 #define TPDEC_EARLY_CONFIG 8
    177 #define TPDEC_LOST_FRAMES_PENDING 16
    178 #define TPDEC_CONFIG_FOUND 32
    179 #define TPDEC_USE_ELEM_SKIPPING 64
    180 
    181 /* force config/content change */
    182 #define TPDEC_FORCE_CONFIG_CHANGE 1
    183 #define TPDEC_FORCE_CONTENT_CHANGE 2
    184 
    185 /* skip packet */
    186 #define TPDEC_SKIP_PACKET 1
    187 
    188 C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1)
    189 C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4))
    190 
    191 HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt,
    192                                       const UINT flags, const UINT nrOfLayers) {
    193   HANDLE_TRANSPORTDEC hInput;
    194 
    195   hInput = GetRam_TransportDecoder(0);
    196   if (hInput == NULL) {
    197     return NULL;
    198   }
    199 
    200   /* Init transportDec struct. */
    201   hInput->transportFmt = transportFmt;
    202 
    203   switch (transportFmt) {
    204     case TT_MP4_ADIF:
    205       break;
    206 
    207     case TT_MP4_ADTS:
    208       if (flags & TP_FLAG_MPEG4)
    209         hInput->parser.adts.decoderCanDoMpeg4 = 1;
    210       else
    211         hInput->parser.adts.decoderCanDoMpeg4 = 0;
    212       adtsRead_CrcInit(&hInput->parser.adts);
    213       hInput->parser.adts.BufferFullnesStartFlag = 1;
    214       hInput->numberOfRawDataBlocks = 0;
    215       break;
    216 
    217     case TT_DRM:
    218       drmRead_CrcInit(&hInput->parser.drm);
    219       break;
    220 
    221     case TT_MP4_LATM_MCP0:
    222     case TT_MP4_LATM_MCP1:
    223       hInput->parser.latm.usacExplicitCfgChanged = 0;
    224       hInput->parser.latm.applyAsc = 1;
    225       break;
    226     case TT_MP4_LOAS:
    227       hInput->parser.latm.usacExplicitCfgChanged = 0;
    228       hInput->parser.latm.applyAsc = 1;
    229       break;
    230     case TT_MP4_RAW:
    231       break;
    232 
    233     default:
    234       FreeRam_TransportDecoder(&hInput);
    235       hInput = NULL;
    236       break;
    237   }
    238 
    239   if (hInput != NULL) {
    240     /* Create bitstream */
    241     {
    242       hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
    243       if (hInput->bsBuffer == NULL) {
    244         transportDec_Close(&hInput);
    245         return NULL;
    246       }
    247       if (nrOfLayers > 1) {
    248         transportDec_Close(&hInput);
    249         return NULL;
    250       }
    251       for (UINT i = 0; i < nrOfLayers; i++) {
    252         FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
    253                          BS_READER);
    254       }
    255     }
    256     hInput->burstPeriod = 0;
    257   }
    258 
    259   return hInput;
    260 }
    261 
    262 TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
    263                                                 UCHAR *conf, const UINT length,
    264                                                 UINT layer) {
    265   int i;
    266 
    267   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
    268 
    269   FDK_BITSTREAM bs;
    270   HANDLE_FDK_BITSTREAM hBs = &bs;
    271 
    272   int fConfigFound = 0;
    273 
    274   UCHAR configChanged = 0;
    275   UCHAR configMode = AC_CM_DET_CFG_CHANGE;
    276 
    277   UCHAR tmpConf[1024] = {0};
    278   if (length > 1024) {
    279     return TRANSPORTDEC_UNSUPPORTED_FORMAT;
    280   }
    281   FDKmemcpy(tmpConf, conf, length);
    282   FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);
    283 
    284   for (i = 0; i < 2; i++) {
    285     if (i > 0) {
    286       FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs));
    287       configMode = AC_CM_ALLOC_MEM;
    288     }
    289 
    290     /* config transport decoder */
    291     switch (hTp->transportFmt) {
    292       case TT_MP4_LATM_MCP0:
    293       case TT_MP4_LATM_MCP1:
    294       case TT_MP4_LOAS: {
    295         if (layer != 0) {
    296           return TRANSPORTDEC_INVALID_PARAMETER;
    297         }
    298         CLatmDemux *pLatmDemux = &hTp->parser.latm;
    299         err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks,
    300                                              hTp->asc, &fConfigFound,
    301                                              configMode, configChanged);
    302         if (err != TRANSPORTDEC_OK) {
    303           return err;
    304         }
    305       } break;
    306       default:
    307         fConfigFound = 1;
    308         err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
    309                                         &hTp->callbacks, configMode,
    310                                         configChanged, AOT_NULL_OBJECT);
    311         if (err == TRANSPORTDEC_OK) {
    312           int errC;
    313 
    314           hTp->asc[layer] = hTp->asc[(1 * 1)];
    315           errC = hTp->callbacks.cbUpdateConfig(
    316               hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
    317               hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
    318           if (errC != 0) {
    319             err = TRANSPORTDEC_PARSE_ERROR;
    320           }
    321         }
    322         break;
    323       case TT_DRM:
    324         fConfigFound = 1;
    325         err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks,
    326                                          configMode, configChanged);
    327         if (err == TRANSPORTDEC_OK) {
    328           int errC;
    329 
    330           errC = hTp->callbacks.cbUpdateConfig(
    331               hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
    332               hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
    333           if (errC != 0) {
    334             err = TRANSPORTDEC_PARSE_ERROR;
    335           }
    336         }
    337         break;
    338     }
    339 
    340     if (err == TRANSPORTDEC_OK) {
    341       if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
    342                        hTp->asc[layer].SbrConfigChanged ||
    343                        hTp->asc[layer].SacConfigChanged)) {
    344         int errC;
    345 
    346         configChanged = 1;
    347         errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
    348                                         &hTp->asc[layer]);
    349         if (errC != 0) {
    350           err = TRANSPORTDEC_PARSE_ERROR;
    351         }
    352       }
    353     }
    354   }
    355 
    356   if (err == TRANSPORTDEC_OK && fConfigFound) {
    357     hTp->flags |= TPDEC_CONFIG_FOUND;
    358   }
    359 
    360   return err;
    361 }
    362 
    363 TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
    364                                              UCHAR *newConfig,
    365                                              const UINT newConfigLength,
    366                                              const UCHAR buildUpStatus,
    367                                              UCHAR *configChanged, UINT layer,
    368                                              UCHAR *implicitExplicitCfgDiff) {
    369   int errC;
    370   FDK_BITSTREAM bs;
    371   HANDLE_FDK_BITSTREAM hBs = &bs;
    372   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
    373   int fConfigFound = 0;
    374   UCHAR configMode = AC_CM_ALLOC_MEM;
    375   *implicitExplicitCfgDiff = 0;
    376 
    377   FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
    378 
    379   FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
    380                    BS_READER);
    381 
    382   if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
    383       (hTp->ctrlCFGChange[layer].buildUpStatus !=
    384        TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
    385     if (hTp->asc->m_aot == AOT_USAC) {
    386       if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
    387           newConfigLength) {
    388         if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
    389                            newConfigLength)) {
    390           if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
    391                                                             LOAS/LATM parser */
    392             hTp->parser.latm.usacExplicitCfgChanged = 0;
    393             hTp->ctrlCFGChange[layer].flushCnt = 0;
    394             hTp->ctrlCFGChange[layer].flushStatus =
    395                 TPDEC_USAC_DASH_IPF_FLUSH_ON;
    396             hTp->ctrlCFGChange[layer].buildUpCnt = 0;
    397             hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
    398           } else {
    399             *configChanged = 0;
    400             return err;
    401           }
    402         } else {
    403           *implicitExplicitCfgDiff = 1;
    404         }
    405       } else {
    406         *implicitExplicitCfgDiff = 1;
    407       }
    408       /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
    409        * config shall be identical. */
    410       if (*implicitExplicitCfgDiff) {
    411         switch (hTp->transportFmt) {
    412           case TT_MP4_LATM_MCP0:
    413           case TT_MP4_LATM_MCP1:
    414           case TT_MP4_LOAS:
    415             /* reset decoder to initial state to achieve definite behavior after
    416              * error in config */
    417             hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
    418                                      &hTp->asc[layer]);
    419             hTp->parser.latm.usacExplicitCfgChanged = 0;
    420             hTp->parser.latm.applyAsc = 1;
    421             err = TRANSPORTDEC_PARSE_ERROR;
    422             goto bail;
    423           default:
    424             break;
    425         }
    426       }
    427     }
    428   }
    429 
    430   {
    431     if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
    432         (hTp->ctrlCFGChange[layer].buildUpStatus !=
    433          TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
    434       hTp->ctrlCFGChange[layer].flushCnt = 0;
    435       hTp->ctrlCFGChange[layer].buildUpCnt = 0;
    436       hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
    437       if (hTp->asc->m_aot == AOT_USAC) {
    438         hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
    439       }
    440     }
    441 
    442     if ((hTp->ctrlCFGChange[layer].flushStatus ==
    443          TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
    444         (hTp->ctrlCFGChange[layer].flushStatus ==
    445          TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
    446       SCHAR counter = 0;
    447       if (hTp->asc->m_aot == AOT_USAC) {
    448         counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
    449       }
    450       if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
    451         hTp->ctrlCFGChange[layer].flushCnt = 0;
    452         hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
    453         hTp->ctrlCFGChange[layer].forceCfgChange = 0;
    454         if (hTp->asc->m_aot == AOT_USAC) {
    455           hTp->ctrlCFGChange[layer].buildUpCnt =
    456               TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
    457           hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
    458         }
    459       }
    460 
    461       /* Activate flush mode. After that continue with build up mode in core */
    462       if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
    463                                          &hTp->ctrlCFGChange[layer]) != 0) {
    464         err = TRANSPORTDEC_PARSE_ERROR;
    465       }
    466 
    467       if ((hTp->ctrlCFGChange[layer].flushStatus ==
    468            TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
    469           (hTp->ctrlCFGChange[layer].flushStatus ==
    470            TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
    471         hTp->ctrlCFGChange[layer].flushCnt++;
    472         return err;
    473       }
    474     }
    475 
    476     if (hTp->asc->m_aot == AOT_USAC) {
    477       fConfigFound = 1;
    478 
    479       if (err == TRANSPORTDEC_OK) {
    480         *configChanged = 0;
    481         configMode = AC_CM_DET_CFG_CHANGE;
    482 
    483         for (int i = 0; i < 2; i++) {
    484           if (i > 0) {
    485             FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs));
    486             configMode = AC_CM_ALLOC_MEM;
    487           }
    488           /* config transport decoder */
    489           err = AudioSpecificConfig_Parse(
    490               &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
    491               *configChanged, hTp->asc[layer].m_aot);
    492           if (err == TRANSPORTDEC_OK) {
    493             hTp->asc[layer] = hTp->asc[(1 * 1)];
    494             errC = hTp->callbacks.cbUpdateConfig(
    495                 hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
    496                 hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
    497             if (errC != 0) {
    498               err = TRANSPORTDEC_PARSE_ERROR;
    499             }
    500           }
    501 
    502           if (err == TRANSPORTDEC_OK) {
    503             if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
    504                              hTp->asc[layer].SbrConfigChanged ||
    505                              hTp->asc[layer].SacConfigChanged)) {
    506               *configChanged = 1;
    507               errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
    508                                               &hTp->asc[layer]);
    509               if (errC != 0) {
    510                 err = TRANSPORTDEC_PARSE_ERROR;
    511               }
    512             }
    513           }
    514 
    515           /* if an error is detected terminate config parsing to avoid that an
    516            * invalid config is accepted in the second pass */
    517           if (err != TRANSPORTDEC_OK) {
    518             break;
    519           }
    520         }
    521       }
    522     }
    523 
    524   bail:
    525     /* save new config */
    526     if (err == TRANSPORTDEC_OK) {
    527       if (hTp->asc->m_aot == AOT_USAC) {
    528         hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
    529         FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
    530                   newConfigLength);
    531         /* in case of USAC reset transportDecoder variables here because
    532          * otherwise without IPF they are not reset */
    533         hTp->ctrlCFGChange[layer].flushCnt = 0;
    534         hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
    535         hTp->ctrlCFGChange[layer].buildUpCnt = 0;
    536         hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
    537       }
    538     } else {
    539       hTp->numberOfRawDataBlocks = 0;
    540 
    541       /* If parsing error while config found, clear ctrlCFGChange-struct */
    542       hTp->ctrlCFGChange[layer].flushCnt = 0;
    543       hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
    544       hTp->ctrlCFGChange[layer].buildUpCnt = 0;
    545       hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
    546       hTp->ctrlCFGChange[layer].cfgChanged = 0;
    547       hTp->ctrlCFGChange[layer].contentChanged = 0;
    548       hTp->ctrlCFGChange[layer].forceCfgChange = 0;
    549 
    550       hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
    551                                      &hTp->ctrlCFGChange[layer]);
    552     }
    553   }
    554 
    555   if (err == TRANSPORTDEC_OK && fConfigFound) {
    556     hTp->flags |= TPDEC_CONFIG_FOUND;
    557   }
    558 
    559   return err;
    560 }
    561 
    562 int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
    563                                      const cbUpdateConfig_t cbUpdateConfig,
    564                                      void *user_data) {
    565   if (hTpDec == NULL) {
    566     return -1;
    567   }
    568   hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
    569   hTpDec->callbacks.cbUpdateConfigData = user_data;
    570   return 0;
    571 }
    572 
    573 int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
    574                                          const cbFreeMem_t cbFreeMem,
    575                                          void *user_data) {
    576   if (hTpDec == NULL) {
    577     return -1;
    578   }
    579   hTpDec->callbacks.cbFreeMem = cbFreeMem;
    580   hTpDec->callbacks.cbFreeMemData = user_data;
    581   return 0;
    582 }
    583 
    584 int transportDec_RegisterCtrlCFGChangeCallback(
    585     HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
    586     void *user_data) {
    587   if (hTpDec == NULL) {
    588     return -1;
    589   }
    590   hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
    591   hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
    592   return 0;
    593 }
    594 
    595 int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
    596                                      const cbSsc_t cbSsc, void *user_data) {
    597   if (hTpDec == NULL) {
    598     return -1;
    599   }
    600   hTpDec->callbacks.cbSsc = cbSsc;
    601   hTpDec->callbacks.cbSscData = user_data;
    602   return 0;
    603 }
    604 
    605 int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
    606                                      const cbSbr_t cbSbr, void *user_data) {
    607   if (hTpDec == NULL) {
    608     return -1;
    609   }
    610   hTpDec->callbacks.cbSbr = cbSbr;
    611   hTpDec->callbacks.cbSbrData = user_data;
    612   return 0;
    613 }
    614 
    615 int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
    616                                       const cbUsac_t cbUsac, void *user_data) {
    617   if (hTpDec == NULL) {
    618     return -1;
    619   }
    620   hTpDec->callbacks.cbUsac = cbUsac;
    621   hTpDec->callbacks.cbUsacData = user_data;
    622   return 0;
    623 }
    624 
    625 int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
    626                                               const cbUniDrc_t cbUniDrc,
    627                                               void *user_data,
    628                                               UINT *pLoudnessInfoSetPosition) {
    629   if (hTpDec == NULL) {
    630     return -1;
    631   }
    632 
    633   hTpDec->callbacks.cbUniDrc = cbUniDrc;
    634   hTpDec->callbacks.cbUniDrcData = user_data;
    635 
    636   hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
    637   return 0;
    638 }
    639 
    640 TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
    641                                          UCHAR *pBuffer, const UINT bufferSize,
    642                                          UINT *pBytesValid, const INT layer) {
    643   HANDLE_FDK_BITSTREAM hBs;
    644 
    645   if ((hTp == NULL) || (layer >= 1)) {
    646     return TRANSPORTDEC_INVALID_PARAMETER;
    647   }
    648 
    649   /* set bitbuffer shortcut */
    650   hBs = &hTp->bitStream[layer];
    651 
    652   if (TT_IS_PACKET(hTp->transportFmt)) {
    653     if (hTp->numberOfRawDataBlocks == 0) {
    654       FDKresetBitbuffer(hBs);
    655       FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
    656       if (*pBytesValid != 0) {
    657         return TRANSPORTDEC_TOO_MANY_BITS;
    658       }
    659     }
    660   } else {
    661     /* ... else feed bitbuffer with new stream data (append). */
    662 
    663     if (*pBytesValid == 0) {
    664       /* nothing to do */
    665       return TRANSPORTDEC_OK;
    666     }
    667 
    668     if (hTp->numberOfRawDataBlocks <= 0) {
    669       FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
    670     }
    671   }
    672 
    673   return TRANSPORTDEC_OK;
    674 }
    675 
    676 HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
    677                                                const UINT layer) {
    678   return &hTp->bitStream[layer];
    679 }
    680 
    681 TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
    682   return hTp->transportFmt;
    683 }
    684 
    685 INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
    686   INT bufferFullness = -1;
    687 
    688   switch (hTp->transportFmt) {
    689     case TT_MP4_ADTS:
    690       if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
    691         bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
    692                          hTp->parser.adts.bs.adts_fullness * 32 *
    693                              getNumberOfEffectiveChannels(
    694                                  hTp->parser.adts.bs.channel_config);
    695       }
    696       break;
    697     case TT_MP4_LOAS:
    698     case TT_MP4_LATM_MCP0:
    699     case TT_MP4_LATM_MCP1:
    700       if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
    701         bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
    702       }
    703       break;
    704     default:
    705       break;
    706   }
    707 
    708   return bufferFullness;
    709 }
    710 
    711 /**
    712  * \brief adjust bit stream position and the end of an access unit.
    713  * \param hTp transport decoder handle.
    714  * \return error code.
    715  */
    716 static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
    717     HANDLE_TRANSPORTDEC hTp) {
    718   HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
    719   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
    720 
    721   switch (hTp->transportFmt) {
    722     case TT_MP4_ADIF:
    723       /* Do byte align at the end of raw_data_block() because UsacFrame() is not
    724        * byte aligned. */
    725       FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
    726       break;
    727     case TT_MP4_LOAS:
    728     case TT_MP4_LATM_MCP0:
    729     case TT_MP4_LATM_MCP1:
    730       if (hTp->numberOfRawDataBlocks == 0) {
    731         /* Do byte align at the end of AudioMuxElement. */
    732         FDKbyteAlign(hBs, hTp->globalFramePos);
    733 
    734         /* Check global frame length */
    735         if (hTp->transportFmt == TT_MP4_LOAS &&
    736             hTp->parser.latm.m_audioMuxLengthBytes > 0) {
    737           int loasOffset;
    738 
    739           loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
    740                         (INT)FDKgetValidBits(hBs)) -
    741                        (INT)hTp->globalFramePos;
    742           if (loasOffset != 0) {
    743             FDKpushBiDirectional(hBs, loasOffset);
    744             /* For ELD and other payloads there is an unknown amount of padding,
    745                so ignore unread bits, but throw an error only if too many bits
    746                where read. */
    747             if (loasOffset < 0) {
    748               err = TRANSPORTDEC_PARSE_ERROR;
    749             }
    750           }
    751         }
    752       }
    753       break;
    754 
    755     case TT_MP4_ADTS:
    756       if (hTp->parser.adts.bs.protection_absent == 0) {
    757         int offset;
    758 
    759         /* Calculate offset to end of AU */
    760         offset = hTp->parser.adts
    761                      .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
    762                                        hTp->numberOfRawDataBlocks]
    763                  << 3;
    764         /* CAUTION: The PCE (if available) is declared to be a part of the
    765          * header! */
    766         offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
    767                   16 + hTp->parser.adts.bs.num_pce_bits;
    768         FDKpushBiDirectional(hBs, offset);
    769       }
    770       if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
    771           hTp->parser.adts.bs.protection_absent == 0) {
    772         /* Note this CRC read currently happens twice because of
    773          * transportDec_CrcCheck() */
    774         hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
    775       }
    776       if (hTp->numberOfRawDataBlocks == 0) {
    777         /* Check global frame length */
    778         if (hTp->parser.adts.bs.protection_absent == 0) {
    779           int offset;
    780 
    781           offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
    782                     (INT)FDKgetValidBits(hBs)) -
    783                    (INT)hTp->globalFramePos;
    784           if (offset != 0) {
    785             FDKpushBiDirectional(hBs, offset);
    786           }
    787         }
    788       }
    789       break;
    790 
    791     default:
    792       break;
    793   }
    794 
    795   return err;
    796 }
    797 
    798 /**
    799  * \brief Determine additional buffer fullness contraint due to burst data
    800  * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
    801  * precondition.
    802  * \param hTp transport decoder handle.
    803  * \param bufferFullness the buffer fullness value of the first frame to be
    804  * decoded.
    805  * \param bitsAvail the amount of available bits at the end of the first frame
    806  * to be decoded.
    807  * \return error code
    808  */
    809 static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
    810                                                   INT bufferFullness,
    811                                                   INT bitsAvail) {
    812   INT checkLengthBits, avgBitsPerFrame;
    813   INT maxAU; /* maximum number of frames per Master Frame */
    814   INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
    815   INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
    816 
    817   if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
    818     return TRANSPORTDEC_OK;
    819   }
    820   if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
    821     return TRANSPORTDEC_NOT_ENOUGH_BITS;
    822   }
    823 
    824   /* One Master Frame is sent every hTp->burstPeriod ms */
    825   maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
    826   maxAU = maxAU / (samplesPerFrame * 1000);
    827   /* Subtract number of frames which were already held off. */
    828   maxAU -= hTp->holdOffFrames;
    829 
    830   avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
    831   avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
    832 
    833   /* Consider worst case of bufferFullness quantization. */
    834   switch (hTp->transportFmt) {
    835     case TT_MP4_ADIF:
    836     case TT_MP4_ADTS:
    837     case TT_MP4_LOAS:
    838     case TT_MP4_LATM_MCP0:
    839     case TT_MP4_LATM_MCP1:
    840       bufferFullness += 31;
    841       break;
    842     default: /* added to avoid compiler warning */
    843       break; /* added to avoid compiler warning */
    844   }
    845 
    846   checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;
    847 
    848   /* Check if buffer is big enough to fullfill buffer fullness condition */
    849   if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
    850     return TRANSPORTDEC_SYNC_ERROR;
    851   }
    852 
    853   if (bitsAvail < checkLengthBits) {
    854     return TRANSPORTDEC_NOT_ENOUGH_BITS;
    855   } else {
    856     return TRANSPORTDEC_OK;
    857   }
    858 }
    859 
    860 static TRANSPORTDEC_ERROR transportDec_readHeader(
    861     HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
    862     int ignoreBufferFullness, int *pRawDataBlockLength,
    863     int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
    864     int *pHeaderBits) {
    865   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
    866   int rawDataBlockLength = *pRawDataBlockLength;
    867   int fTraverseMoreFrames =
    868       (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
    869   int syncLayerFrameBits =
    870       (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
    871   int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
    872   int startPos;
    873 
    874   startPos = (INT)FDKgetValidBits(hBs);
    875 
    876   switch (hTp->transportFmt) {
    877     case TT_MP4_ADTS:
    878       if (hTp->numberOfRawDataBlocks <= 0) {
    879         int i, errC;
    880 
    881         hTp->globalFramePos = FDKgetValidBits(hBs);
    882 
    883         UCHAR configChanged = 0;
    884         UCHAR configMode = AC_CM_DET_CFG_CHANGE;
    885 
    886         for (i = 0; i < 2; i++) {
    887           if (i > 0) {
    888             FDKpushBack(hBs,
    889                         (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
    890             configMode = AC_CM_ALLOC_MEM;
    891           }
    892 
    893           /* Parse ADTS header */
    894           err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
    895                                       ignoreBufferFullness);
    896           if (err != TRANSPORTDEC_OK) {
    897             if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
    898               err = TRANSPORTDEC_SYNC_ERROR;
    899             }
    900           } else {
    901             errC = hTp->callbacks.cbUpdateConfig(
    902                 hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
    903                 &configChanged);
    904             if (errC != 0) {
    905               if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
    906                 err = TRANSPORTDEC_NEED_TO_RESTART;
    907                 goto bail;
    908               } else {
    909                 err = TRANSPORTDEC_SYNC_ERROR;
    910               }
    911             } else {
    912               fConfigFound = 1;
    913               hTp->numberOfRawDataBlocks =
    914                   hTp->parser.adts.bs.num_raw_blocks + 1;
    915             }
    916           }
    917 
    918           if (err == TRANSPORTDEC_OK) {
    919             if ((i == 0) && configChanged) {
    920               errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
    921                                               &hTp->asc[0]);
    922               if (errC != 0) {
    923                 err = TRANSPORTDEC_PARSE_ERROR;
    924               }
    925             }
    926           }
    927         }
    928       } else {
    929         /* Reset CRC because the next bits are the beginning of a
    930          * raw_data_block() */
    931         FDKcrcReset(&hTp->parser.adts.crcInfo);
    932         hTp->parser.adts.bs.num_pce_bits = 0;
    933       }
    934       if (err == TRANSPORTDEC_OK) {
    935         hTp->numberOfRawDataBlocks--;
    936         rawDataBlockLength = adtsRead_GetRawDataBlockLength(
    937             &hTp->parser.adts,
    938             (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
    939         if (rawDataBlockLength <= 0) {
    940           /* No further frame traversal possible. */
    941           fTraverseMoreFrames = 0;
    942         }
    943         syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
    944                              (startPos - (INT)FDKgetValidBits(hBs)) -
    945                              syncLength;
    946         if (syncLayerFrameBits <= 0) {
    947           err = TRANSPORTDEC_SYNC_ERROR;
    948         }
    949       } else {
    950         hTp->numberOfRawDataBlocks = 0;
    951       }
    952       break;
    953     case TT_MP4_LOAS:
    954       if (hTp->numberOfRawDataBlocks <= 0) {
    955         syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
    956         hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
    957         syncLayerFrameBits <<= 3;
    958       }
    959       FDK_FALLTHROUGH;
    960     case TT_MP4_LATM_MCP1:
    961     case TT_MP4_LATM_MCP0:
    962       if (hTp->numberOfRawDataBlocks <= 0) {
    963         hTp->globalFramePos = FDKgetValidBits(hBs);
    964 
    965         err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
    966                               &hTp->callbacks, hTp->asc, &fConfigFound,
    967                               ignoreBufferFullness);
    968 
    969         if (err != TRANSPORTDEC_OK) {
    970           if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
    971               !TPDEC_IS_FATAL_ERROR(err)) {
    972             err = TRANSPORTDEC_SYNC_ERROR;
    973           }
    974         } else {
    975           hTp->numberOfRawDataBlocks =
    976               CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
    977           if (hTp->transportFmt == TT_MP4_LOAS) {
    978             syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
    979           }
    980         }
    981       } else {
    982         err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
    983         if (err != TRANSPORTDEC_OK) {
    984           err = TRANSPORTDEC_SYNC_ERROR;
    985         }
    986       }
    987       if (err == TRANSPORTDEC_OK) {
    988         int layer;
    989         rawDataBlockLength = 0;
    990         for (layer = 0;
    991              layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
    992              layer += 1) {
    993           rawDataBlockLength +=
    994               CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
    995         }
    996         hTp->numberOfRawDataBlocks--;
    997       } else {
    998         hTp->numberOfRawDataBlocks = 0;
    999       }
   1000       break;
   1001     default: { syncLayerFrameBits = 0; } break;
   1002   }
   1003 
   1004 bail:
   1005 
   1006   *pRawDataBlockLength = rawDataBlockLength;
   1007 
   1008   if (pHeaderBits != NULL) {
   1009     *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
   1010   }
   1011 
   1012   for (int i = 0; i < (1 * 1); i++) {
   1013     /* If parsing error while config found, clear ctrlCFGChange-struct */
   1014     if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
   1015       hTp->numberOfRawDataBlocks = 0;
   1016       hTp->ctrlCFGChange[i].flushCnt = 0;
   1017       hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
   1018       hTp->ctrlCFGChange[i].buildUpCnt = 0;
   1019       hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
   1020       hTp->ctrlCFGChange[i].cfgChanged = 0;
   1021       hTp->ctrlCFGChange[i].contentChanged = 0;
   1022       hTp->ctrlCFGChange[i].forceCfgChange = 0;
   1023 
   1024       hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
   1025                                      &hTp->ctrlCFGChange[i]);
   1026     }
   1027   }
   1028 
   1029   if (pfConfigFound != NULL) {
   1030     *pfConfigFound = fConfigFound;
   1031   }
   1032 
   1033   if (pfTraverseMoreFrames != NULL) {
   1034     *pfTraverseMoreFrames = fTraverseMoreFrames;
   1035   }
   1036   if (pSyncLayerFrameBits != NULL) {
   1037     *pSyncLayerFrameBits = syncLayerFrameBits;
   1038   }
   1039 
   1040   return err;
   1041 }
   1042 
   1043 /* How many bits to advance for synchronization search. */
   1044 #define TPDEC_SYNCSKIP 8
   1045 
   1046 static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
   1047                                           INT *pHeaderBits) {
   1048   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
   1049   HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
   1050 
   1051   INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
   1052   INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
   1053   INT totalBits;
   1054   INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
   1055   INT numFramesTraversed = 0, fTraverseMoreFrames,
   1056       fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
   1057   INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
   1058       globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
   1059   INT ignoreBufferFullness =
   1060       hTp->flags &
   1061       (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
   1062   UINT endTpFrameBitsPrevious = 0;
   1063 
   1064   /* Synch parameters */
   1065   INT syncLength; /* Length of sync word in bits */
   1066   UINT syncWord;  /* Sync word to be found */
   1067   UINT syncMask;  /* Mask for sync word (for adding one bit, so comprising one
   1068                      bit less) */
   1069   C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
   1070 
   1071   totalBits = (INT)FDKgetValidBits(hBs);
   1072 
   1073   if (totalBits <= 0) {
   1074     err = TRANSPORTDEC_NOT_ENOUGH_BITS;
   1075     goto bail;
   1076   }
   1077 
   1078   fTraverseMoreFrames =
   1079       (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
   1080       !(hTp->flags & TPDEC_SYNCOK);
   1081 
   1082   /* Set transport specific sync parameters */
   1083   switch (hTp->transportFmt) {
   1084     case TT_MP4_ADTS:
   1085       syncWord = ADTS_SYNCWORD;
   1086       syncLength = ADTS_SYNCLENGTH;
   1087       break;
   1088     case TT_MP4_LOAS:
   1089       syncWord = 0x2B7;
   1090       syncLength = 11;
   1091       break;
   1092     default:
   1093       syncWord = 0;
   1094       syncLength = 0;
   1095       break;
   1096   }
   1097 
   1098   syncMask = (1 << syncLength) - 1;
   1099 
   1100   do {
   1101     INT bitsAvail = 0;   /* Bits available in bitstream buffer    */
   1102     INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
   1103                           */
   1104     UINT synch;          /* Current sync word read from bitstream */
   1105 
   1106     headerBitsPrevious = headerBits;
   1107 
   1108     bitsAvail = (INT)FDKgetValidBits(hBs);
   1109 
   1110     if (hTp->numberOfRawDataBlocks == 0) {
   1111       /* search synchword */
   1112 
   1113       FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
   1114 
   1115       if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
   1116         err = TRANSPORTDEC_NOT_ENOUGH_BITS;
   1117         headerBits = 0;
   1118       } else {
   1119         synch = FDKreadBits(hBs, syncLength);
   1120 
   1121         if (!(hTp->flags & TPDEC_SYNCOK)) {
   1122           for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
   1123                bitsAvail -= TPDEC_SYNCSKIP) {
   1124             if (synch == syncWord) {
   1125               break;
   1126             }
   1127             synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
   1128                     FDKreadBits(hBs, TPDEC_SYNCSKIP);
   1129           }
   1130         }
   1131         if (synch != syncWord) {
   1132           /* No correct syncword found. */
   1133           err = TRANSPORTDEC_SYNC_ERROR;
   1134         } else {
   1135           err = TRANSPORTDEC_OK;
   1136         }
   1137         headerBits = syncLength;
   1138       }
   1139     } else {
   1140       headerBits = 0;
   1141     }
   1142 
   1143     /* Save previous raw data block data */
   1144     rawDataBlockLengthPrevious = rawDataBlockLength;
   1145     numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
   1146 
   1147     /* Parse transport header (raw data block granularity) */
   1148 
   1149     if (err == TRANSPORTDEC_OK) {
   1150       err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
   1151                                     &rawDataBlockLength, &fTraverseMoreFrames,
   1152                                     &syncLayerFrameBits, &fConfigFound,
   1153                                     &headerBits);
   1154       if (TPDEC_IS_FATAL_ERROR(err)) {
   1155         /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
   1156          * next time. Ensure that the bit amount lands at a multiple of
   1157          * TPDEC_SYNCSKIP. */
   1158         FDKpushBiDirectional(
   1159             hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP));
   1160 
   1161         goto bail;
   1162       }
   1163     }
   1164 
   1165     bitsAvail -= headerBits;
   1166 
   1167     checkLengthBits = syncLayerFrameBits;
   1168 
   1169     /* Check if the whole frame would fit the bitstream buffer */
   1170     if (err == TRANSPORTDEC_OK) {
   1171       if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
   1172         /* We assume that the size of the transport bit buffer has been
   1173            chosen to meet all system requirements, thus this condition
   1174            is considered a synchronisation error. */
   1175         err = TRANSPORTDEC_SYNC_ERROR;
   1176       } else {
   1177         if (bitsAvail < checkLengthBits) {
   1178           err = TRANSPORTDEC_NOT_ENOUGH_BITS;
   1179         }
   1180       }
   1181     }
   1182 
   1183     if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
   1184       /* Enforce reading of new data */
   1185       hTp->numberOfRawDataBlocks = 0;
   1186       break;
   1187     }
   1188 
   1189     if (err == TRANSPORTDEC_SYNC_ERROR) {
   1190       int bits;
   1191 
   1192       /* Enforce re-sync of transport headers. */
   1193       hTp->numberOfRawDataBlocks = 0;
   1194 
   1195       /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
   1196       bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
   1197       /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
   1198        * next time. */
   1199       FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
   1200       headerBits = 0;
   1201     }
   1202 
   1203     /* Frame traversal */
   1204     if (fTraverseMoreFrames) {
   1205       /* Save parser context for early config discovery "rewind all frames" */
   1206       if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
   1207           !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
   1208         /* ignore buffer fullness if just traversing additional frames for ECD
   1209          */
   1210         ignoreBufferFullness = 1;
   1211 
   1212         /* Save context in order to return later */
   1213         if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
   1214           startPosFirstFrame = FDKgetValidBits(hBs);
   1215           numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
   1216           globalFramePosFirstFrame = hTp->globalFramePos;
   1217           rawDataBlockLengthFirstFrame = rawDataBlockLength;
   1218           headerBitsFirstFrame = headerBits;
   1219           errFirstFrame = err;
   1220           FDKmemcpy(contextFirstFrame, &hTp->parser,
   1221                     sizeof(transportdec_parser_t));
   1222         }
   1223 
   1224         /* Break when config was found or it is not possible anymore to find a
   1225          * config */
   1226         if (startPosFirstFrame != -1 &&
   1227             (fConfigFound || err != TRANSPORTDEC_OK)) {
   1228           /* In case of ECD and sync error, do not rewind anywhere. */
   1229           if (err == TRANSPORTDEC_SYNC_ERROR) {
   1230             startPosFirstFrame = -1;
   1231             fConfigFound = 0;
   1232             numFramesTraversed = 0;
   1233           }
   1234           break;
   1235         }
   1236       }
   1237 
   1238       if (err == TRANSPORTDEC_OK) {
   1239         FDKpushFor(hBs, rawDataBlockLength);
   1240         numFramesTraversed++;
   1241         endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
   1242         /* Ignore error here itentionally. */
   1243         transportDec_AdjustEndOfAccessUnit(hTp);
   1244         endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
   1245       }
   1246     }
   1247   } while (fTraverseMoreFrames ||
   1248            (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
   1249 
   1250   /* Restore context in case of ECD frame traversal */
   1251   if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
   1252     FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
   1253     FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
   1254     hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
   1255     hTp->globalFramePos = globalFramePosFirstFrame;
   1256     rawDataBlockLength = rawDataBlockLengthFirstFrame;
   1257     headerBits = headerBitsFirstFrame;
   1258     err = errFirstFrame;
   1259     numFramesTraversed = 0;
   1260   }
   1261 
   1262   /* Additional burst data mode buffer fullness check. */
   1263   if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
   1264                       TPDEC_SYNCOK)) &&
   1265       err == TRANSPORTDEC_OK) {
   1266     err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
   1267                                   FDKgetValidBits(hBs) - syncLayerFrameBits);
   1268     if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
   1269       hTp->holdOffFrames++;
   1270     }
   1271   }
   1272 
   1273   /* Rewind for retry because of not enough bits */
   1274   if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
   1275     FDKpushBack(hBs, headerBits);
   1276     headerBits = 0;
   1277   } else {
   1278     /* reset hold off frame counter */
   1279     hTp->holdOffFrames = 0;
   1280   }
   1281 
   1282   /* Return to last good frame in case of frame traversal but not ECD. */
   1283   if (numFramesTraversed > 0) {
   1284     FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
   1285     if (err != TRANSPORTDEC_OK) {
   1286       hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
   1287       headerBits = headerBitsPrevious;
   1288       rawDataBlockLength = rawDataBlockLengthPrevious;
   1289     }
   1290     err = TRANSPORTDEC_OK;
   1291   }
   1292 
   1293 bail:
   1294   hTp->auLength[0] = rawDataBlockLength;
   1295 
   1296   /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
   1297      buffer is already full, or no new burst packet fits. Recover by advancing
   1298      the bit buffer. */
   1299   if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
   1300       (FDKgetValidBits(hBs) >=
   1301        (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
   1302         7))) {
   1303     FDKpushFor(hBs, TPDEC_SYNCSKIP);
   1304     err = TRANSPORTDEC_SYNC_ERROR;
   1305   }
   1306 
   1307   if (err == TRANSPORTDEC_OK) {
   1308     hTp->flags |= TPDEC_SYNCOK;
   1309   }
   1310 
   1311   if (fConfigFound) {
   1312     hTp->flags |= TPDEC_CONFIG_FOUND;
   1313   }
   1314 
   1315   if (pHeaderBits != NULL) {
   1316     *pHeaderBits = headerBits;
   1317   }
   1318 
   1319   if (err == TRANSPORTDEC_SYNC_ERROR) {
   1320     hTp->flags &= ~TPDEC_SYNCOK;
   1321   }
   1322 
   1323   C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
   1324 
   1325   return err;
   1326 }
   1327 
   1328 /**
   1329  * \brief Synchronize to stream and estimate the amount of missing access units
   1330  * due to a current synchronization error in case of constant average bit rate.
   1331  */
   1332 static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
   1333                                                   const UINT layer) {
   1334   TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
   1335   HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
   1336 
   1337   INT headerBits;
   1338   INT bitDistance, bfDelta;
   1339 
   1340   /* Obtain distance to next synch word */
   1341   bitDistance = (INT)FDKgetValidBits(hBs);
   1342   error = synchronization(hTp, &headerBits);
   1343   bitDistance -= (INT)FDKgetValidBits(hBs);
   1344 
   1345   FDK_ASSERT(bitDistance >= 0);
   1346 
   1347   INT nAU = -1;
   1348 
   1349   if (error == TRANSPORTDEC_SYNC_ERROR ||
   1350       (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
   1351     /* Check if estimating lost access units is feasible. */
   1352     if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
   1353         hTp->asc[0].m_samplingFrequency > 0) {
   1354       if (error == TRANSPORTDEC_OK) {
   1355         int aj;
   1356 
   1357         aj = transportDec_GetBufferFullness(hTp);
   1358         if (aj > 0) {
   1359           bfDelta = aj;
   1360         } else {
   1361           bfDelta = 0;
   1362         }
   1363         /* sync was ok: last of a series of bad access units. */
   1364         hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
   1365         /* Add up bitDistance until end of the current frame. Later we substract
   1366            this frame from the grand total, since this current successfully
   1367            synchronized frame should not be skipped of course; but it must be
   1368            accounted into the bufferfulness math. */
   1369         bitDistance += hTp->auLength[0];
   1370       } else {
   1371         if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
   1372           /* sync not ok: one of many bad access units. */
   1373           hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
   1374           bfDelta = -(INT)hTp->lastValidBufferFullness;
   1375         } else {
   1376           bfDelta = 0;
   1377         }
   1378       }
   1379 
   1380       {
   1381         int num, denom;
   1382 
   1383         /* Obtain estimate of number of lost frames */
   1384         num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
   1385               hTp->remainder;
   1386         denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
   1387         if (num > 0) {
   1388           nAU = num / denom;
   1389           hTp->remainder = num % denom;
   1390         } else {
   1391           hTp->remainder = num;
   1392         }
   1393 
   1394         if (error == TRANSPORTDEC_OK) {
   1395           /* Final adjustment of remainder, taken -1 into account because
   1396              current frame should not be skipped, thus substract -1 or do
   1397              nothing instead of +1-1 accordingly. */
   1398           if ((denom - hTp->remainder) >= hTp->remainder) {
   1399             nAU--;
   1400           }
   1401 
   1402           if (nAU < 0) {
   1403             /* There was one frame too much concealed, so unfortunately we will
   1404              * have to skip one good frame. */
   1405             transportDec_EndAccessUnit(hTp);
   1406             error = synchronization(hTp, &headerBits);
   1407             nAU = -1;
   1408           }
   1409           hTp->remainder = 0;
   1410           /* Enforce last missed frames to be concealed. */
   1411           if (nAU > 0) {
   1412             FDKpushBack(hBs, headerBits);
   1413           }
   1414         }
   1415       }
   1416     }
   1417   }
   1418 
   1419   /* Be sure that lost frames are handled correctly. This is necessary due to
   1420      some sync error sequences where later it turns out that there is not enough
   1421      data, but the bits upto the sync word are discarded, thus causing a value
   1422      of nAU > 0 */
   1423   if (nAU > 0) {
   1424     error = TRANSPORTDEC_SYNC_ERROR;
   1425   }
   1426 
   1427   hTp->missingAccessUnits = nAU;
   1428 
   1429   return error;
   1430 }
   1431 
   1432 /* returns error code */
   1433 TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
   1434                                                const UINT layer) {
   1435   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
   1436   HANDLE_FDK_BITSTREAM hBs;
   1437 
   1438   if (!hTp) {
   1439     return TRANSPORTDEC_INVALID_PARAMETER;
   1440   }
   1441 
   1442   hBs = &hTp->bitStream[layer];
   1443 
   1444   if ((INT)FDKgetValidBits(hBs) <= 0) {
   1445     /* This is only relevant for RAW and ADIF cases.
   1446      * For streaming formats err will get overwritten. */
   1447     err = TRANSPORTDEC_NOT_ENOUGH_BITS;
   1448     hTp->numberOfRawDataBlocks = 0;
   1449   }
   1450 
   1451   switch (hTp->transportFmt) {
   1452     case TT_MP4_ADIF:
   1453       /* Read header if not already done */
   1454       if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
   1455         int i;
   1456         CProgramConfig *pce;
   1457         INT bsStart = FDKgetValidBits(hBs);
   1458         UCHAR configChanged = 0;
   1459         UCHAR configMode = AC_CM_DET_CFG_CHANGE;
   1460 
   1461         for (i = 0; i < 2; i++) {
   1462           if (i > 0) {
   1463             FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs));
   1464             configMode = AC_CM_ALLOC_MEM;
   1465           }
   1466 
   1467           AudioSpecificConfig_Init(&hTp->asc[0]);
   1468           pce = &hTp->asc[0].m_progrConfigElement;
   1469           err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
   1470           if (err) goto bail;
   1471 
   1472           /* Map adif header to ASC */
   1473           hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
   1474           hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
   1475           hTp->asc[0].m_samplingFrequency =
   1476               SamplingRateTable[pce->SamplingFrequencyIndex];
   1477           hTp->asc[0].m_channelConfiguration = 0;
   1478           hTp->asc[0].m_samplesPerFrame = 1024;
   1479           hTp->avgBitRate = hTp->parser.adif.BitRate;
   1480 
   1481           /* Call callback to decoder. */
   1482           {
   1483             int errC;
   1484 
   1485             errC = hTp->callbacks.cbUpdateConfig(
   1486                 hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
   1487                 &configChanged);
   1488             if (errC == 0) {
   1489               hTp->flags |= TPDEC_CONFIG_FOUND;
   1490             } else {
   1491               err = TRANSPORTDEC_PARSE_ERROR;
   1492               goto bail;
   1493             }
   1494           }
   1495 
   1496           if (err == TRANSPORTDEC_OK) {
   1497             if ((i == 0) && configChanged) {
   1498               int errC;
   1499               errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
   1500                                               &hTp->asc[0]);
   1501               if (errC != 0) {
   1502                 err = TRANSPORTDEC_PARSE_ERROR;
   1503               }
   1504             }
   1505           }
   1506         }
   1507       }
   1508       hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
   1509       break;
   1510 
   1511     case TT_MP4_RAW:
   1512     case TT_DRM:
   1513       /* One Access Unit was filled into buffer.
   1514          So get the length out of the buffer. */
   1515       hTp->auLength[layer] = FDKgetValidBits(hBs);
   1516       hTp->flags |= TPDEC_SYNCOK;
   1517       break;
   1518 
   1519     case TT_MP4_LATM_MCP0:
   1520     case TT_MP4_LATM_MCP1:
   1521       if (err == TRANSPORTDEC_OK) {
   1522         int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
   1523         err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
   1524                                       NULL, NULL, &fConfigFound, NULL);
   1525         if (fConfigFound) {
   1526           hTp->flags |= TPDEC_CONFIG_FOUND;
   1527         }
   1528       }
   1529       break;
   1530 
   1531     case TT_MP4_ADTS:
   1532     case TT_MP4_LOAS:
   1533       err = transportDec_readStream(hTp, layer);
   1534       break;
   1535 
   1536     default:
   1537       err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
   1538       break;
   1539   }
   1540 
   1541   if (err == TRANSPORTDEC_OK) {
   1542     hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
   1543   } else {
   1544     hTp->accessUnitAnchor[layer] = 0;
   1545   }
   1546 
   1547 bail:
   1548   return err;
   1549 }
   1550 
   1551 TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
   1552                                        const UINT layer,
   1553                                        CSAudioSpecificConfig *asc) {
   1554   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
   1555 
   1556   if (hTp != NULL) {
   1557     *asc = hTp->asc[layer];
   1558     err = TRANSPORTDEC_OK;
   1559   } else {
   1560     err = TRANSPORTDEC_INVALID_PARAMETER;
   1561   }
   1562   return err;
   1563 }
   1564 
   1565 INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
   1566                                     const UINT layer) {
   1567   INT bits;
   1568 
   1569   if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
   1570     bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
   1571     if (bits >= 0) {
   1572       bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
   1573     }
   1574   } else {
   1575     bits = FDKgetValidBits(&hTp->bitStream[layer]);
   1576   }
   1577 
   1578   return bits;
   1579 }
   1580 
   1581 INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
   1582                                 const UINT layer) {
   1583   return hTp->auLength[layer];
   1584 }
   1585 
   1586 TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
   1587     INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
   1588   *pNAccessUnits = hTp->missingAccessUnits;
   1589 
   1590   return TRANSPORTDEC_OK;
   1591 }
   1592 
   1593 /* Inform the transportDec layer that reading of access unit has finished. */
   1594 TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
   1595   TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
   1596 
   1597   switch (hTp->transportFmt) {
   1598     case TT_MP4_LOAS:
   1599     case TT_MP4_LATM_MCP0:
   1600     case TT_MP4_LATM_MCP1: {
   1601       HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
   1602       if (hTp->numberOfRawDataBlocks == 0) {
   1603         /* Read other data if available. */
   1604         if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
   1605           int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
   1606 
   1607           if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
   1608             FDKpushFor(hBs, otherDataLen);
   1609           } else {
   1610             /* Do byte align at the end of AudioMuxElement. */
   1611             if (hTp->numberOfRawDataBlocks == 0) {
   1612               FDKbyteAlign(hBs, hTp->globalFramePos);
   1613             }
   1614             return TRANSPORTDEC_NOT_ENOUGH_BITS;
   1615           }
   1616         }
   1617       } else {
   1618         /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
   1619            then too many bits were read and obviously no more RawDataBlocks can
   1620            be read. Set numberOfRawDataBlocks to zero to attempt a new sync
   1621            attempt. */
   1622         if ((INT)FDKgetValidBits(hBs) <= 0) {
   1623           hTp->numberOfRawDataBlocks = 0;
   1624         }
   1625       }
   1626     } break;
   1627     default:
   1628       break;
   1629   }
   1630 
   1631   err = transportDec_AdjustEndOfAccessUnit(hTp);
   1632 
   1633   switch (hTp->transportFmt) {
   1634     default:
   1635       break;
   1636   }
   1637 
   1638   return err;
   1639 }
   1640 
   1641 TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
   1642                                          const TPDEC_PARAM param,
   1643                                          const INT value) {
   1644   TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
   1645 
   1646   if (hTp == NULL) {
   1647     return TRANSPORTDEC_INVALID_PARAMETER;
   1648   }
   1649 
   1650   switch (param) {
   1651     case TPDEC_PARAM_MINIMIZE_DELAY:
   1652       if (value) {
   1653         hTp->flags |= TPDEC_MINIMIZE_DELAY;
   1654       } else {
   1655         hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
   1656       }
   1657       break;
   1658     case TPDEC_PARAM_EARLY_CONFIG:
   1659       if (value) {
   1660         hTp->flags |= TPDEC_EARLY_CONFIG;
   1661       } else {
   1662         hTp->flags &= ~TPDEC_EARLY_CONFIG;
   1663       }
   1664       break;
   1665     case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
   1666       if (value) {
   1667         hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
   1668       } else {
   1669         hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
   1670       }
   1671       break;
   1672     case TPDEC_PARAM_SET_BITRATE:
   1673       hTp->avgBitRate = value;
   1674       break;
   1675     case TPDEC_PARAM_BURST_PERIOD:
   1676       hTp->burstPeriod = value;
   1677       break;
   1678     case TPDEC_PARAM_RESET: {
   1679       int i;
   1680 
   1681       for (i = 0; i < (1 * 1); i++) {
   1682         FDKresetBitbuffer(&hTp->bitStream[i]);
   1683         hTp->auLength[i] = 0;
   1684         hTp->accessUnitAnchor[i] = 0;
   1685       }
   1686       hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
   1687       if (hTp->transportFmt != TT_MP4_ADIF) {
   1688         hTp->flags &= ~TPDEC_CONFIG_FOUND;
   1689       }
   1690       hTp->remainder = 0;
   1691       hTp->avgBitRate = 0;
   1692       hTp->missingAccessUnits = 0;
   1693       hTp->numberOfRawDataBlocks = 0;
   1694       hTp->globalFramePos = 0;
   1695       hTp->holdOffFrames = 0;
   1696     } break;
   1697     case TPDEC_PARAM_TARGETLAYOUT:
   1698       hTp->targetLayout = value;
   1699       break;
   1700     case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
   1701       hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
   1702       break;
   1703     case TPDEC_PARAM_USE_ELEM_SKIPPING:
   1704       if (value) {
   1705         hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
   1706       } else {
   1707         hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
   1708       }
   1709       break;
   1710   }
   1711 
   1712   return error;
   1713 }
   1714 
   1715 UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
   1716   UINT nSubFrames = 0;
   1717 
   1718   if (hTp == NULL) return 0;
   1719 
   1720   if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
   1721       hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
   1722     nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
   1723   else if (hTp->transportFmt == TT_MP4_ADTS)
   1724     nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
   1725 
   1726   return nSubFrames;
   1727 }
   1728 
   1729 void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
   1730   if (phTp != NULL) {
   1731     if (*phTp != NULL) {
   1732       FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
   1733       FreeRam_TransportDecoder(phTp);
   1734     }
   1735   }
   1736 }
   1737 
   1738 TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
   1739   int i;
   1740 
   1741   if (info == NULL) {
   1742     return TRANSPORTDEC_UNKOWN_ERROR;
   1743   }
   1744 
   1745   /* search for next free tab */
   1746   for (i = 0; i < FDK_MODULE_LAST; i++) {
   1747     if (info[i].module_id == FDK_NONE) break;
   1748   }
   1749   if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
   1750   info += i;
   1751 
   1752   info->module_id = FDK_TPDEC;
   1753 #ifdef __ANDROID__
   1754   info->build_date = "";
   1755   info->build_time = "";
   1756 #else
   1757   info->build_date = __DATE__;
   1758   info->build_time = __TIME__;
   1759 #endif
   1760   info->title = TP_LIB_TITLE;
   1761   info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
   1762   LIB_VERSION_STRING(info);
   1763   info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
   1764                 CAPF_RAWPACKETS | CAPF_DRM;
   1765 
   1766   return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
   1767 }
   1768 
   1769 int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
   1770   switch (pTp->transportFmt) {
   1771     case TT_MP4_ADTS:
   1772       return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
   1773     case TT_DRM:
   1774       return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
   1775     default:
   1776       return -1;
   1777   }
   1778 }
   1779 
   1780 void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
   1781   switch (pTp->transportFmt) {
   1782     case TT_MP4_ADTS:
   1783       adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
   1784       break;
   1785     case TT_DRM:
   1786       drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
   1787       break;
   1788     default:
   1789       break;
   1790   }
   1791 }
   1792 
   1793 TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
   1794   switch (pTp->transportFmt) {
   1795     case TT_MP4_ADTS:
   1796       if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
   1797           (pTp->parser.adts.bs.protection_absent == 0)) {
   1798         transportDec_AdjustEndOfAccessUnit(pTp);
   1799       }
   1800       return adtsRead_CrcCheck(&pTp->parser.adts);
   1801     case TT_DRM:
   1802       return drmRead_CrcCheck(&pTp->parser.drm);
   1803     default:
   1804       return TRANSPORTDEC_OK;
   1805   }
   1806 }
   1807 
   1808 TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
   1809                                                            const UINT length) {
   1810   CSAudioSpecificConfig asc;
   1811   FDK_BITSTREAM bs;
   1812   HANDLE_FDK_BITSTREAM hBs = &bs;
   1813 
   1814   FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);
   1815 
   1816   TRANSPORTDEC_ERROR err =
   1817       DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);
   1818 
   1819   return err;
   1820 }
   1821