1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2015 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and the date of any change. For modified versions of the FDK AAC Codec, the term
50"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84/**************************  MPEG-4 Transport Decoder  ************************
85
86   Author(s): Manuel Jander
87   Description: MPEG Transport decoder
88
89******************************************************************************/
90
91#include "tpdec_lib.h"
92
93/* library version */
94#include "version"
95
96
97#include "tp_data.h"
98
99#include "tpdec_adts.h"
100
101#include "tpdec_adif.h"
102
103#include "tpdec_latm.h"
104
105#include "tpdec_drm.h"
106
107
108#define MODULE_NAME "transportDec"
109
110typedef union {
111  STRUCT_ADTS adts;
112
113  CAdifHeader adif;
114
115  CLatmDemux latm;
116
117  STRUCT_DRM drm;
118
119} transportdec_parser_t;
120
121struct TRANSPORTDEC
122{
123  TRANSPORT_TYPE transportFmt;     /*!< MPEG4 transportDec type. */
124
125  CSTpCallBacks callbacks;         /*!< Struct holding callback and its data */
126
127  FDK_BITSTREAM bitStream[2]; /* Bitstream reader */
128  UCHAR *bsBuffer;                 /* Internal bitstreamd data buffer (unallocated in case of TT_MP4_RAWPACKETS) */
129
130  transportdec_parser_t parser;    /* Format specific parser structs. */
131
132  CSAudioSpecificConfig asc[(1*2)]; /* Audio specific config from the last config found. */
133  UINT  globalFramePos;            /* Global transport frame reference bit position. */
134  UINT  accessUnitAnchor[2];    /* Current access unit start bit position. */
135  INT   auLength[2];            /* Length of current access unit. */
136  INT   numberOfRawDataBlocks;     /* Current number of raw data blocks contained remaining from the current transport frame. */
137  UINT  avgBitRate;                /* Average bit rate used for frame loss estimation. */
138  UINT  lastValidBufferFullness;   /* Last valid buffer fullness value for frame loss estimation */
139  INT   remainder;                 /* Reminder in division during lost access unit estimation. */
140  INT   missingAccessUnits;        /* Estimated missing access units. */
141  UINT  burstPeriod;               /* Data burst period in mili seconds. */
142  UINT  holdOffFrames;             /* Amount of frames that were already hold off due to buffer fullness condition not being met. */
143  UINT  flags;                     /* Flags. */
144};
145
146/* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
147#define TPDEC_SYNCOK                1
148#define TPDEC_MINIMIZE_DELAY        2
149#define TPDEC_IGNORE_BUFFERFULLNESS 4
150#define TPDEC_EARLY_CONFIG          8
151#define TPDEC_LOST_FRAMES_PENDING  16
152#define TPDEC_CONFIG_FOUND         32
153
154C_ALLOC_MEM(Ram_TransportDecoder, TRANSPORTDEC, 1)
155C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, TRANSPORTDEC_INBUF_SIZE)
156
157
158
159
160HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const UINT flags)
161{
162  HANDLE_TRANSPORTDEC hInput;
163
164  hInput = GetRam_TransportDecoder(0);
165  if ( hInput == NULL ) {
166    return NULL;
167  }
168
169  /* Init transportDec struct. */
170  hInput->transportFmt = transportFmt;
171
172  switch (transportFmt) {
173
174  case TT_MP4_ADIF:
175    break;
176
177  case TT_MP4_ADTS:
178    if (flags & TP_FLAG_MPEG4)
179      hInput->parser.adts.decoderCanDoMpeg4 = 1;
180    else
181      hInput->parser.adts.decoderCanDoMpeg4 = 0;
182    adtsRead_CrcInit(&hInput->parser.adts);
183    hInput->parser.adts.BufferFullnesStartFlag = 1;
184    hInput->numberOfRawDataBlocks = 0;
185    break;
186
187  case TT_DRM:
188    drmRead_CrcInit(&hInput->parser.drm);
189    break;
190
191  case TT_MP4_LATM_MCP0:
192  case TT_MP4_LATM_MCP1:
193  case TT_MP4_LOAS:
194  case TT_MP4_RAW:
195    break;
196
197  default:
198    FreeRam_TransportDecoder(&hInput);
199    hInput = NULL;
200    break;
201  }
202
203  if (hInput != NULL) {
204    /* Create bitstream */
205    if ( TT_IS_PACKET(transportFmt) ) {
206      hInput->bsBuffer = NULL;
207    } else {
208      hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
209      if (hInput->bsBuffer == NULL) {
210          transportDec_Close( &hInput );
211          return NULL;
212      }
213      FDKinitBitStream(&hInput->bitStream[0], hInput->bsBuffer, TRANSPORTDEC_INBUF_SIZE, 0, BS_READER);
214    }
215
216    hInput->burstPeriod = 0;
217  }
218
219  return hInput;
220}
221
222TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *conf, const UINT length, UINT layer )
223{
224  TRANSPORTDEC_ERROR     err        = TRANSPORTDEC_OK;
225
226  FDK_BITSTREAM bs;
227  HANDLE_FDK_BITSTREAM  hBs        = &bs;
228
229  FDKinitBitStream(hBs, conf, 0x10000000, length<<3, BS_READER);
230
231  int fConfigFound = 0;
232
233  /* config transport decoder */
234  switch (hTp->transportFmt) {
235    case TT_MP4_LATM_MCP0:
236    case TT_MP4_LATM_MCP1:
237    case TT_MP4_LOAS:
238      {
239        if (layer != 0) {
240          return TRANSPORTDEC_INVALID_PARAMETER;
241        }
242        CLatmDemux *pLatmDemux = &hTp->parser.latm;
243        err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks, hTp->asc, &fConfigFound);
244        if (err != TRANSPORTDEC_OK) {
245          return err;
246        }
247      }
248      break;
249    default:
250      fConfigFound = 1;
251      err = AudioSpecificConfig_Parse(&hTp->asc[layer], hBs, 1, &hTp->callbacks);
252      if (err == TRANSPORTDEC_OK) {
253        int errC;
254
255        errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
256        if (errC != 0) {
257          err = TRANSPORTDEC_PARSE_ERROR;
258        }
259      }
260      break;
261    case TT_DRM:
262      fConfigFound = 1;
263      err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs);
264      if (err == TRANSPORTDEC_OK) {
265        int errC;
266
267        errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
268        if (errC != 0) {
269          err = TRANSPORTDEC_PARSE_ERROR;
270        }
271      }
272      break;
273  }
274
275  if (err == TRANSPORTDEC_OK && fConfigFound) {
276    hTp->flags |= TPDEC_CONFIG_FOUND;
277  }
278
279  return err;
280}
281
282int transportDec_RegisterAscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbUpdateConfig_t cbUpdateConfig, void* user_data)
283{
284  if (hTpDec == NULL) {
285    return -1;
286  }
287  hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
288  hTpDec->callbacks.cbUpdateConfigData = user_data;
289  return 0;
290}
291
292int transportDec_RegisterSscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSsc_t cbSsc, void* user_data)
293{
294  if (hTpDec == NULL) {
295    return -1;
296  }
297  hTpDec->callbacks.cbSsc = cbSsc;
298  hTpDec->callbacks.cbSscData = user_data;
299  return 0;
300}
301
302int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t cbSbr, void* user_data)
303{
304  if (hTpDec == NULL) {
305    return -1;
306  }
307  hTpDec->callbacks.cbSbr = cbSbr;
308  hTpDec->callbacks.cbSbrData = user_data;
309  return 0;
310}
311
312TRANSPORTDEC_ERROR transportDec_FillData(
313        const HANDLE_TRANSPORTDEC  hTp,
314        UCHAR                     *pBuffer,
315        const UINT                 bufferSize,
316        UINT                      *pBytesValid,
317        const INT                  layer )
318{
319  HANDLE_FDK_BITSTREAM hBs;
320
321  if ( (hTp == NULL)
322    || (layer >= 2) ) {
323    return TRANSPORTDEC_INVALID_PARAMETER;
324  }
325
326  if (*pBytesValid == 0) {
327    /* nothing to do */
328    return TRANSPORTDEC_OK;
329  }
330
331  /* set bitbuffer shortcut */
332  hBs = &hTp->bitStream[layer];
333
334  if ( TT_IS_PACKET(hTp->transportFmt) ) {
335    if (hTp->numberOfRawDataBlocks == 0) {
336    /* For packet based transport, pass input buffer to bitbuffer without copying the data.
337       Unfortunately we do not know the actual buffer size. And the FDK bit buffer implementation
338       needs a number 2^x. So we assume the maximum of 48 channels with 6144 bits per channel
339       and round it up to the next power of 2 => 65536 bytes */
340    FDKinitBitStream(hBs, pBuffer, 0x10000, (*pBytesValid)<<3, BS_READER);
341    *pBytesValid = 0;
342    }
343  } else {
344    /* ... else feed bitbuffer with new stream data (append). */
345    if (hTp->numberOfRawDataBlocks <= 0) {
346      FDKfeedBuffer (hBs, pBuffer, bufferSize, pBytesValid) ;
347    }
348  }
349
350  return TRANSPORTDEC_OK;
351}
352
353HANDLE_FDK_BITSTREAM transportDec_GetBitstream( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
354{
355  return &hTp->bitStream[layer];
356}
357
358TRANSPORT_TYPE transportDec_GetFormat( const HANDLE_TRANSPORTDEC hTp )
359{
360  return hTp->transportFmt;
361}
362
363INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp )
364{
365  INT bufferFullness = -1;
366
367  switch (hTp->transportFmt) {
368    case TT_MP4_ADTS:
369      if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
370        bufferFullness = hTp->parser.adts.bs.frame_length*8 + hTp->parser.adts.bs.adts_fullness * 32 * getNumberOfEffectiveChannels(hTp->parser.adts.bs.channel_config);
371      }
372      break;
373    case TT_MP4_LOAS:
374    case TT_MP4_LATM_MCP0:
375    case TT_MP4_LATM_MCP1:
376      if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
377        bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
378      }
379      break;
380    default:
381      break;
382  }
383
384  return bufferFullness;
385}
386
387/**
388 * \brief adjust bit stream position and the end of an access unit.
389 * \param hTp transport decoder handle.
390 * \return error code.
391 */
392static
393TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)
394{
395  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
396  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
397
398  switch (hTp->transportFmt) {
399    case TT_MP4_LOAS:
400    case TT_MP4_LATM_MCP0:
401    case TT_MP4_LATM_MCP1:
402      if ( hTp->numberOfRawDataBlocks == 0 )
403      {
404        /* Do byte align at the end of AudioMuxElement. */
405        FDKbyteAlign(hBs, hTp->globalFramePos);
406
407        /* Check global frame length */
408        if (hTp->transportFmt == TT_MP4_LOAS && hTp->parser.latm.m_audioMuxLengthBytes > 0)
409        {
410          int loasOffset;
411
412          loasOffset = (hTp->parser.latm.m_audioMuxLengthBytes*8 + FDKgetValidBits(hBs)) - hTp->globalFramePos;
413          if (loasOffset != 0) {
414            FDKpushBiDirectional(hBs, loasOffset);
415            /* For ELD and other payloads there is an unknown amount of padding, so ignore unread bits, but
416               throw an error only if too many bits where read. */
417            if (loasOffset < 0) {
418              err = TRANSPORTDEC_PARSE_ERROR;
419            }
420          }
421        }
422      }
423      break;
424
425    case TT_MP4_ADTS:
426      if (hTp->parser.adts.bs.protection_absent == 0)
427      {
428        int offset;
429
430        /* Calculate offset to end of AU */
431        offset  = hTp->parser.adts.rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks]<<3;
432        /* CAUTION: The PCE (if available) is declared to be a part of the header! */
433        offset -= hTp->accessUnitAnchor[0] - FDKgetValidBits(hBs) + 16 + hTp->parser.adts.bs.num_pce_bits;
434        FDKpushBiDirectional(hBs, offset);
435      }
436      if (hTp->parser.adts.bs.num_raw_blocks > 0 && hTp->parser.adts.bs.protection_absent == 0) {
437        /* Note this CRC read currently happens twice because of transportDec_CrcCheck() */
438        hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
439      }
440      if ( hTp->numberOfRawDataBlocks == 0 )
441      {
442        /* Check global frame length */
443        if (hTp->parser.adts.bs.protection_absent == 0)
444        {
445          int offset;
446
447          offset = (hTp->parser.adts.bs.frame_length*8 - ADTS_SYNCLENGTH + FDKgetValidBits(hBs)) - hTp->globalFramePos;
448          if (offset != 0) {
449            FDKpushBiDirectional(hBs, offset);
450          }
451        }
452      }
453      break;
454
455    default:
456      break;
457  }
458
459  return err;
460}
461
462
463/**
464 * \brief Determine additional buffer fullness contraint due to burst data reception.
465 *        The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a precondition.
466 * \param hTp transport decoder handle.
467 * \param bufferFullness the buffer fullness value of the first frame to be decoded.
468 * \param bitsAvail the amount of available bits at the end of the first frame to be decoded.
469 * \return error code
470 */
471static
472TRANSPORTDEC_ERROR additionalHoldOffNeeded(
473        HANDLE_TRANSPORTDEC hTp,
474        INT                 bufferFullness,
475        INT                 bitsAvail
476        )
477{
478  INT checkLengthBits, avgBitsPerFrame;
479  INT maxAU; /* maximum number of frames per Master Frame */
480  INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
481  INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
482
483  if ( (hTp->avgBitRate == 0) || (hTp->burstPeriod == 0) ) {
484    return TRANSPORTDEC_OK;
485  }
486  if ( (samplesPerFrame == 0 ) || (samplingFrequency == 0) ) {
487    return TRANSPORTDEC_NOT_ENOUGH_BITS;
488  }
489
490  /* One Master Frame is sent every hTp->burstPeriod ms */
491  maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame*1000 - 1);
492  maxAU = maxAU / (samplesPerFrame*1000);
493  /* Subtract number of frames which were already held off. */
494  maxAU -= hTp->holdOffFrames;
495
496  avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency-1);
497  avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
498
499  /* Consider worst case of bufferFullness quantization. */
500  switch (hTp->transportFmt) {
501    case TT_MP4_ADIF:
502    case TT_MP4_ADTS:
503    case TT_MP4_LOAS:
504    case TT_MP4_LATM_MCP0:
505    case TT_MP4_LATM_MCP1:
506      bufferFullness += 31;
507      break;
508    default:
509      break;
510  }
511
512  checkLengthBits = bufferFullness + (maxAU-1)*avgBitsPerFrame;
513
514  /* Check if buffer is big enough to fullfill buffer fullness condition */
515  if ( (checkLengthBits /*+headerBits*/) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
516    return TRANSPORTDEC_SYNC_ERROR;
517  }
518
519  if ( bitsAvail < checkLengthBits ) {
520    return TRANSPORTDEC_NOT_ENOUGH_BITS;
521  }
522  else {
523    return TRANSPORTDEC_OK;
524  }
525}
526
527static TRANSPORTDEC_ERROR transportDec_readHeader(
528        HANDLE_TRANSPORTDEC hTp,
529        HANDLE_FDK_BITSTREAM hBs,
530        int syncLength,
531        int ignoreBufferFullness,
532        int *pRawDataBlockLength,
533        int *pfTraverseMoreFrames,
534        int *pSyncLayerFrameBits,
535        int *pfConfigFound,
536        int *pHeaderBits
537        )
538{
539  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
540  int rawDataBlockLength = *pRawDataBlockLength;
541  int fTraverseMoreFrames = (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
542  int syncLayerFrameBits = (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
543  int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
544  int startPos;
545
546  startPos = FDKgetValidBits(hBs);
547
548  switch (hTp->transportFmt) {
549    case TT_MP4_ADTS:
550      if (hTp->numberOfRawDataBlocks <= 0)
551      {
552        int errC;
553
554        hTp->globalFramePos = FDKgetValidBits(hBs);
555
556        /* Parse ADTS header */
557        err = adtsRead_DecodeHeader( &hTp->parser.adts, &hTp->asc[0], hBs, ignoreBufferFullness );
558        if (err != TRANSPORTDEC_OK) {
559          if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
560            err = TRANSPORTDEC_SYNC_ERROR;
561          }
562        } else {
563          errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
564          if (errC != 0) {
565            if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
566              err = TRANSPORTDEC_NEED_TO_RESTART;
567              goto bail;
568            } else {
569              err = TRANSPORTDEC_SYNC_ERROR;
570            }
571          } else {
572            fConfigFound = 1;
573            hTp->numberOfRawDataBlocks = hTp->parser.adts.bs.num_raw_blocks+1;
574          }
575        }
576      }
577      else {
578        /* Reset CRC because the next bits are the beginning of a raw_data_block() */
579        FDKcrcReset(&hTp->parser.adts.crcInfo);
580        hTp->parser.adts.bs.num_pce_bits = 0;
581      }
582      if (err == TRANSPORTDEC_OK) {
583        hTp->numberOfRawDataBlocks--;
584        rawDataBlockLength = adtsRead_GetRawDataBlockLength(&hTp->parser.adts, (hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks));
585        if (rawDataBlockLength <= 0) {
586          /* No further frame traversal possible. */
587          fTraverseMoreFrames = 0;
588        }
589        syncLayerFrameBits = (hTp->parser.adts.bs.frame_length<<3) - (startPos - FDKgetValidBits(hBs)) - syncLength;
590        if (syncLayerFrameBits <= 0) {
591          err = TRANSPORTDEC_SYNC_ERROR;
592        }
593      } else {
594        hTp->numberOfRawDataBlocks = 0;
595      }
596      break;
597    case TT_MP4_LOAS:
598      if (hTp->numberOfRawDataBlocks <= 0)
599      {
600        syncLayerFrameBits = FDKreadBits(hBs, 13);
601        hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
602        syncLayerFrameBits <<= 3;
603      }
604    case TT_MP4_LATM_MCP1:
605    case TT_MP4_LATM_MCP0:
606      if (hTp->numberOfRawDataBlocks <= 0)
607      {
608        hTp->globalFramePos = FDKgetValidBits(hBs);
609
610        err = CLatmDemux_Read(
611                hBs,
612               &hTp->parser.latm,
613                hTp->transportFmt,
614               &hTp->callbacks,
615                hTp->asc,
616               &fConfigFound,
617                ignoreBufferFullness);
618
619        if (err != TRANSPORTDEC_OK) {
620          if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
621            err = TRANSPORTDEC_SYNC_ERROR;
622          }
623        } else {
624          hTp->numberOfRawDataBlocks = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
625          if (hTp->transportFmt == TT_MP4_LOAS) {
626            syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13);
627          }
628        }
629      } else {
630        err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
631        if (err != TRANSPORTDEC_OK) {
632          err = TRANSPORTDEC_SYNC_ERROR;
633        }
634      }
635      if (err == TRANSPORTDEC_OK) {
636        rawDataBlockLength = CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm);
637        hTp->numberOfRawDataBlocks--;
638      } else {
639        hTp->numberOfRawDataBlocks = 0;
640      }
641      break;
642    default:
643      {
644        syncLayerFrameBits = 0;
645      }
646      break;
647  }
648
649bail:
650
651  *pRawDataBlockLength = rawDataBlockLength;
652
653  if (pHeaderBits != NULL) {
654    *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
655  }
656  if (pfConfigFound != NULL) {
657    *pfConfigFound = fConfigFound;
658  }
659
660  if (pfTraverseMoreFrames != NULL) {
661    *pfTraverseMoreFrames = fTraverseMoreFrames;
662  }
663  if  (pSyncLayerFrameBits != NULL) {
664    *pSyncLayerFrameBits = syncLayerFrameBits;
665  }
666  if (pfConfigFound != NULL) {
667    *pfConfigFound = fConfigFound;
668  }
669
670  return err;
671}
672
673/* How many bits to advance for synchronization search. */
674#define TPDEC_SYNCSKIP 8
675
676static
677TRANSPORTDEC_ERROR synchronization(
678        HANDLE_TRANSPORTDEC hTp,
679        INT                *pHeaderBits
680        )
681{
682  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
683  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
684
685  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
686  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
687  INT totalBits;
688  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
689  INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
690  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
691  INT ignoreBufferFullness = hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK);
692
693  /* Synch parameters */
694  INT syncLength;      /* Length of sync word in bits */
695  UINT syncWord;       /* Sync word to be found */
696  UINT syncMask;       /* Mask for sync word (for adding one bit, so comprising one bit less) */
697  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
698
699  totalBits = (INT)FDKgetValidBits(hBs);
700
701  if (totalBits <= 0) {
702    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
703    goto bail;
704  }
705
706  fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK);
707
708  /* Set transport specific sync parameters */
709  switch (hTp->transportFmt) {
710    case TT_MP4_ADTS:
711      syncWord = ADTS_SYNCWORD;
712      syncLength = ADTS_SYNCLENGTH;
713      break;
714    case TT_MP4_LOAS:
715      syncWord = 0x2B7;
716      syncLength = 11;
717      break;
718    default:
719      syncWord = 0;
720      syncLength = 0;
721      break;
722  }
723
724  syncMask = (1<<syncLength)-1;
725
726  do {
727    INT bitsAvail = 0;     /* Bits available in bitstream buffer    */
728    INT checkLengthBits;   /* Helper to check remaining bits and buffer boundaries */
729    UINT synch;            /* Current sync word read from bitstream */
730
731    headerBitsPrevious = headerBits;
732
733    bitsAvail = (INT)FDKgetValidBits(hBs);
734
735    if (hTp->numberOfRawDataBlocks == 0) {
736      /* search synchword */
737
738      FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0);
739
740      if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) {
741        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
742        headerBits = 0;
743      } else {
744
745        synch = FDKreadBits(hBs, syncLength);
746
747        if ( !(hTp->flags & TPDEC_SYNCOK) ) {
748          for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) {
749            if (synch == syncWord) {
750              break;
751            }
752            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP);
753          }
754        }
755        if (synch != syncWord) {
756          /* No correct syncword found. */
757          err = TRANSPORTDEC_SYNC_ERROR;
758        } else {
759          err = TRANSPORTDEC_OK;
760        }
761        headerBits = syncLength;
762      }
763    } else {
764      headerBits = 0;
765    }
766
767    /* Save previous raw data block data */
768    rawDataBlockLengthPrevious = rawDataBlockLength;
769    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
770
771    /* Parse transport header (raw data block granularity) */
772
773    if (err == TRANSPORTDEC_OK )
774    {
775      err = transportDec_readHeader(
776              hTp,
777              hBs,
778              syncLength,
779              ignoreBufferFullness,
780             &rawDataBlockLength,
781             &fTraverseMoreFrames,
782             &syncLayerFrameBits,
783             &fConfigFound,
784             &headerBits
785              );
786    }
787
788    bitsAvail -= headerBits;
789
790    checkLengthBits  = syncLayerFrameBits;
791
792    /* Check if the whole frame would fit the bitstream buffer */
793    if (err == TRANSPORTDEC_OK) {
794      if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
795        /* We assume that the size of the transport bit buffer has been
796           chosen to meet all system requirements, thus this condition
797           is considered a synchronisation error. */
798        err = TRANSPORTDEC_SYNC_ERROR;
799      } else {
800        if ( bitsAvail < checkLengthBits ) {
801          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
802        }
803      }
804    }
805
806    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
807      break;
808    }
809
810
811    if (err == TRANSPORTDEC_SYNC_ERROR) {
812      int bits;
813
814      /* Enforce re-sync of transport headers. */
815      hTp->numberOfRawDataBlocks = 0;
816
817      /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
818      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
819      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */
820      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
821      bitsAvail += headerBits - TPDEC_SYNCSKIP - bits;
822      headerBits = 0;
823    }
824
825    /* Frame traversal */
826    if ( fTraverseMoreFrames )
827    {
828      /* Save parser context for early config discovery "rewind all frames" */
829      if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY))
830      {
831        /* ignore buffer fullness if just traversing additional frames for ECD */
832        ignoreBufferFullness = 1;
833
834        /* Save context in order to return later */
835        if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) {
836          startPosFirstFrame = FDKgetValidBits(hBs);
837          numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
838          globalFramePosFirstFrame = hTp->globalFramePos;
839          rawDataBlockLengthFirstFrame = rawDataBlockLength;
840          headerBitsFirstFrame = headerBits;
841          errFirstFrame = err;
842          FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t));
843        }
844
845        /* Break when config was found or it is not possible anymore to find a config */
846        if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK))
847        {
848          /* In case of ECD and sync error, do not rewind anywhere. */
849          if (err == TRANSPORTDEC_SYNC_ERROR)
850          {
851            startPosFirstFrame = -1;
852            fConfigFound = 0;
853            numFramesTraversed = 0;
854          }
855          break;
856        }
857      }
858
859      if (err == TRANSPORTDEC_OK) {
860        FDKpushFor(hBs, rawDataBlockLength);
861        bitsAvail -= rawDataBlockLength;
862        numFramesTraversed++;
863        /* Ignore error here itentionally. */
864        transportDec_AdjustEndOfAccessUnit(hTp);
865      }
866    }
867  } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
868
869  /* Restore context in case of ECD frame traversal */
870  if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) {
871    FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
872    FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
873    hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
874    hTp->globalFramePos = globalFramePosFirstFrame;
875    rawDataBlockLength = rawDataBlockLengthFirstFrame;
876    headerBits = headerBitsFirstFrame;
877    err = errFirstFrame;
878    numFramesTraversed = 0;
879  }
880
881  /* Additional burst data mode buffer fullness check. */
882  if ( !(hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) {
883    err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits);
884    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
885      hTp->holdOffFrames++;
886    }
887  }
888
889  /* Rewind for retry because of not enough bits */
890  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
891    FDKpushBack(hBs, headerBits);
892    headerBits = 0;
893  }
894  else {
895    /* reset hold off frame counter */
896    hTp->holdOffFrames = 0;
897  }
898
899  /* Return to last good frame in case of frame traversal but not ECD. */
900  if (numFramesTraversed > 0) {
901    FDKpushBack(hBs, rawDataBlockLengthPrevious);
902    if (err != TRANSPORTDEC_OK) {
903      hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
904      headerBits = headerBitsPrevious;
905    }
906    err = TRANSPORTDEC_OK;
907  }
908
909bail:
910  hTp->auLength[0] = rawDataBlockLength;
911
912  /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, were the bit buffer is already full,
913     or no new burst packet fits. Recover by advancing the bit buffer. */
914  if ( (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&  (FDKgetValidBits(hBs) >= ((TRANSPORTDEC_INBUF_SIZE*8 - ((hTp->avgBitRate*hTp->burstPeriod)/1000)) - 7)) )
915  {
916    FDKpushFor(hBs, TPDEC_SYNCSKIP);
917    err = TRANSPORTDEC_SYNC_ERROR;
918  }
919
920  if (err == TRANSPORTDEC_OK) {
921    hTp->flags |= TPDEC_SYNCOK;
922  }
923
924  if (fConfigFound) {
925    hTp->flags |= TPDEC_CONFIG_FOUND;
926  }
927
928  if (pHeaderBits != NULL) {
929    *pHeaderBits = headerBits;
930  }
931
932  if (err == TRANSPORTDEC_SYNC_ERROR) {
933    hTp->flags &= ~TPDEC_SYNCOK;
934  }
935
936  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
937
938  return err;
939}
940
941/**
942 * \brief Synchronize to stream and estimate the amount of missing access units due
943 *        to a current synchronization error in case of constant average bit rate.
944 */
945static
946TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT layer )
947{
948
949  TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
950  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
951  INT nAU = -1;
952  INT headerBits;
953  INT bitDistance, bfDelta;
954
955  /* Obtain distance to next synch word */
956  bitDistance = FDKgetValidBits(hBs);
957  error = synchronization(hTp, &headerBits);
958  bitDistance -= FDKgetValidBits(hBs);
959
960
961  FDK_ASSERT(bitDistance >= 0);
962
963  if (error == TRANSPORTDEC_SYNC_ERROR || (hTp->flags & TPDEC_LOST_FRAMES_PENDING))
964  {
965    /* Check if estimating lost access units is feasible. */
966    if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 && hTp->asc[0].m_samplingFrequency > 0)
967    {
968      if (error == TRANSPORTDEC_OK)
969      {
970        int aj;
971
972        aj = transportDec_GetBufferFullness(hTp);
973        if (aj > 0) {
974          bfDelta = aj;
975        } else {
976          bfDelta = 0;
977        }
978        /* sync was ok: last of a series of bad access units. */
979        hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
980        /* Add up bitDistance until end of the current frame. Later we substract
981           this frame from the grand total, since this current successfully synchronized
982           frame should not be skipped of course; but it must be accounted into the
983           bufferfulness math. */
984        bitDistance += hTp->auLength[0];
985      } else {
986        if ( !(hTp->flags & TPDEC_LOST_FRAMES_PENDING) ) {
987          /* sync not ok: one of many bad access units. */
988          hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
989          bfDelta = - (INT)hTp->lastValidBufferFullness;
990        } else {
991          bfDelta = 0;
992        }
993      }
994
995      {
996        int num, denom;
997
998        /* Obtain estimate of number of lost frames */
999        num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + hTp->remainder;
1000        denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
1001        if (num > 0) {
1002          nAU = num / denom;
1003          hTp->remainder = num % denom;
1004        } else {
1005          hTp->remainder = num;
1006        }
1007
1008        if (error == TRANSPORTDEC_OK)
1009        {
1010          /* Final adjustment of remainder, taken -1 into account because current
1011             frame should not be skipped, thus substract -1 or do nothing instead
1012             of +1-1 accordingly. */
1013          if ( (denom - hTp->remainder) >= hTp->remainder ) {
1014            nAU--;
1015          }
1016
1017          if (nAU < 0) {
1018            /* There was one frame too much concealed, so unfortunately we will have to skip one good frame. */
1019            transportDec_EndAccessUnit(hTp);
1020            error = synchronization(hTp, &headerBits);
1021            nAU = -1;
1022#ifdef DEBUG
1023            FDKprintf("ERROR: Bufferfullness accounting failed. remainder=%d, nAU=%d\n", hTp->remainder, nAU);
1024#endif
1025          }
1026          hTp->remainder = 0;
1027          /* Enforce last missed frames to be concealed. */
1028          if (nAU > 0) {
1029            FDKpushBack(hBs, headerBits);
1030          }
1031        }
1032      }
1033    }
1034  }
1035
1036  /* Be sure that lost frames are handled correctly. This is necessary due to some
1037     sync error sequences where later it turns out that there is not enough data, but
1038     the bits upto the sync word are discarded, thus causing a value of nAU > 0 */
1039  if (nAU > 0) {
1040    error = TRANSPORTDEC_SYNC_ERROR;
1041  }
1042
1043  hTp->missingAccessUnits = nAU;
1044
1045  return error;
1046}
1047
1048/* returns error code */
1049TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
1050{
1051  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1052  HANDLE_FDK_BITSTREAM hBs;
1053
1054  if (!hTp) {
1055    return TRANSPORTDEC_INVALID_PARAMETER;
1056  }
1057
1058  hBs = &hTp->bitStream[layer];
1059
1060  if ((INT)FDKgetValidBits(hBs) <= 0) {
1061    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1062  }
1063
1064  switch (hTp->transportFmt) {
1065
1066    case TT_MP4_ADIF:
1067      /* Read header if not already done */
1068      if (!(hTp->flags & TPDEC_CONFIG_FOUND))
1069      {
1070        CProgramConfig *pce;
1071
1072        AudioSpecificConfig_Init(&hTp->asc[0]);
1073        pce = &hTp->asc[0].m_progrConfigElement;
1074        err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
1075        if (err)
1076          goto bail;
1077
1078        /* Map adif header to ASC */
1079        hTp->asc[0].m_aot                    = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
1080        hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
1081        hTp->asc[0].m_samplingFrequency      = SamplingRateTable[pce->SamplingFrequencyIndex];
1082        hTp->asc[0].m_channelConfiguration   = 0;
1083        hTp->asc[0].m_samplesPerFrame        = 1024;
1084        hTp->avgBitRate                      = hTp->parser.adif.BitRate;
1085
1086        /* Call callback to decoder. */
1087        {
1088          int errC;
1089
1090          errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
1091          if (errC == 0) {
1092            hTp->flags |= TPDEC_CONFIG_FOUND;
1093          } else {
1094            err = TRANSPORTDEC_PARSE_ERROR;
1095            goto bail;
1096          }
1097        }
1098      }
1099      hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
1100      break;
1101
1102    case TT_MP4_RAW:
1103    case TT_DRM:
1104      /* One Access Unit was filled into buffer.
1105         So get the length out of the buffer. */
1106      hTp->auLength[layer] = FDKgetValidBits(hBs);
1107      hTp->flags |= TPDEC_SYNCOK;
1108      break;
1109
1110    case TT_MP4_LATM_MCP0:
1111    case TT_MP4_LATM_MCP1:
1112      {
1113        int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
1114        err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer], NULL, NULL, &fConfigFound, NULL);
1115        if (fConfigFound) {
1116          hTp->flags |= TPDEC_CONFIG_FOUND;
1117        }
1118      }
1119      break;
1120
1121    case TT_MP4_ADTS:
1122    case TT_MP4_LOAS:
1123      err = transportDec_readStream(hTp, layer);
1124      break;
1125
1126    default:
1127      err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
1128      break;
1129  }
1130
1131  if (err == TRANSPORTDEC_OK) {
1132    hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
1133  } else {
1134    hTp->accessUnitAnchor[layer] = 0;
1135  }
1136
1137bail:
1138  return err;
1139}
1140
1141INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
1142{
1143  INT bits;
1144
1145  if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
1146    bits = hTp->auLength[layer] - (hTp->accessUnitAnchor[layer] - FDKgetValidBits(&hTp->bitStream[layer]));
1147  } else {
1148    bits = FDKgetValidBits(&hTp->bitStream[layer]);
1149  }
1150
1151  return bits;
1152}
1153
1154INT transportDec_GetAuBitsTotal( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
1155{
1156  return hTp->auLength[layer];
1157}
1158
1159TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount ( INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp )
1160{
1161  *pNAccessUnits = hTp->missingAccessUnits;
1162
1163  return TRANSPORTDEC_OK;
1164}
1165
1166/* Inform the transportDec layer that reading of access unit has finished. */
1167TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp)
1168{
1169  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1170
1171
1172  err = transportDec_AdjustEndOfAccessUnit(hTp);
1173
1174  switch (hTp->transportFmt) {
1175    default:
1176      break;
1177  }
1178
1179  return err;
1180}
1181
1182TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp,
1183                                           const TPDEC_PARAM        param,
1184                                           const INT                value)
1185{
1186  TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1187
1188  switch (param) {
1189    case TPDEC_PARAM_MINIMIZE_DELAY:
1190      if (value) {
1191        hTp->flags |= TPDEC_MINIMIZE_DELAY;
1192      } else {
1193        hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
1194      }
1195      break;
1196    case TPDEC_PARAM_EARLY_CONFIG:
1197      if (value) {
1198        hTp->flags |= TPDEC_EARLY_CONFIG;
1199      } else {
1200        hTp->flags &= ~TPDEC_EARLY_CONFIG;
1201      }
1202      break;
1203    case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
1204      if (value) {
1205        hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
1206      } else {
1207        hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
1208      }
1209      break;
1210    case TPDEC_PARAM_SET_BITRATE:
1211      hTp->avgBitRate = value;
1212      break;
1213    case TPDEC_PARAM_BURST_PERIOD:
1214      hTp->burstPeriod = value;
1215      break;
1216    case TPDEC_PARAM_RESET:
1217      {
1218        int i;
1219
1220        for (i=0; i<(1*2); i++) {
1221          FDKresetBitbuffer(&hTp->bitStream[i]);
1222          hTp->auLength[i] = 0;
1223          hTp->accessUnitAnchor[i] = 0;
1224        }
1225        hTp->flags &= ~(TPDEC_SYNCOK|TPDEC_LOST_FRAMES_PENDING);
1226        if (hTp->transportFmt != TT_MP4_ADIF) {
1227          hTp->flags &= ~TPDEC_CONFIG_FOUND;
1228        }
1229        hTp->remainder = 0;
1230        hTp->avgBitRate = 0;
1231        hTp->missingAccessUnits = 0;
1232        hTp->numberOfRawDataBlocks = 0;
1233        hTp->globalFramePos = 0;
1234        hTp->holdOffFrames = 0;
1235      }
1236      break;
1237  }
1238
1239  return error;
1240}
1241
1242UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp)
1243{
1244  UINT nSubFrames = 0;
1245
1246  if (hTp == NULL)
1247    return 0;
1248
1249  if (hTp->transportFmt==TT_MP4_LATM_MCP1 || hTp->transportFmt==TT_MP4_LATM_MCP0 || hTp->transportFmt==TT_MP4_LOAS)
1250    nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
1251  else if (hTp->transportFmt==TT_MP4_ADTS)
1252    nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
1253
1254  return nSubFrames;
1255}
1256
1257void transportDec_Close(HANDLE_TRANSPORTDEC *phTp)
1258{
1259  if (phTp != NULL)
1260  {
1261    if (*phTp != NULL) {
1262      if ( ! TT_IS_PACKET((*phTp)->transportFmt) ) {
1263        FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
1264      }
1265      if (*phTp != NULL) {
1266        FreeRam_TransportDecoder(phTp);
1267      }
1268    }
1269  }
1270}
1271
1272TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
1273{
1274  int i;
1275
1276  if (info == NULL) {
1277    return TRANSPORTDEC_UNKOWN_ERROR;
1278  }
1279
1280  /* search for next free tab */
1281  for (i = 0; i < FDK_MODULE_LAST; i++) {
1282    if (info[i].module_id == FDK_NONE) break;
1283  }
1284  if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
1285  info += i;
1286
1287  info->module_id  = FDK_TPDEC;
1288#ifdef __ANDROID__
1289  info->build_date = "";
1290  info->build_time = "";
1291#else
1292  info->build_date = __DATE__;
1293  info->build_time = __TIME__;
1294#endif
1295  info->title      = TP_LIB_TITLE;
1296  info->version    = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
1297  LIB_VERSION_STRING(info);
1298  info->flags = 0
1299    | CAPF_ADIF
1300    | CAPF_ADTS
1301    | CAPF_LATM
1302    | CAPF_LOAS
1303    | CAPF_RAWPACKETS
1304    | CAPF_DRM
1305    ;
1306
1307  return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
1308}
1309
1310
1311int  transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits)
1312{
1313  switch (pTp->transportFmt) {
1314  case TT_MP4_ADTS:
1315    return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
1316  case TT_DRM:
1317    return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
1318  default:
1319    return 0;
1320  }
1321}
1322
1323void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg)
1324{
1325  switch (pTp->transportFmt) {
1326  case TT_MP4_ADTS:
1327    adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
1328    break;
1329  case TT_DRM:
1330    drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
1331    break;
1332  default:
1333    break;
1334  }
1335}
1336
1337TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)
1338{
1339  switch (pTp->transportFmt) {
1340  case TT_MP4_ADTS:
1341    if ( (pTp->parser.adts.bs.num_raw_blocks > 0) && (pTp->parser.adts.bs.protection_absent == 0) )
1342    {
1343      HANDLE_FDK_BITSTREAM hBs = &pTp->bitStream[0];
1344
1345      transportDec_AdjustEndOfAccessUnit(pTp);
1346    }
1347    return adtsRead_CrcCheck(&pTp->parser.adts);
1348  case TT_DRM:
1349    return drmRead_CrcCheck(&pTp->parser.drm);
1350    break;
1351  default:
1352    return TRANSPORTDEC_OK;
1353  }
1354}
1355