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

© Copyright  1995 - 2018 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];
  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, newConfigLength * 8 - 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;
    }

    if (hTp->numberOfRawDataBlocks <= 0) {
      FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
    }
  }

  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;
              }
            }
          }
        }
      } 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);
          }
        }
      } 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 (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) {
      /* Enforce reading of new data */
      hTp->numberOfRawDataBlocks = 0;
      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),
                                  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);
    headerBits = 0;
  } 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 - 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;
}
