/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */

/******************* MPEG transport format decoder library *********************

   Author(s):   Manuel Jander

   Description: MPEG Transport decoder

*******************************************************************************/

#include "tpdec_lib.h"

/* library version */
#include "tp_version.h"

#include "tp_data.h"

#include "tpdec_adts.h"

#include "tpdec_adif.h"

#include "tpdec_latm.h"

#include "tpdec_drm.h"

#include "FDK_crc.h"

#define MODULE_NAME "transportDec"

typedef union {
  STRUCT_ADTS adts;

  CAdifHeader adif;

  CLatmDemux latm;

  STRUCT_DRM drm;

} transportdec_parser_t;

#define MHAS_CONFIG_PRESENT 0x001
#define MHAS_UI_PRESENT 0x002

struct TRANSPORTDEC {
  TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */

  CSTpCallBacks callbacks; /*!< Struct holding callback and its data */

  FDK_BITSTREAM bitStream[1]; /* Bitstream reader */
  UCHAR *bsBuffer;            /* Internal bitstreamd data buffer */

  transportdec_parser_t parser; /* Format specific parser structs. */

  CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last
                                             config found. One additional
                                             CSAudioSpecificConfig is used
                                             temporarily for parsing. */
  CCtrlCFGChange ctrlCFGChange[(1 * 1)];  /* Controls config change */

  UINT globalFramePos;      /* Global transport frame reference bit position. */
  UINT accessUnitAnchor[1]; /* Current access unit start bit position. */
  INT auLength[1];          /* Length of current access unit. */
  INT numberOfRawDataBlocks; /* Current number of raw data blocks contained
                                remaining from the current transport frame. */
  UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
  UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame
                                   loss estimation */
  INT remainder; /* Reminder in division during lost access unit estimation. */
  INT missingAccessUnits; /* Estimated missing access units. */
  UINT burstPeriod;       /* Data burst period in mili seconds. */
  UINT holdOffFrames;     /* Amount of frames that were already hold off due to
                             buffer fullness condition not being met. */
  UINT flags;             /* Flags. */
  INT targetLayout;       /* CICP target layout. */
  UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and
                                     length (bytes) of loudnessInfoSet within
                                     rsv603daConfig.  */
};

/* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
#define TPDEC_SYNCOK 1
#define TPDEC_MINIMIZE_DELAY 2
#define TPDEC_IGNORE_BUFFERFULLNESS 4
#define TPDEC_EARLY_CONFIG 8
#define TPDEC_LOST_FRAMES_PENDING 16
#define TPDEC_CONFIG_FOUND 32
#define TPDEC_USE_ELEM_SKIPPING 64

/* force config/content change */
#define TPDEC_FORCE_CONFIG_CHANGE 1
#define TPDEC_FORCE_CONTENT_CHANGE 2

/* skip packet */
#define TPDEC_SKIP_PACKET 1

C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1)
C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4))

HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt,
                                      const UINT flags, const UINT nrOfLayers) {
  HANDLE_TRANSPORTDEC hInput;

  hInput = GetRam_TransportDecoder(0);
  if (hInput == NULL) {
    return NULL;
  }

  /* Init transportDec struct. */
  hInput->transportFmt = transportFmt;

  switch (transportFmt) {
    case TT_MP4_ADIF:
      break;

    case TT_MP4_ADTS:
      if (flags & TP_FLAG_MPEG4)
        hInput->parser.adts.decoderCanDoMpeg4 = 1;
      else
        hInput->parser.adts.decoderCanDoMpeg4 = 0;
      adtsRead_CrcInit(&hInput->parser.adts);
      hInput->parser.adts.BufferFullnesStartFlag = 1;
      hInput->numberOfRawDataBlocks = 0;
      break;

    case TT_DRM:
      drmRead_CrcInit(&hInput->parser.drm);
      break;

    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      hInput->parser.latm.usacExplicitCfgChanged = 0;
      hInput->parser.latm.applyAsc = 1;
      break;
    case TT_MP4_LOAS:
      hInput->parser.latm.usacExplicitCfgChanged = 0;
      hInput->parser.latm.applyAsc = 1;
      break;
    case TT_MP4_RAW:
      break;

    default:
      FreeRam_TransportDecoder(&hInput);
      hInput = NULL;
      break;
  }

  if (hInput != NULL) {
    /* Create bitstream */
    {
      hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
      if (hInput->bsBuffer == NULL) {
        transportDec_Close(&hInput);
        return NULL;
      }
      if (nrOfLayers > 1) {
        transportDec_Close(&hInput);
        return NULL;
      }
      for (UINT i = 0; i < nrOfLayers; i++) {
        FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
                         BS_READER);
      }
    }
    hInput->burstPeriod = 0;
  }

  return hInput;
}

TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
                                                UCHAR *conf, const UINT length,
                                                UINT layer) {
  int i;

  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;

  FDK_BITSTREAM bs;
  HANDLE_FDK_BITSTREAM hBs = &bs;

  int fConfigFound = 0;

  UCHAR configChanged = 0;
  UCHAR configMode = AC_CM_DET_CFG_CHANGE;

  UCHAR tmpConf[1024] = {0};
  if (length > 1024) {
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }
  FDKmemcpy(tmpConf, conf, length);
  FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);

  for (i = 0; i < 2; i++) {
    if (i > 0) {
      FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs));
      configMode = AC_CM_ALLOC_MEM;
    }

    /* config transport decoder */
    switch (hTp->transportFmt) {
      case TT_MP4_LATM_MCP0:
      case TT_MP4_LATM_MCP1:
      case TT_MP4_LOAS: {
        if (layer != 0) {
          return TRANSPORTDEC_INVALID_PARAMETER;
        }
        CLatmDemux *pLatmDemux = &hTp->parser.latm;
        err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks,
                                             hTp->asc, &fConfigFound,
                                             configMode, configChanged);
        if (err != TRANSPORTDEC_OK) {
          return err;
        }
      } break;
      default:
        fConfigFound = 1;
        err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
                                        &hTp->callbacks, configMode,
                                        configChanged, AOT_NULL_OBJECT);
        if (err == TRANSPORTDEC_OK) {
          int errC;

          hTp->asc[layer] = hTp->asc[(1 * 1)];
          errC = hTp->callbacks.cbUpdateConfig(
              hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
              hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
          if (errC != 0) {
            err = TRANSPORTDEC_PARSE_ERROR;
          }
        }
        break;
      case TT_DRM:
        fConfigFound = 1;
        err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks,
                                         configMode, configChanged);
        if (err == TRANSPORTDEC_OK) {
          int errC;

          errC = hTp->callbacks.cbUpdateConfig(
              hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
              hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
          if (errC != 0) {
            err = TRANSPORTDEC_PARSE_ERROR;
          }
        }
        break;
    }

    if (err == TRANSPORTDEC_OK) {
      if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
                       hTp->asc[layer].SbrConfigChanged ||
                       hTp->asc[layer].SacConfigChanged)) {
        int errC;

        configChanged = 1;
        errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
                                        &hTp->asc[layer]);
        if (errC != 0) {
          err = TRANSPORTDEC_PARSE_ERROR;
        }
      }
    }
  }

  if (err == TRANSPORTDEC_OK && fConfigFound) {
    hTp->flags |= TPDEC_CONFIG_FOUND;
  }

  return err;
}

TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
                                             UCHAR *newConfig,
                                             const UINT newConfigLength,
                                             const UCHAR buildUpStatus,
                                             UCHAR *configChanged, UINT layer,
                                             UCHAR *implicitExplicitCfgDiff) {
  int errC;
  FDK_BITSTREAM bs;
  HANDLE_FDK_BITSTREAM hBs = &bs;
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
  int fConfigFound = 0;
  UCHAR configMode = AC_CM_ALLOC_MEM;
  *implicitExplicitCfgDiff = 0;

  FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);

  FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
                   BS_READER);

  if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
      (hTp->ctrlCFGChange[layer].buildUpStatus !=
       TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
    if (hTp->asc->m_aot == AOT_USAC) {
      if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
          newConfigLength) {
        if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
                           newConfigLength)) {
          if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
                                                            LOAS/LATM parser */
            hTp->parser.latm.usacExplicitCfgChanged = 0;
            hTp->ctrlCFGChange[layer].flushCnt = 0;
            hTp->ctrlCFGChange[layer].flushStatus =
                TPDEC_USAC_DASH_IPF_FLUSH_ON;
            hTp->ctrlCFGChange[layer].buildUpCnt = 0;
            hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
          } else {
            *configChanged = 0;
            return err;
          }
        } else {
          *implicitExplicitCfgDiff = 1;
        }
      } else {
        *implicitExplicitCfgDiff = 1;
      }
      /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
       * config shall be identical. */
      if (*implicitExplicitCfgDiff) {
        switch (hTp->transportFmt) {
          case TT_MP4_LATM_MCP0:
          case TT_MP4_LATM_MCP1:
          case TT_MP4_LOAS:
            /* reset decoder to initial state to achieve definite behavior after
             * error in config */
            hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
                                     &hTp->asc[layer]);
            hTp->parser.latm.usacExplicitCfgChanged = 0;
            hTp->parser.latm.applyAsc = 1;
            err = TRANSPORTDEC_PARSE_ERROR;
            goto bail;
          default:
            break;
        }
      }
    }
  }

  {
    if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
        (hTp->ctrlCFGChange[layer].buildUpStatus !=
         TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
      hTp->ctrlCFGChange[layer].flushCnt = 0;
      hTp->ctrlCFGChange[layer].buildUpCnt = 0;
      hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
      if (hTp->asc->m_aot == AOT_USAC) {
        hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
      }
    }

    if ((hTp->ctrlCFGChange[layer].flushStatus ==
         TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
        (hTp->ctrlCFGChange[layer].flushStatus ==
         TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
      SCHAR counter = 0;
      if (hTp->asc->m_aot == AOT_USAC) {
        counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
      }
      if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
        hTp->ctrlCFGChange[layer].flushCnt = 0;
        hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
        hTp->ctrlCFGChange[layer].forceCfgChange = 0;
        if (hTp->asc->m_aot == AOT_USAC) {
          hTp->ctrlCFGChange[layer].buildUpCnt =
              TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
          hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
        }
      }

      /* Activate flush mode. After that continue with build up mode in core */
      if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
                                         &hTp->ctrlCFGChange[layer]) != 0) {
        err = TRANSPORTDEC_PARSE_ERROR;
      }

      if ((hTp->ctrlCFGChange[layer].flushStatus ==
           TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
          (hTp->ctrlCFGChange[layer].flushStatus ==
           TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
        hTp->ctrlCFGChange[layer].flushCnt++;
        return err;
      }
    }

    if (hTp->asc->m_aot == AOT_USAC) {
      fConfigFound = 1;

      if (err == TRANSPORTDEC_OK) {
        *configChanged = 0;
        configMode = AC_CM_DET_CFG_CHANGE;

        for (int i = 0; i < 2; i++) {
          if (i > 0) {
            FDKpushBack(hBs,
                        (INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
            configMode = AC_CM_ALLOC_MEM;
          }
          /* config transport decoder */
          err = AudioSpecificConfig_Parse(
              &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
              *configChanged, hTp->asc[layer].m_aot);
          if (err == TRANSPORTDEC_OK) {
            hTp->asc[layer] = hTp->asc[(1 * 1)];
            errC = hTp->callbacks.cbUpdateConfig(
                hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
                hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
            if (errC != 0) {
              err = TRANSPORTDEC_PARSE_ERROR;
            }
          }

          if (err == TRANSPORTDEC_OK) {
            if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
                             hTp->asc[layer].SbrConfigChanged ||
                             hTp->asc[layer].SacConfigChanged)) {
              *configChanged = 1;
              errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
                                              &hTp->asc[layer]);
              if (errC != 0) {
                err = TRANSPORTDEC_PARSE_ERROR;
              }
            }
          }

          /* if an error is detected terminate config parsing to avoid that an
           * invalid config is accepted in the second pass */
          if (err != TRANSPORTDEC_OK) {
            break;
          }
        }
      }
    }

  bail:
    /* save new config */
    if (err == TRANSPORTDEC_OK) {
      if (hTp->asc->m_aot == AOT_USAC) {
        hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
        FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
                  newConfigLength);
        /* in case of USAC reset transportDecoder variables here because
         * otherwise without IPF they are not reset */
        hTp->ctrlCFGChange[layer].flushCnt = 0;
        hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
        hTp->ctrlCFGChange[layer].buildUpCnt = 0;
        hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
      }
    } else {
      hTp->numberOfRawDataBlocks = 0;

      /* If parsing error while config found, clear ctrlCFGChange-struct */
      hTp->ctrlCFGChange[layer].flushCnt = 0;
      hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
      hTp->ctrlCFGChange[layer].buildUpCnt = 0;
      hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
      hTp->ctrlCFGChange[layer].cfgChanged = 0;
      hTp->ctrlCFGChange[layer].contentChanged = 0;
      hTp->ctrlCFGChange[layer].forceCfgChange = 0;

      hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
                                     &hTp->ctrlCFGChange[layer]);
    }
  }

  if (err == TRANSPORTDEC_OK && fConfigFound) {
    hTp->flags |= TPDEC_CONFIG_FOUND;
  }

  return err;
}

int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
                                     const cbUpdateConfig_t cbUpdateConfig,
                                     void *user_data) {
  if (hTpDec == NULL) {
    return -1;
  }
  hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
  hTpDec->callbacks.cbUpdateConfigData = user_data;
  return 0;
}

int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
                                         const cbFreeMem_t cbFreeMem,
                                         void *user_data) {
  if (hTpDec == NULL) {
    return -1;
  }
  hTpDec->callbacks.cbFreeMem = cbFreeMem;
  hTpDec->callbacks.cbFreeMemData = user_data;
  return 0;
}

int transportDec_RegisterCtrlCFGChangeCallback(
    HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
    void *user_data) {
  if (hTpDec == NULL) {
    return -1;
  }
  hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
  hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
  return 0;
}

int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
                                     const cbSsc_t cbSsc, void *user_data) {
  if (hTpDec == NULL) {
    return -1;
  }
  hTpDec->callbacks.cbSsc = cbSsc;
  hTpDec->callbacks.cbSscData = user_data;
  return 0;
}

int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
                                     const cbSbr_t cbSbr, void *user_data) {
  if (hTpDec == NULL) {
    return -1;
  }
  hTpDec->callbacks.cbSbr = cbSbr;
  hTpDec->callbacks.cbSbrData = user_data;
  return 0;
}

int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
                                      const cbUsac_t cbUsac, void *user_data) {
  if (hTpDec == NULL) {
    return -1;
  }
  hTpDec->callbacks.cbUsac = cbUsac;
  hTpDec->callbacks.cbUsacData = user_data;
  return 0;
}

int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
                                              const cbUniDrc_t cbUniDrc,
                                              void *user_data,
                                              UINT *pLoudnessInfoSetPosition) {
  if (hTpDec == NULL) {
    return -1;
  }

  hTpDec->callbacks.cbUniDrc = cbUniDrc;
  hTpDec->callbacks.cbUniDrcData = user_data;

  hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
  return 0;
}

TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
                                         UCHAR *pBuffer, const UINT bufferSize,
                                         UINT *pBytesValid, const INT layer) {
  HANDLE_FDK_BITSTREAM hBs;

  if ((hTp == NULL) || (layer >= 1)) {
    return TRANSPORTDEC_INVALID_PARAMETER;
  }

  /* set bitbuffer shortcut */
  hBs = &hTp->bitStream[layer];

  if (TT_IS_PACKET(hTp->transportFmt)) {
    if (hTp->numberOfRawDataBlocks == 0) {
      FDKresetBitbuffer(hBs);
      FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
      if (*pBytesValid != 0) {
        return TRANSPORTDEC_TOO_MANY_BITS;
      }
    }
  } else {
    /* ... else feed bitbuffer with new stream data (append). */

    if (*pBytesValid == 0) {
      /* nothing to do */
      return TRANSPORTDEC_OK;
    } else {
      const int bytesValid = *pBytesValid;
      FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);

      if (hTp->numberOfRawDataBlocks > 0) {
        hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
        hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
      }
    }
  }

  return TRANSPORTDEC_OK;
}

HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
                                               const UINT layer) {
  return &hTp->bitStream[layer];
}

TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
  return hTp->transportFmt;
}

INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
  INT bufferFullness = -1;

  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
        bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
                         hTp->parser.adts.bs.adts_fullness * 32 *
                             getNumberOfEffectiveChannels(
                                 hTp->parser.adts.bs.channel_config);
      }
      break;
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
        bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
      }
      break;
    default:
      break;
  }

  return bufferFullness;
}

/**
 * \brief adjust bit stream position and the end of an access unit.
 * \param hTp transport decoder handle.
 * \return error code.
 */
static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
    HANDLE_TRANSPORTDEC hTp) {
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;

  switch (hTp->transportFmt) {
    case TT_MP4_ADIF:
      /* Do byte align at the end of raw_data_block() because UsacFrame() is not
       * byte aligned. */
      FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
      break;
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      if (hTp->numberOfRawDataBlocks == 0) {
        /* Do byte align at the end of AudioMuxElement. */
        FDKbyteAlign(hBs, hTp->globalFramePos);

        /* Check global frame length */
        if (hTp->transportFmt == TT_MP4_LOAS &&
            hTp->parser.latm.m_audioMuxLengthBytes > 0) {
          int loasOffset;

          loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
                        (INT)FDKgetValidBits(hBs)) -
                       (INT)hTp->globalFramePos;
          if (loasOffset != 0) {
            FDKpushBiDirectional(hBs, loasOffset);
            /* For ELD and other payloads there is an unknown amount of padding,
               so ignore unread bits, but throw an error only if too many bits
               where read. */
            if (loasOffset < 0) {
              err = TRANSPORTDEC_PARSE_ERROR;
            }
          }
        }
      }
      break;

    case TT_MP4_ADTS:
      if (hTp->parser.adts.bs.protection_absent == 0) {
        int offset;

        /* Calculate offset to end of AU */
        offset = hTp->parser.adts
                     .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
                                       hTp->numberOfRawDataBlocks]
                 << 3;
        /* CAUTION: The PCE (if available) is declared to be a part of the
         * header! */
        offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
                  16 + hTp->parser.adts.bs.num_pce_bits;
        FDKpushBiDirectional(hBs, offset);
      }
      if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
          hTp->parser.adts.bs.protection_absent == 0) {
        /* Note this CRC read currently happens twice because of
         * transportDec_CrcCheck() */
        hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
      }
      if (hTp->numberOfRawDataBlocks == 0) {
        /* Check global frame length */
        if (hTp->parser.adts.bs.protection_absent == 0) {
          int offset;

          offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
                    (INT)FDKgetValidBits(hBs)) -
                   (INT)hTp->globalFramePos;
          if (offset != 0) {
            FDKpushBiDirectional(hBs, offset);
          }
        }
      }
      break;

    default:
      break;
  }

  return err;
}

/**
 * \brief Determine additional buffer fullness contraint due to burst data
 * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
 * precondition.
 * \param hTp transport decoder handle.
 * \param bufferFullness the buffer fullness value of the first frame to be
 * decoded.
 * \param bitsAvail the amount of available bits at the end of the first frame
 * to be decoded.
 * \return error code
 */
static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
                                                  INT bufferFullness,
                                                  INT bitsAvail) {
  INT checkLengthBits, avgBitsPerFrame;
  INT maxAU; /* maximum number of frames per Master Frame */
  INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
  INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;

  if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
    return TRANSPORTDEC_OK;
  }
  if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
    return TRANSPORTDEC_NOT_ENOUGH_BITS;
  }

  /* One Master Frame is sent every hTp->burstPeriod ms */
  maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
  maxAU = maxAU / (samplesPerFrame * 1000);
  /* Subtract number of frames which were already held off. */
  maxAU -= hTp->holdOffFrames;

  avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
  avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;

  /* Consider worst case of bufferFullness quantization. */
  switch (hTp->transportFmt) {
    case TT_MP4_ADIF:
    case TT_MP4_ADTS:
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      bufferFullness += 31;
      break;
    default: /* added to avoid compiler warning */
      break; /* added to avoid compiler warning */
  }

  checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;

  /* Check if buffer is big enough to fullfill buffer fullness condition */
  if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
    return TRANSPORTDEC_SYNC_ERROR;
  }

  if (bitsAvail < checkLengthBits) {
    return TRANSPORTDEC_NOT_ENOUGH_BITS;
  } else {
    return TRANSPORTDEC_OK;
  }
}

static TRANSPORTDEC_ERROR transportDec_readHeader(
    HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
    int ignoreBufferFullness, int *pRawDataBlockLength,
    int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
    int *pHeaderBits) {
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
  int rawDataBlockLength = *pRawDataBlockLength;
  int fTraverseMoreFrames =
      (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
  int syncLayerFrameBits =
      (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
  int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
  int startPos;

  startPos = (INT)FDKgetValidBits(hBs);

  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      if (hTp->numberOfRawDataBlocks <= 0) {
        int i, errC;

        hTp->globalFramePos = FDKgetValidBits(hBs);

        UCHAR configChanged = 0;
        UCHAR configMode = AC_CM_DET_CFG_CHANGE;

        for (i = 0; i < 2; i++) {
          if (i > 0) {
            FDKpushBack(hBs,
                        (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
            configMode = AC_CM_ALLOC_MEM;
          }

          /* Parse ADTS header */
          err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
                                      ignoreBufferFullness);
          if (err != TRANSPORTDEC_OK) {
            if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          } else {
            errC = hTp->callbacks.cbUpdateConfig(
                hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
                &configChanged);
            if (errC != 0) {
              if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
                err = TRANSPORTDEC_NEED_TO_RESTART;
                goto bail;
              } else {
                err = TRANSPORTDEC_SYNC_ERROR;
              }
            } else {
              fConfigFound = 1;
              hTp->numberOfRawDataBlocks =
                  hTp->parser.adts.bs.num_raw_blocks + 1;
            }
          }

          if (err == TRANSPORTDEC_OK) {
            if ((i == 0) && configChanged) {
              errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
                                              &hTp->asc[0]);
              if (errC != 0) {
                err = TRANSPORTDEC_PARSE_ERROR;
              }
            }
          }
          /* if an error is detected terminate config parsing to avoid that an
           * invalid config is accepted in the second pass */
          if (err != TRANSPORTDEC_OK) {
            break;
          }
        }
      } else {
        /* Reset CRC because the next bits are the beginning of a
         * raw_data_block() */
        FDKcrcReset(&hTp->parser.adts.crcInfo);
        hTp->parser.adts.bs.num_pce_bits = 0;
      }
      if (err == TRANSPORTDEC_OK) {
        hTp->numberOfRawDataBlocks--;
        rawDataBlockLength = adtsRead_GetRawDataBlockLength(
            &hTp->parser.adts,
            (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
        if (rawDataBlockLength <= 0) {
          /* No further frame traversal possible. */
          fTraverseMoreFrames = 0;
        }
        syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
                             (startPos - (INT)FDKgetValidBits(hBs)) -
                             syncLength;
        if (syncLayerFrameBits <= 0) {
          err = TRANSPORTDEC_SYNC_ERROR;
        }
      } else {
        hTp->numberOfRawDataBlocks = 0;
      }
      break;
    case TT_MP4_LOAS:
      if (hTp->numberOfRawDataBlocks <= 0) {
        syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
        hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
        syncLayerFrameBits <<= 3;
      }
      FDK_FALLTHROUGH;
    case TT_MP4_LATM_MCP1:
    case TT_MP4_LATM_MCP0:
      if (hTp->numberOfRawDataBlocks <= 0) {
        hTp->globalFramePos = FDKgetValidBits(hBs);

        err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
                              &hTp->callbacks, hTp->asc, &fConfigFound,
                              ignoreBufferFullness);

        if (err != TRANSPORTDEC_OK) {
          if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
              !TPDEC_IS_FATAL_ERROR(err)) {
            err = TRANSPORTDEC_SYNC_ERROR;
          }
        } else {
          hTp->numberOfRawDataBlocks =
              CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
          if (hTp->transportFmt == TT_MP4_LOAS) {
            syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
            if (syncLayerFrameBits <= 0) {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          }
        }
      } else {
        err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
        if (err != TRANSPORTDEC_OK) {
          err = TRANSPORTDEC_SYNC_ERROR;
        }
      }
      if (err == TRANSPORTDEC_OK) {
        int layer;
        rawDataBlockLength = 0;
        for (layer = 0;
             layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
             layer += 1) {
          rawDataBlockLength +=
              CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
        }
        hTp->numberOfRawDataBlocks--;
      } else {
        hTp->numberOfRawDataBlocks = 0;
      }
      break;
    default: { syncLayerFrameBits = 0; } break;
  }

bail:

  *pRawDataBlockLength = rawDataBlockLength;

  if (pHeaderBits != NULL) {
    *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
  }

  for (int i = 0; i < (1 * 1); i++) {
    /* If parsing error while config found, clear ctrlCFGChange-struct */
    if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
      hTp->numberOfRawDataBlocks = 0;
      hTp->ctrlCFGChange[i].flushCnt = 0;
      hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
      hTp->ctrlCFGChange[i].buildUpCnt = 0;
      hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
      hTp->ctrlCFGChange[i].cfgChanged = 0;
      hTp->ctrlCFGChange[i].contentChanged = 0;
      hTp->ctrlCFGChange[i].forceCfgChange = 0;

      hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
                                     &hTp->ctrlCFGChange[i]);
    }
  }

  if (pfConfigFound != NULL) {
    *pfConfigFound = fConfigFound;
  }

  if (pfTraverseMoreFrames != NULL) {
    *pfTraverseMoreFrames = fTraverseMoreFrames;
  }
  if (pSyncLayerFrameBits != NULL) {
    *pSyncLayerFrameBits = syncLayerFrameBits;
  }

  return err;
}

/* How many bits to advance for synchronization search. */
#define TPDEC_SYNCSKIP 8

static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
                                          INT *pHeaderBits) {
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];

  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
  INT totalBits;
  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
  INT numFramesTraversed = 0, fTraverseMoreFrames,
      fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
      globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
  INT ignoreBufferFullness =
      hTp->flags &
      (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
  UINT endTpFrameBitsPrevious = 0;

  /* Synch parameters */
  INT syncLength; /* Length of sync word in bits */
  UINT syncWord;  /* Sync word to be found */
  UINT syncMask;  /* Mask for sync word (for adding one bit, so comprising one
                     bit less) */
  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);

  totalBits = (INT)FDKgetValidBits(hBs);

  if (totalBits <= 0) {
    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
    goto bail;
  }

  fTraverseMoreFrames =
      (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
      !(hTp->flags & TPDEC_SYNCOK);

  /* Set transport specific sync parameters */
  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      syncWord = ADTS_SYNCWORD;
      syncLength = ADTS_SYNCLENGTH;
      break;
    case TT_MP4_LOAS:
      syncWord = 0x2B7;
      syncLength = 11;
      break;
    default:
      syncWord = 0;
      syncLength = 0;
      break;
  }

  syncMask = (1 << syncLength) - 1;

  do {
    INT bitsAvail = 0;   /* Bits available in bitstream buffer    */
    INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
                          */
    UINT synch;          /* Current sync word read from bitstream */

    headerBitsPrevious = headerBits;

    bitsAvail = (INT)FDKgetValidBits(hBs);

    if (hTp->numberOfRawDataBlocks == 0) {
      /* search synchword */

      FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);

      if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        headerBits = 0;
      } else {
        synch = FDKreadBits(hBs, syncLength);

        if (!(hTp->flags & TPDEC_SYNCOK)) {
          for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
               bitsAvail -= TPDEC_SYNCSKIP) {
            if (synch == syncWord) {
              break;
            }
            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
                    FDKreadBits(hBs, TPDEC_SYNCSKIP);
          }
        }
        if (synch != syncWord) {
          /* No correct syncword found. */
          err = TRANSPORTDEC_SYNC_ERROR;
        } else {
          err = TRANSPORTDEC_OK;
        }
        headerBits = syncLength;
      }
    } else {
      headerBits = 0;
    }

    /* Save previous raw data block data */
    rawDataBlockLengthPrevious = rawDataBlockLength;
    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;

    /* Parse transport header (raw data block granularity) */

    if (err == TRANSPORTDEC_OK) {
      err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
                                    &rawDataBlockLength, &fTraverseMoreFrames,
                                    &syncLayerFrameBits, &fConfigFound,
                                    &headerBits);
      if (headerBits > bitsAvail) {
        err = (headerBits < (INT)hBs->hBitBuf.bufBits)
                  ? TRANSPORTDEC_NOT_ENOUGH_BITS
                  : TRANSPORTDEC_SYNC_ERROR;
      }
      if (TPDEC_IS_FATAL_ERROR(err)) {
        /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
         * next time. Ensure that the bit amount lands at a multiple of
         * TPDEC_SYNCSKIP. */
        FDKpushBiDirectional(
            hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP));

        goto bail;
      }
    }

    bitsAvail -= headerBits;

    checkLengthBits = syncLayerFrameBits;

    /* Check if the whole frame would fit the bitstream buffer */
    if (err == TRANSPORTDEC_OK) {
      if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
        /* We assume that the size of the transport bit buffer has been
           chosen to meet all system requirements, thus this condition
           is considered a synchronisation error. */
        err = TRANSPORTDEC_SYNC_ERROR;
      } else {
        if (bitsAvail < checkLengthBits) {
          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        }
      }
    }

    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      break;
    }

    if (err == TRANSPORTDEC_SYNC_ERROR) {
      int bits;

      /* Enforce re-sync of transport headers. */
      hTp->numberOfRawDataBlocks = 0;

      /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
       * next time. */
      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
      headerBits = 0;
    }

    /* Frame traversal */
    if (fTraverseMoreFrames) {
      /* Save parser context for early config discovery "rewind all frames" */
      if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
          !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
        /* ignore buffer fullness if just traversing additional frames for ECD
         */
        ignoreBufferFullness = 1;

        /* Save context in order to return later */
        if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
          startPosFirstFrame = FDKgetValidBits(hBs);
          numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
          globalFramePosFirstFrame = hTp->globalFramePos;
          rawDataBlockLengthFirstFrame = rawDataBlockLength;
          headerBitsFirstFrame = headerBits;
          errFirstFrame = err;
          FDKmemcpy(contextFirstFrame, &hTp->parser,
                    sizeof(transportdec_parser_t));
        }

        /* Break when config was found or it is not possible anymore to find a
         * config */
        if (startPosFirstFrame != -1 &&
            (fConfigFound || err != TRANSPORTDEC_OK)) {
          /* In case of ECD and sync error, do not rewind anywhere. */
          if (err == TRANSPORTDEC_SYNC_ERROR) {
            startPosFirstFrame = -1;
            fConfigFound = 0;
            numFramesTraversed = 0;
          }
          break;
        }
      }

      if (err == TRANSPORTDEC_OK) {
        FDKpushFor(hBs, rawDataBlockLength);
        numFramesTraversed++;
        endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
        /* Ignore error here itentionally. */
        transportDec_AdjustEndOfAccessUnit(hTp);
        endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
      }
    }
  } while (fTraverseMoreFrames ||
           (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));

  /* Restore context in case of ECD frame traversal */
  if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
    FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
    FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
    hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
    hTp->globalFramePos = globalFramePosFirstFrame;
    rawDataBlockLength = rawDataBlockLengthFirstFrame;
    headerBits = headerBitsFirstFrame;
    err = errFirstFrame;
    numFramesTraversed = 0;
  }

  /* Additional burst data mode buffer fullness check. */
  if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
                      TPDEC_SYNCOK)) &&
      err == TRANSPORTDEC_OK) {
    err =
        additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
                                (INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      hTp->holdOffFrames++;
    }
  }

  /* Rewind for retry because of not enough bits */
  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
    FDKpushBack(hBs, headerBits);
    hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
    headerBits = 0;
    rawDataBlockLength = rawDataBlockLengthPrevious;
  } else {
    /* reset hold off frame counter */
    hTp->holdOffFrames = 0;
  }

  /* Return to last good frame in case of frame traversal but not ECD. */
  if (numFramesTraversed > 0) {
    FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
    if (err != TRANSPORTDEC_OK) {
      hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
      headerBits = headerBitsPrevious;
      rawDataBlockLength = rawDataBlockLengthPrevious;
    }
    err = TRANSPORTDEC_OK;
  }

bail:
  hTp->auLength[0] = rawDataBlockLength;

  /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
     buffer is already full, or no new burst packet fits. Recover by advancing
     the bit buffer. */
  if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
      (FDKgetValidBits(hBs) >=
       (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
        7))) {
    FDKpushFor(hBs, TPDEC_SYNCSKIP);
    err = TRANSPORTDEC_SYNC_ERROR;
  }

  if (err == TRANSPORTDEC_OK) {
    hTp->flags |= TPDEC_SYNCOK;
  }

  if (fConfigFound) {
    hTp->flags |= TPDEC_CONFIG_FOUND;
  }

  if (pHeaderBits != NULL) {
    *pHeaderBits = headerBits;
  }

  if (err == TRANSPORTDEC_SYNC_ERROR) {
    hTp->flags &= ~TPDEC_SYNCOK;
  }

  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);

  return err;
}

/**
 * \brief Synchronize to stream and estimate the amount of missing access units
 * due to a current synchronization error in case of constant average bit rate.
 */
static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
                                                  const UINT layer) {
  TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];

  INT headerBits;
  INT bitDistance, bfDelta;

  /* Obtain distance to next synch word */
  bitDistance = (INT)FDKgetValidBits(hBs);
  error = synchronization(hTp, &headerBits);
  bitDistance -= (INT)FDKgetValidBits(hBs);

  FDK_ASSERT(bitDistance >= 0);

  INT nAU = -1;

  if (error == TRANSPORTDEC_SYNC_ERROR ||
      (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
    /* Check if estimating lost access units is feasible. */
    if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
        hTp->asc[0].m_samplingFrequency > 0) {
      if (error == TRANSPORTDEC_OK) {
        int aj;

        aj = transportDec_GetBufferFullness(hTp);
        if (aj > 0) {
          bfDelta = aj;
        } else {
          bfDelta = 0;
        }
        /* sync was ok: last of a series of bad access units. */
        hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
        /* Add up bitDistance until end of the current frame. Later we substract
           this frame from the grand total, since this current successfully
           synchronized frame should not be skipped of course; but it must be
           accounted into the bufferfulness math. */
        bitDistance += hTp->auLength[0];
      } else {
        if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
          /* sync not ok: one of many bad access units. */
          hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
          bfDelta = -(INT)hTp->lastValidBufferFullness;
        } else {
          bfDelta = 0;
        }
      }

      {
        int num, denom;

        /* Obtain estimate of number of lost frames */
        num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
              hTp->remainder;
        denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
        if (num > 0) {
          nAU = num / denom;
          hTp->remainder = num % denom;
        } else {
          hTp->remainder = num;
        }

        if (error == TRANSPORTDEC_OK) {
          /* Final adjustment of remainder, taken -1 into account because
             current frame should not be skipped, thus substract -1 or do
             nothing instead of +1-1 accordingly. */
          if ((denom - hTp->remainder) >= hTp->remainder) {
            nAU--;
          }

          if (nAU < 0) {
            /* There was one frame too much concealed, so unfortunately we will
             * have to skip one good frame. */
            transportDec_EndAccessUnit(hTp);
            error = synchronization(hTp, &headerBits);
            nAU = -1;
          }
          hTp->remainder = 0;
          /* Enforce last missed frames to be concealed. */
          if (nAU > 0) {
            FDKpushBack(hBs, headerBits);
          }
        }
      }
    }
  }

  /* Be sure that lost frames are handled correctly. This is necessary due to
     some sync error sequences where later it turns out that there is not enough
     data, but the bits upto the sync word are discarded, thus causing a value
     of nAU > 0 */
  if (nAU > 0) {
    error = TRANSPORTDEC_SYNC_ERROR;
  }

  hTp->missingAccessUnits = nAU;

  return error;
}

/* returns error code */
TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
                                               const UINT layer) {
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs;

  if (!hTp) {
    return TRANSPORTDEC_INVALID_PARAMETER;
  }

  hBs = &hTp->bitStream[layer];

  if ((INT)FDKgetValidBits(hBs) <= 0) {
    /* This is only relevant for RAW and ADIF cases.
     * For streaming formats err will get overwritten. */
    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
    hTp->numberOfRawDataBlocks = 0;
  }

  switch (hTp->transportFmt) {
    case TT_MP4_ADIF:
      /* Read header if not already done */
      if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
        int i;
        CProgramConfig *pce;
        INT bsStart = FDKgetValidBits(hBs);
        UCHAR configChanged = 0;
        UCHAR configMode = AC_CM_DET_CFG_CHANGE;

        for (i = 0; i < 2; i++) {
          if (i > 0) {
            FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
            configMode = AC_CM_ALLOC_MEM;
          }

          AudioSpecificConfig_Init(&hTp->asc[0]);
          pce = &hTp->asc[0].m_progrConfigElement;
          err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
          if (err) goto bail;

          /* Map adif header to ASC */
          hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
          hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
          hTp->asc[0].m_samplingFrequency =
              SamplingRateTable[pce->SamplingFrequencyIndex];
          hTp->asc[0].m_channelConfiguration = 0;
          hTp->asc[0].m_samplesPerFrame = 1024;
          hTp->avgBitRate = hTp->parser.adif.BitRate;

          /* Call callback to decoder. */
          {
            int errC;

            errC = hTp->callbacks.cbUpdateConfig(
                hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
                &configChanged);
            if (errC == 0) {
              hTp->flags |= TPDEC_CONFIG_FOUND;
            } else {
              err = TRANSPORTDEC_PARSE_ERROR;
              goto bail;
            }
          }

          if (err == TRANSPORTDEC_OK) {
            if ((i == 0) && configChanged) {
              int errC;
              errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
                                              &hTp->asc[0]);
              if (errC != 0) {
                err = TRANSPORTDEC_PARSE_ERROR;
              }
            }
          }
        }
      }
      hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
      break;

    case TT_MP4_RAW:
    case TT_DRM:
      /* One Access Unit was filled into buffer.
         So get the length out of the buffer. */
      hTp->auLength[layer] = FDKgetValidBits(hBs);
      hTp->flags |= TPDEC_SYNCOK;
      break;

    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      if (err == TRANSPORTDEC_OK) {
        int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
        err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
                                      NULL, NULL, &fConfigFound, NULL);
        if (fConfigFound) {
          hTp->flags |= TPDEC_CONFIG_FOUND;
        }
      }
      break;

    case TT_MP4_ADTS:
    case TT_MP4_LOAS:
      err = transportDec_readStream(hTp, layer);
      break;

    default:
      err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
      break;
  }

  if (err == TRANSPORTDEC_OK) {
    hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
  } else {
    hTp->accessUnitAnchor[layer] = 0;
  }

bail:
  return err;
}

TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
                                       const UINT layer,
                                       CSAudioSpecificConfig *asc) {
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;

  if (hTp != NULL) {
    *asc = hTp->asc[layer];
    err = TRANSPORTDEC_OK;
  } else {
    err = TRANSPORTDEC_INVALID_PARAMETER;
  }
  return err;
}

INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
                                    const UINT layer) {
  INT bits;

  if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
    bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
    if (bits >= 0) {
      bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
    }
  } else {
    bits = FDKgetValidBits(&hTp->bitStream[layer]);
  }

  return bits;
}

INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
                                const UINT layer) {
  return hTp->auLength[layer];
}

TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
    INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
  *pNAccessUnits = hTp->missingAccessUnits;

  return TRANSPORTDEC_OK;
}

/* Inform the transportDec layer that reading of access unit has finished. */
TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;

  switch (hTp->transportFmt) {
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1: {
      HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
      if (hTp->numberOfRawDataBlocks == 0) {
        /* Read other data if available. */
        if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
          int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);

          if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
            FDKpushFor(hBs, otherDataLen);
          } else {
            /* Do byte align at the end of AudioMuxElement. */
            if (hTp->numberOfRawDataBlocks == 0) {
              FDKbyteAlign(hBs, hTp->globalFramePos);
            }
            return TRANSPORTDEC_NOT_ENOUGH_BITS;
          }
        }
      } else {
        /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
           then too many bits were read and obviously no more RawDataBlocks can
           be read. Set numberOfRawDataBlocks to zero to attempt a new sync
           attempt. */
        if ((INT)FDKgetValidBits(hBs) <= 0) {
          hTp->numberOfRawDataBlocks = 0;
        }
      }
    } break;
    default:
      break;
  }

  err = transportDec_AdjustEndOfAccessUnit(hTp);

  switch (hTp->transportFmt) {
    default:
      break;
  }

  return err;
}

TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
                                         const TPDEC_PARAM param,
                                         const INT value) {
  TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;

  if (hTp == NULL) {
    return TRANSPORTDEC_INVALID_PARAMETER;
  }

  switch (param) {
    case TPDEC_PARAM_MINIMIZE_DELAY:
      if (value) {
        hTp->flags |= TPDEC_MINIMIZE_DELAY;
      } else {
        hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
      }
      break;
    case TPDEC_PARAM_EARLY_CONFIG:
      if (value) {
        hTp->flags |= TPDEC_EARLY_CONFIG;
      } else {
        hTp->flags &= ~TPDEC_EARLY_CONFIG;
      }
      break;
    case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
      if (value) {
        hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
      } else {
        hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
      }
      break;
    case TPDEC_PARAM_SET_BITRATE:
      hTp->avgBitRate = value;
      break;
    case TPDEC_PARAM_BURST_PERIOD:
      hTp->burstPeriod = value;
      break;
    case TPDEC_PARAM_RESET: {
      int i;

      for (i = 0; i < (1 * 1); i++) {
        FDKresetBitbuffer(&hTp->bitStream[i]);
        hTp->auLength[i] = 0;
        hTp->accessUnitAnchor[i] = 0;
      }
      hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
      if (hTp->transportFmt != TT_MP4_ADIF) {
        hTp->flags &= ~TPDEC_CONFIG_FOUND;
      }
      hTp->remainder = 0;
      hTp->avgBitRate = 0;
      hTp->missingAccessUnits = 0;
      hTp->numberOfRawDataBlocks = 0;
      hTp->globalFramePos = 0;
      hTp->holdOffFrames = 0;
    } break;
    case TPDEC_PARAM_TARGETLAYOUT:
      hTp->targetLayout = value;
      break;
    case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
      hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
      break;
    case TPDEC_PARAM_USE_ELEM_SKIPPING:
      if (value) {
        hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
      } else {
        hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
      }
      break;
  }

  return error;
}

UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
  UINT nSubFrames = 0;

  if (hTp == NULL) return 0;

  if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
      hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
    nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
  else if (hTp->transportFmt == TT_MP4_ADTS)
    nSubFrames = hTp->parser.adts.bs.num_raw_blocks;

  return nSubFrames;
}

void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
  if (phTp != NULL) {
    if (*phTp != NULL) {
      FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
      FreeRam_TransportDecoder(phTp);
    }
  }
}

TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
  int i;

  if (info == NULL) {
    return TRANSPORTDEC_UNKOWN_ERROR;
  }

  /* search for next free tab */
  for (i = 0; i < FDK_MODULE_LAST; i++) {
    if (info[i].module_id == FDK_NONE) break;
  }
  if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
  info += i;

  info->module_id = FDK_TPDEC;
#ifdef __ANDROID__
  info->build_date = "";
  info->build_time = "";
#else
  info->build_date = __DATE__;
  info->build_time = __TIME__;
#endif
  info->title = TP_LIB_TITLE;
  info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
  LIB_VERSION_STRING(info);
  info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
                CAPF_RAWPACKETS | CAPF_DRM;

  return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
}

int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
  switch (pTp->transportFmt) {
    case TT_MP4_ADTS:
      return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
    case TT_DRM:
      return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
    default:
      return -1;
  }
}

void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
  switch (pTp->transportFmt) {
    case TT_MP4_ADTS:
      adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
      break;
    case TT_DRM:
      drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
      break;
    default:
      break;
  }
}

TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
  switch (pTp->transportFmt) {
    case TT_MP4_ADTS:
      if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
          (pTp->parser.adts.bs.protection_absent == 0)) {
        transportDec_AdjustEndOfAccessUnit(pTp);
      }
      return adtsRead_CrcCheck(&pTp->parser.adts);
    case TT_DRM:
      return drmRead_CrcCheck(&pTp->parser.drm);
    default:
      return TRANSPORTDEC_OK;
  }
}

TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
                                                           const UINT length) {
  CSAudioSpecificConfig asc;
  FDK_BITSTREAM bs;
  HANDLE_FDK_BITSTREAM hBs = &bs;

  FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);

  TRANSPORTDEC_ERROR err =
      DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);

  return err;
}
