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