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