Imported Debian version 0.1.3.1
[deb_fdk-aac.git] / libMpegTPDec / src / tpdec_lib.cpp
1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software 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
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)
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 ( 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
217 TRANSPORTDEC_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
265 int 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
275 int 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
285 int 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
295 TRANSPORTDEC_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
336 HANDLE_FDK_BITSTREAM transportDec_GetBitstream( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
337 {
338 return &hTp->bitStream[layer];
339 }
340
341 TRANSPORT_TYPE transportDec_GetFormat( const HANDLE_TRANSPORTDEC hTp )
342 {
343 return hTp->transportFmt;
344 }
345
346 INT 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 */
375 static
376 TRANSPORTDEC_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 */
454 static
455 TRANSPORTDEC_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
510 static 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
632 bail:
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
659 static
660 TRANSPORTDEC_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
892 bail:
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 */
928 static
929 TRANSPORTDEC_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 */
1032 TRANSPORTDEC_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
1120 bail:
1121 return err;
1122 }
1123
1124 INT 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
1137 INT transportDec_GetAuBitsTotal( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
1138 {
1139 return hTp->auLength[layer];
1140 }
1141
1142 TRANSPORTDEC_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. */
1150 TRANSPORTDEC_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
1165 TRANSPORTDEC_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
1225 UINT 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
1240 void 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
1255 TRANSPORTDEC_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
1288 int 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
1298 void 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
1309 TRANSPORTDEC_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 }