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