1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2022 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 [email protected]
93 ----------------------------------------------------------------------------- */
94
95 /******************* MPEG transport format decoder library *********************
96
97 Author(s): Manuel Jander
98
99 Description: MPEG Transport decoder
100
101 *******************************************************************************/
102
103 #include "tpdec_lib.h"
104
105 /* library version */
106 #include "tp_version.h"
107
108 #include "tp_data.h"
109
110 #include "tpdec_adts.h"
111
112 #include "tpdec_adif.h"
113
114 #include "tpdec_latm.h"
115
116 #include "tpdec_drm.h"
117
118 #include "FDK_crc.h"
119
120 #define MODULE_NAME "transportDec"
121
122 typedef union {
123 STRUCT_ADTS adts;
124
125 CAdifHeader adif;
126
127 CLatmDemux latm;
128
129 STRUCT_DRM drm;
130
131 } transportdec_parser_t;
132
133 #define MHAS_CONFIG_PRESENT 0x001
134 #define MHAS_UI_PRESENT 0x002
135
136 struct TRANSPORTDEC {
137 TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */
138
139 CSTpCallBacks callbacks; /*!< Struct holding callback and its data */
140
141 FDK_BITSTREAM bitStream[1]; /* Bitstream reader */
142 UCHAR *bsBuffer; /* Internal bitstreamd data buffer */
143
144 transportdec_parser_t parser; /* Format specific parser structs. */
145
146 CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last
147 config found. One additional
148 CSAudioSpecificConfig is used
149 temporarily for parsing. */
150 CCtrlCFGChange ctrlCFGChange[(1 * 1)]; /* Controls config change */
151
152 UINT globalFramePos; /* Global transport frame reference bit position. */
153 UINT accessUnitAnchor[1]; /* Current access unit start bit position. */
154 INT auLength[1]; /* Length of current access unit. */
155 INT numberOfRawDataBlocks; /* Current number of raw data blocks contained
156 remaining from the current transport frame. */
157 UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
158 UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame
159 loss estimation */
160 INT remainder; /* Reminder in division during lost access unit estimation. */
161 INT missingAccessUnits; /* Estimated missing access units. */
162 UINT burstPeriod; /* Data burst period in mili seconds. */
163 UINT holdOffFrames; /* Amount of frames that were already hold off due to
164 buffer fullness condition not being met. */
165 UINT flags; /* Flags. */
166 INT targetLayout; /* CICP target layout. */
167 UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and
168 length (bytes) of loudnessInfoSet within
169 rsv603daConfig. */
170 };
171
172 /* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
173 #define TPDEC_SYNCOK 1
174 #define TPDEC_MINIMIZE_DELAY 2
175 #define TPDEC_IGNORE_BUFFERFULLNESS 4
176 #define TPDEC_EARLY_CONFIG 8
177 #define TPDEC_LOST_FRAMES_PENDING 16
178 #define TPDEC_CONFIG_FOUND 32
179 #define TPDEC_USE_ELEM_SKIPPING 64
180
181 /* force config/content change */
182 #define TPDEC_FORCE_CONFIG_CHANGE 1
183 #define TPDEC_FORCE_CONTENT_CHANGE 2
184
185 /* skip packet */
186 #define TPDEC_SKIP_PACKET 1
187
188 C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1)
189 C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4))
190
transportDec_Open(const TRANSPORT_TYPE transportFmt,const UINT flags,const UINT nrOfLayers)191 HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt,
192 const UINT flags, const UINT nrOfLayers) {
193 HANDLE_TRANSPORTDEC hInput;
194
195 hInput = GetRam_TransportDecoder(0);
196 if (hInput == NULL) {
197 return NULL;
198 }
199
200 /* Init transportDec struct. */
201 hInput->transportFmt = transportFmt;
202
203 switch (transportFmt) {
204 case TT_MP4_ADIF:
205 break;
206
207 case TT_MP4_ADTS:
208 if (flags & TP_FLAG_MPEG4)
209 hInput->parser.adts.decoderCanDoMpeg4 = 1;
210 else
211 hInput->parser.adts.decoderCanDoMpeg4 = 0;
212 adtsRead_CrcInit(&hInput->parser.adts);
213 hInput->parser.adts.BufferFullnesStartFlag = 1;
214 hInput->numberOfRawDataBlocks = 0;
215 break;
216
217 case TT_DRM:
218 drmRead_CrcInit(&hInput->parser.drm);
219 break;
220
221 case TT_MP4_LATM_MCP0:
222 case TT_MP4_LATM_MCP1:
223 hInput->parser.latm.usacExplicitCfgChanged = 0;
224 hInput->parser.latm.applyAsc = 1;
225 break;
226 case TT_MP4_LOAS:
227 hInput->parser.latm.usacExplicitCfgChanged = 0;
228 hInput->parser.latm.applyAsc = 1;
229 break;
230 case TT_MP4_RAW:
231 break;
232
233 default:
234 FreeRam_TransportDecoder(&hInput);
235 hInput = NULL;
236 break;
237 }
238
239 if (hInput != NULL) {
240 /* Create bitstream */
241 {
242 hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
243 if (hInput->bsBuffer == NULL) {
244 transportDec_Close(&hInput);
245 return NULL;
246 }
247 if (nrOfLayers > 1) {
248 transportDec_Close(&hInput);
249 return NULL;
250 }
251 for (UINT i = 0; i < nrOfLayers; i++) {
252 FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
253 BS_READER);
254 }
255 }
256 hInput->burstPeriod = 0;
257 }
258
259 return hInput;
260 }
261
transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,UCHAR * conf,const UINT length,UINT layer)262 TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
263 UCHAR *conf, const UINT length,
264 UINT layer) {
265 int i;
266
267 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
268
269 FDK_BITSTREAM bs;
270 HANDLE_FDK_BITSTREAM hBs = &bs;
271
272 int fConfigFound = 0;
273
274 UCHAR configChanged = 0;
275 UCHAR configMode = AC_CM_DET_CFG_CHANGE;
276
277 UCHAR tmpConf[1024] = {0};
278 if (length > 1024) {
279 return TRANSPORTDEC_UNSUPPORTED_FORMAT;
280 }
281 FDKmemcpy(tmpConf, conf, length);
282 FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);
283
284 for (i = 0; i < 2; i++) {
285 if (i > 0) {
286 FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs));
287 configMode = AC_CM_ALLOC_MEM;
288 }
289
290 /* config transport decoder */
291 switch (hTp->transportFmt) {
292 case TT_MP4_LATM_MCP0:
293 case TT_MP4_LATM_MCP1:
294 case TT_MP4_LOAS: {
295 if (layer != 0) {
296 return TRANSPORTDEC_INVALID_PARAMETER;
297 }
298 CLatmDemux *pLatmDemux = &hTp->parser.latm;
299 err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks,
300 hTp->asc, &fConfigFound,
301 configMode, configChanged);
302 if (err != TRANSPORTDEC_OK) {
303 return err;
304 }
305 } break;
306 default:
307 fConfigFound = 1;
308 err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
309 &hTp->callbacks, configMode,
310 configChanged, AOT_NULL_OBJECT);
311 if (err == TRANSPORTDEC_OK) {
312 int errC;
313
314 hTp->asc[layer] = hTp->asc[(1 * 1)];
315 errC = hTp->callbacks.cbUpdateConfig(
316 hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
317 hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
318 if (errC != 0) {
319 err = TRANSPORTDEC_PARSE_ERROR;
320 }
321 }
322 break;
323 case TT_DRM:
324 fConfigFound = 1;
325 err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks,
326 configMode, configChanged);
327 if (err == TRANSPORTDEC_OK) {
328 int errC;
329
330 errC = hTp->callbacks.cbUpdateConfig(
331 hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
332 hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
333 if (errC != 0) {
334 err = TRANSPORTDEC_PARSE_ERROR;
335 }
336 }
337 break;
338 }
339
340 if (err == TRANSPORTDEC_OK) {
341 if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
342 hTp->asc[layer].SbrConfigChanged ||
343 hTp->asc[layer].SacConfigChanged)) {
344 int errC;
345
346 configChanged = 1;
347 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
348 &hTp->asc[layer]);
349 if (errC != 0) {
350 err = TRANSPORTDEC_PARSE_ERROR;
351 }
352 }
353 }
354
355 /* if an error is detected terminate config parsing to avoid that an invalid
356 * config is accepted in the second pass */
357 if (err != TRANSPORTDEC_OK) {
358 break;
359 }
360 }
361
362 if (err == TRANSPORTDEC_OK && fConfigFound) {
363 hTp->flags |= TPDEC_CONFIG_FOUND;
364 }
365
366 return err;
367 }
368
transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,UCHAR * newConfig,const UINT newConfigLength,const UCHAR buildUpStatus,UCHAR * configChanged,UINT layer,UCHAR * implicitExplicitCfgDiff)369 TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
370 UCHAR *newConfig,
371 const UINT newConfigLength,
372 const UCHAR buildUpStatus,
373 UCHAR *configChanged, UINT layer,
374 UCHAR *implicitExplicitCfgDiff) {
375 int errC;
376 FDK_BITSTREAM bs;
377 HANDLE_FDK_BITSTREAM hBs = &bs;
378 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
379 int fConfigFound = 0;
380 UCHAR configMode = AC_CM_ALLOC_MEM;
381 *implicitExplicitCfgDiff = 0;
382
383 FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
384
385 FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
386 BS_READER);
387
388 if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
389 (hTp->ctrlCFGChange[layer].buildUpStatus !=
390 TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
391 if (hTp->asc->m_aot == AOT_USAC) {
392 if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
393 newConfigLength) {
394 if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
395 newConfigLength)) {
396 if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
397 LOAS/LATM parser */
398 hTp->parser.latm.usacExplicitCfgChanged = 0;
399 hTp->ctrlCFGChange[layer].flushCnt = 0;
400 hTp->ctrlCFGChange[layer].flushStatus =
401 TPDEC_USAC_DASH_IPF_FLUSH_ON;
402 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
403 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
404 } else {
405 *configChanged = 0;
406 return err;
407 }
408 } else {
409 *implicitExplicitCfgDiff = 1;
410 }
411 } else {
412 *implicitExplicitCfgDiff = 1;
413 }
414 /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
415 * config shall be identical. */
416 if (*implicitExplicitCfgDiff) {
417 switch (hTp->transportFmt) {
418 case TT_MP4_LATM_MCP0:
419 case TT_MP4_LATM_MCP1:
420 case TT_MP4_LOAS:
421 /* reset decoder to initial state to achieve definite behavior after
422 * error in config */
423 hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
424 &hTp->asc[layer]);
425 hTp->parser.latm.usacExplicitCfgChanged = 0;
426 hTp->parser.latm.applyAsc = 1;
427 err = TRANSPORTDEC_PARSE_ERROR;
428 goto bail;
429 default:
430 break;
431 }
432 }
433 }
434 }
435
436 {
437 if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
438 (hTp->ctrlCFGChange[layer].buildUpStatus !=
439 TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
440 hTp->ctrlCFGChange[layer].flushCnt = 0;
441 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
442 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
443 if (hTp->asc->m_aot == AOT_USAC) {
444 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
445 }
446 }
447
448 if ((hTp->ctrlCFGChange[layer].flushStatus ==
449 TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
450 (hTp->ctrlCFGChange[layer].flushStatus ==
451 TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
452 SCHAR counter = 0;
453 if (hTp->asc->m_aot == AOT_USAC) {
454 counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
455 }
456 if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
457 hTp->ctrlCFGChange[layer].flushCnt = 0;
458 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
459 hTp->ctrlCFGChange[layer].forceCfgChange = 0;
460 if (hTp->asc->m_aot == AOT_USAC) {
461 hTp->ctrlCFGChange[layer].buildUpCnt =
462 TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
463 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
464 }
465 }
466
467 /* Activate flush mode. After that continue with build up mode in core */
468 if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
469 &hTp->ctrlCFGChange[layer]) != 0) {
470 err = TRANSPORTDEC_PARSE_ERROR;
471 }
472
473 if ((hTp->ctrlCFGChange[layer].flushStatus ==
474 TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
475 (hTp->ctrlCFGChange[layer].flushStatus ==
476 TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
477 hTp->ctrlCFGChange[layer].flushCnt++;
478 return err;
479 }
480 }
481
482 if (hTp->asc->m_aot == AOT_USAC) {
483 fConfigFound = 1;
484
485 if (err == TRANSPORTDEC_OK) {
486 *configChanged = 0;
487 configMode = AC_CM_DET_CFG_CHANGE;
488
489 for (int i = 0; i < 2; i++) {
490 if (i > 0) {
491 FDKpushBack(hBs,
492 (INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
493 configMode = AC_CM_ALLOC_MEM;
494 }
495 /* config transport decoder */
496 err = AudioSpecificConfig_Parse(
497 &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
498 *configChanged, hTp->asc[layer].m_aot);
499 if (err == TRANSPORTDEC_OK) {
500 hTp->asc[layer] = hTp->asc[(1 * 1)];
501 errC = hTp->callbacks.cbUpdateConfig(
502 hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
503 hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
504 if (errC != 0) {
505 err = TRANSPORTDEC_PARSE_ERROR;
506 }
507 }
508
509 if (err == TRANSPORTDEC_OK) {
510 if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
511 hTp->asc[layer].SbrConfigChanged ||
512 hTp->asc[layer].SacConfigChanged)) {
513 *configChanged = 1;
514 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
515 &hTp->asc[layer]);
516 if (errC != 0) {
517 err = TRANSPORTDEC_PARSE_ERROR;
518 }
519 }
520 }
521
522 /* if an error is detected terminate config parsing to avoid that an
523 * invalid config is accepted in the second pass */
524 if (err != TRANSPORTDEC_OK) {
525 break;
526 }
527 }
528 }
529 }
530
531 bail:
532 /* save new config */
533 if (err == TRANSPORTDEC_OK) {
534 if (hTp->asc->m_aot == AOT_USAC) {
535 hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
536 FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
537 newConfigLength);
538 /* in case of USAC reset transportDecoder variables here because
539 * otherwise without IPF they are not reset */
540 hTp->ctrlCFGChange[layer].flushCnt = 0;
541 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
542 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
543 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
544 }
545 } else {
546 hTp->numberOfRawDataBlocks = 0;
547
548 /* If parsing error while config found, clear ctrlCFGChange-struct */
549 hTp->ctrlCFGChange[layer].flushCnt = 0;
550 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
551 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
552 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
553 hTp->ctrlCFGChange[layer].cfgChanged = 0;
554 hTp->ctrlCFGChange[layer].contentChanged = 0;
555 hTp->ctrlCFGChange[layer].forceCfgChange = 0;
556
557 hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
558 &hTp->ctrlCFGChange[layer]);
559 }
560 }
561
562 if (err == TRANSPORTDEC_OK && fConfigFound) {
563 hTp->flags |= TPDEC_CONFIG_FOUND;
564 }
565
566 return err;
567 }
568
transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUpdateConfig_t cbUpdateConfig,void * user_data)569 int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
570 const cbUpdateConfig_t cbUpdateConfig,
571 void *user_data) {
572 if (hTpDec == NULL) {
573 return -1;
574 }
575 hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
576 hTpDec->callbacks.cbUpdateConfigData = user_data;
577 return 0;
578 }
579
transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,const cbFreeMem_t cbFreeMem,void * user_data)580 int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
581 const cbFreeMem_t cbFreeMem,
582 void *user_data) {
583 if (hTpDec == NULL) {
584 return -1;
585 }
586 hTpDec->callbacks.cbFreeMem = cbFreeMem;
587 hTpDec->callbacks.cbFreeMemData = user_data;
588 return 0;
589 }
590
transportDec_RegisterCtrlCFGChangeCallback(HANDLE_TRANSPORTDEC hTpDec,const cbCtrlCFGChange_t cbCtrlCFGChange,void * user_data)591 int transportDec_RegisterCtrlCFGChangeCallback(
592 HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
593 void *user_data) {
594 if (hTpDec == NULL) {
595 return -1;
596 }
597 hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
598 hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
599 return 0;
600 }
601
transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,const cbSsc_t cbSsc,void * user_data)602 int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
603 const cbSsc_t cbSsc, void *user_data) {
604 if (hTpDec == NULL) {
605 return -1;
606 }
607 hTpDec->callbacks.cbSsc = cbSsc;
608 hTpDec->callbacks.cbSscData = user_data;
609 return 0;
610 }
611
transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,const cbSbr_t cbSbr,void * user_data)612 int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
613 const cbSbr_t cbSbr, void *user_data) {
614 if (hTpDec == NULL) {
615 return -1;
616 }
617 hTpDec->callbacks.cbSbr = cbSbr;
618 hTpDec->callbacks.cbSbrData = user_data;
619 return 0;
620 }
621
transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUsac_t cbUsac,void * user_data)622 int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
623 const cbUsac_t cbUsac, void *user_data) {
624 if (hTpDec == NULL) {
625 return -1;
626 }
627 hTpDec->callbacks.cbUsac = cbUsac;
628 hTpDec->callbacks.cbUsacData = user_data;
629 return 0;
630 }
631
transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUniDrc_t cbUniDrc,void * user_data,UINT * pLoudnessInfoSetPosition)632 int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
633 const cbUniDrc_t cbUniDrc,
634 void *user_data,
635 UINT *pLoudnessInfoSetPosition) {
636 if (hTpDec == NULL) {
637 return -1;
638 }
639
640 hTpDec->callbacks.cbUniDrc = cbUniDrc;
641 hTpDec->callbacks.cbUniDrcData = user_data;
642
643 hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
644 return 0;
645 }
646
transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,UCHAR * pBuffer,const UINT bufferSize,UINT * pBytesValid,const INT layer)647 TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
648 UCHAR *pBuffer, const UINT bufferSize,
649 UINT *pBytesValid, const INT layer) {
650 HANDLE_FDK_BITSTREAM hBs;
651
652 if ((hTp == NULL) || (layer >= 1)) {
653 return TRANSPORTDEC_INVALID_PARAMETER;
654 }
655
656 /* set bitbuffer shortcut */
657 hBs = &hTp->bitStream[layer];
658
659 if (TT_IS_PACKET(hTp->transportFmt)) {
660 if (hTp->numberOfRawDataBlocks == 0) {
661 FDKresetBitbuffer(hBs);
662 FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
663 if (*pBytesValid != 0) {
664 return TRANSPORTDEC_TOO_MANY_BITS;
665 }
666 }
667 } else {
668 /* ... else feed bitbuffer with new stream data (append). */
669
670 if (*pBytesValid == 0) {
671 /* nothing to do */
672 return TRANSPORTDEC_OK;
673 } else {
674 const int bytesValid = *pBytesValid;
675 FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
676
677 if (hTp->numberOfRawDataBlocks > 0) {
678 hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
679 hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
680 }
681 }
682 }
683
684 return TRANSPORTDEC_OK;
685 }
686
transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,const UINT layer)687 HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
688 const UINT layer) {
689 return &hTp->bitStream[layer];
690 }
691
transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp)692 TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
693 return hTp->transportFmt;
694 }
695
transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp)696 INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
697 INT bufferFullness = -1;
698
699 switch (hTp->transportFmt) {
700 case TT_MP4_ADTS:
701 if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
702 bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
703 hTp->parser.adts.bs.adts_fullness * 32 *
704 getNumberOfEffectiveChannels(
705 hTp->parser.adts.bs.channel_config);
706 }
707 break;
708 case TT_MP4_LOAS:
709 case TT_MP4_LATM_MCP0:
710 case TT_MP4_LATM_MCP1:
711 if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
712 bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
713 }
714 break;
715 default:
716 break;
717 }
718
719 return bufferFullness;
720 }
721
722 /**
723 * \brief adjust bit stream position and the end of an access unit.
724 * \param hTp transport decoder handle.
725 * \return error code.
726 */
transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)727 static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
728 HANDLE_TRANSPORTDEC hTp) {
729 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
730 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
731
732 switch (hTp->transportFmt) {
733 case TT_MP4_ADIF:
734 /* Do byte align at the end of raw_data_block() because UsacFrame() is not
735 * byte aligned. */
736 FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
737 break;
738 case TT_MP4_LOAS:
739 case TT_MP4_LATM_MCP0:
740 case TT_MP4_LATM_MCP1:
741 if (hTp->numberOfRawDataBlocks == 0) {
742 /* Do byte align at the end of AudioMuxElement. */
743 FDKbyteAlign(hBs, hTp->globalFramePos);
744
745 /* Check global frame length */
746 if (hTp->transportFmt == TT_MP4_LOAS &&
747 hTp->parser.latm.m_audioMuxLengthBytes > 0) {
748 int loasOffset;
749
750 loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
751 (INT)FDKgetValidBits(hBs)) -
752 (INT)hTp->globalFramePos;
753 if (loasOffset != 0) {
754 FDKpushBiDirectional(hBs, loasOffset);
755 /* For ELD and other payloads there is an unknown amount of padding,
756 so ignore unread bits, but throw an error only if too many bits
757 where read. */
758 if (loasOffset < 0) {
759 err = TRANSPORTDEC_PARSE_ERROR;
760 }
761 }
762 }
763 }
764 break;
765
766 case TT_MP4_ADTS:
767 if (hTp->parser.adts.bs.protection_absent == 0) {
768 int offset;
769
770 /* Calculate offset to end of AU */
771 offset = hTp->parser.adts
772 .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
773 hTp->numberOfRawDataBlocks]
774 << 3;
775 /* CAUTION: The PCE (if available) is declared to be a part of the
776 * header! */
777 offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
778 16 + hTp->parser.adts.bs.num_pce_bits;
779 FDKpushBiDirectional(hBs, offset);
780 }
781 if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
782 hTp->parser.adts.bs.protection_absent == 0) {
783 /* Note this CRC read currently happens twice because of
784 * transportDec_CrcCheck() */
785 hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
786 }
787 if (hTp->numberOfRawDataBlocks == 0) {
788 /* Check global frame length */
789 if (hTp->parser.adts.bs.protection_absent == 0) {
790 int offset;
791
792 offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
793 (INT)FDKgetValidBits(hBs)) -
794 (INT)hTp->globalFramePos;
795 if (offset != 0) {
796 FDKpushBiDirectional(hBs, offset);
797 }
798 }
799 }
800 break;
801
802 default:
803 break;
804 }
805
806 return err;
807 }
808
809 /**
810 * \brief Determine additional buffer fullness contraint due to burst data
811 * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
812 * precondition.
813 * \param hTp transport decoder handle.
814 * \param bufferFullness the buffer fullness value of the first frame to be
815 * decoded.
816 * \param bitsAvail the amount of available bits at the end of the first frame
817 * to be decoded.
818 * \return error code
819 */
additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,INT bufferFullness,INT bitsAvail)820 static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
821 INT bufferFullness,
822 INT bitsAvail) {
823 INT checkLengthBits, avgBitsPerFrame;
824 INT maxAU; /* maximum number of frames per Master Frame */
825 INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
826 INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
827
828 if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
829 return TRANSPORTDEC_OK;
830 }
831 if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
832 return TRANSPORTDEC_NOT_ENOUGH_BITS;
833 }
834
835 /* One Master Frame is sent every hTp->burstPeriod ms */
836 maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
837 maxAU = maxAU / (samplesPerFrame * 1000);
838 /* Subtract number of frames which were already held off. */
839 maxAU -= hTp->holdOffFrames;
840
841 avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
842 avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
843
844 /* Consider worst case of bufferFullness quantization. */
845 switch (hTp->transportFmt) {
846 case TT_MP4_ADIF:
847 case TT_MP4_ADTS:
848 case TT_MP4_LOAS:
849 case TT_MP4_LATM_MCP0:
850 case TT_MP4_LATM_MCP1:
851 bufferFullness += 31;
852 break;
853 default: /* added to avoid compiler warning */
854 break; /* added to avoid compiler warning */
855 }
856
857 checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;
858
859 /* Check if buffer is big enough to fullfill buffer fullness condition */
860 if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
861 return TRANSPORTDEC_SYNC_ERROR;
862 }
863
864 if (bitsAvail < checkLengthBits) {
865 return TRANSPORTDEC_NOT_ENOUGH_BITS;
866 } else {
867 return TRANSPORTDEC_OK;
868 }
869 }
870
transportDec_readHeader(HANDLE_TRANSPORTDEC hTp,HANDLE_FDK_BITSTREAM hBs,int syncLength,int ignoreBufferFullness,int * pRawDataBlockLength,int * pfTraverseMoreFrames,int * pSyncLayerFrameBits,int * pfConfigFound,int * pHeaderBits)871 static TRANSPORTDEC_ERROR transportDec_readHeader(
872 HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
873 int ignoreBufferFullness, int *pRawDataBlockLength,
874 int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
875 int *pHeaderBits) {
876 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
877 int rawDataBlockLength = *pRawDataBlockLength;
878 int fTraverseMoreFrames =
879 (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
880 int syncLayerFrameBits =
881 (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
882 int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
883 int startPos;
884
885 startPos = (INT)FDKgetValidBits(hBs);
886
887 switch (hTp->transportFmt) {
888 case TT_MP4_ADTS:
889 if (hTp->numberOfRawDataBlocks <= 0) {
890 int i, errC;
891
892 hTp->globalFramePos = FDKgetValidBits(hBs);
893
894 UCHAR configChanged = 0;
895 UCHAR configMode = AC_CM_DET_CFG_CHANGE;
896
897 for (i = 0; i < 2; i++) {
898 if (i > 0) {
899 FDKpushBack(hBs,
900 (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
901 configMode = AC_CM_ALLOC_MEM;
902 }
903
904 /* Parse ADTS header */
905 err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
906 ignoreBufferFullness);
907 if (err != TRANSPORTDEC_OK) {
908 if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
909 err = TRANSPORTDEC_SYNC_ERROR;
910 }
911 } else {
912 errC = hTp->callbacks.cbUpdateConfig(
913 hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
914 &configChanged);
915 if (errC != 0) {
916 if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
917 err = TRANSPORTDEC_NEED_TO_RESTART;
918 goto bail;
919 } else {
920 err = TRANSPORTDEC_SYNC_ERROR;
921 }
922 } else {
923 fConfigFound = 1;
924 hTp->numberOfRawDataBlocks =
925 hTp->parser.adts.bs.num_raw_blocks + 1;
926 }
927 }
928
929 if (err == TRANSPORTDEC_OK) {
930 if ((i == 0) && configChanged) {
931 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
932 &hTp->asc[0]);
933 if (errC != 0) {
934 err = TRANSPORTDEC_PARSE_ERROR;
935 }
936 }
937 }
938 /* if an error is detected terminate config parsing to avoid that an
939 * invalid config is accepted in the second pass */
940 if (err != TRANSPORTDEC_OK) {
941 break;
942 }
943 }
944 } else {
945 /* Reset CRC because the next bits are the beginning of a
946 * raw_data_block() */
947 FDKcrcReset(&hTp->parser.adts.crcInfo);
948 hTp->parser.adts.bs.num_pce_bits = 0;
949 }
950 if (err == TRANSPORTDEC_OK) {
951 hTp->numberOfRawDataBlocks--;
952 rawDataBlockLength = adtsRead_GetRawDataBlockLength(
953 &hTp->parser.adts,
954 (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
955 if (rawDataBlockLength <= 0) {
956 /* No further frame traversal possible. */
957 fTraverseMoreFrames = 0;
958 }
959 syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
960 (startPos - (INT)FDKgetValidBits(hBs)) -
961 syncLength;
962 if (syncLayerFrameBits <= 0) {
963 err = TRANSPORTDEC_SYNC_ERROR;
964 }
965 } else {
966 hTp->numberOfRawDataBlocks = 0;
967 }
968 break;
969 case TT_MP4_LOAS:
970 if (hTp->numberOfRawDataBlocks <= 0) {
971 syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
972 hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
973 syncLayerFrameBits <<= 3;
974 }
975 FDK_FALLTHROUGH;
976 case TT_MP4_LATM_MCP1:
977 case TT_MP4_LATM_MCP0:
978 if (hTp->numberOfRawDataBlocks <= 0) {
979 hTp->globalFramePos = FDKgetValidBits(hBs);
980
981 err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
982 &hTp->callbacks, hTp->asc, &fConfigFound,
983 ignoreBufferFullness);
984
985 if (err != TRANSPORTDEC_OK) {
986 if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
987 !TPDEC_IS_FATAL_ERROR(err)) {
988 err = TRANSPORTDEC_SYNC_ERROR;
989 }
990 } else {
991 hTp->numberOfRawDataBlocks =
992 CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
993 if (hTp->transportFmt == TT_MP4_LOAS) {
994 syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
995 if (syncLayerFrameBits <= 0) {
996 err = TRANSPORTDEC_SYNC_ERROR;
997 }
998 }
999 }
1000 } else {
1001 err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
1002 if (err != TRANSPORTDEC_OK) {
1003 err = TRANSPORTDEC_SYNC_ERROR;
1004 }
1005 }
1006 if (err == TRANSPORTDEC_OK) {
1007 int layer;
1008 rawDataBlockLength = 0;
1009 for (layer = 0;
1010 layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
1011 layer += 1) {
1012 rawDataBlockLength +=
1013 CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
1014 }
1015 hTp->numberOfRawDataBlocks--;
1016 } else {
1017 hTp->numberOfRawDataBlocks = 0;
1018 }
1019 break;
1020 default: { syncLayerFrameBits = 0; } break;
1021 }
1022
1023 bail:
1024
1025 *pRawDataBlockLength = rawDataBlockLength;
1026
1027 if (pHeaderBits != NULL) {
1028 *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
1029 }
1030
1031 for (int i = 0; i < (1 * 1); i++) {
1032 /* If parsing error while config found, clear ctrlCFGChange-struct */
1033 if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
1034 hTp->numberOfRawDataBlocks = 0;
1035 hTp->ctrlCFGChange[i].flushCnt = 0;
1036 hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
1037 hTp->ctrlCFGChange[i].buildUpCnt = 0;
1038 hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
1039 hTp->ctrlCFGChange[i].cfgChanged = 0;
1040 hTp->ctrlCFGChange[i].contentChanged = 0;
1041 hTp->ctrlCFGChange[i].forceCfgChange = 0;
1042
1043 hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
1044 &hTp->ctrlCFGChange[i]);
1045 }
1046 }
1047
1048 if (pfConfigFound != NULL) {
1049 *pfConfigFound = fConfigFound;
1050 }
1051
1052 if (pfTraverseMoreFrames != NULL) {
1053 *pfTraverseMoreFrames = fTraverseMoreFrames;
1054 }
1055 if (pSyncLayerFrameBits != NULL) {
1056 *pSyncLayerFrameBits = syncLayerFrameBits;
1057 }
1058
1059 return err;
1060 }
1061
1062 /* How many bits to advance for synchronization search. */
1063 #define TPDEC_SYNCSKIP 8
1064
synchronization(HANDLE_TRANSPORTDEC hTp,INT * pHeaderBits)1065 static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
1066 INT *pHeaderBits) {
1067 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
1068 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1069
1070 INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
1071 INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
1072 INT totalBits;
1073 INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
1074 INT numFramesTraversed = 0, fTraverseMoreFrames,
1075 fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
1076 INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
1077 globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
1078 INT ignoreBufferFullness =
1079 hTp->flags &
1080 (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
1081 UINT endTpFrameBitsPrevious = 0;
1082
1083 /* Synch parameters */
1084 INT syncLength; /* Length of sync word in bits */
1085 UINT syncWord; /* Sync word to be found */
1086 UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one
1087 bit less) */
1088 C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
1089
1090 totalBits = (INT)FDKgetValidBits(hBs);
1091
1092 if (totalBits <= 0) {
1093 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1094 goto bail;
1095 }
1096
1097 fTraverseMoreFrames =
1098 (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
1099 !(hTp->flags & TPDEC_SYNCOK);
1100
1101 /* Set transport specific sync parameters */
1102 switch (hTp->transportFmt) {
1103 case TT_MP4_ADTS:
1104 syncWord = ADTS_SYNCWORD;
1105 syncLength = ADTS_SYNCLENGTH;
1106 break;
1107 case TT_MP4_LOAS:
1108 syncWord = 0x2B7;
1109 syncLength = 11;
1110 break;
1111 default:
1112 syncWord = 0;
1113 syncLength = 0;
1114 break;
1115 }
1116
1117 syncMask = (1 << syncLength) - 1;
1118
1119 do {
1120 INT bitsAvail = 0; /* Bits available in bitstream buffer */
1121 INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
1122 */
1123 UINT synch; /* Current sync word read from bitstream */
1124
1125 headerBitsPrevious = headerBits;
1126
1127 bitsAvail = (INT)FDKgetValidBits(hBs);
1128
1129 if (hTp->numberOfRawDataBlocks == 0) {
1130 /* search synchword */
1131
1132 FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
1133
1134 if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
1135 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1136 headerBits = 0;
1137 } else {
1138 synch = FDKreadBits(hBs, syncLength);
1139
1140 if (!(hTp->flags & TPDEC_SYNCOK)) {
1141 for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
1142 bitsAvail -= TPDEC_SYNCSKIP) {
1143 if (synch == syncWord) {
1144 break;
1145 }
1146 synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
1147 FDKreadBits(hBs, TPDEC_SYNCSKIP);
1148 }
1149 }
1150 if (synch != syncWord) {
1151 /* No correct syncword found. */
1152 err = TRANSPORTDEC_SYNC_ERROR;
1153 } else {
1154 err = TRANSPORTDEC_OK;
1155 }
1156 headerBits = syncLength;
1157 }
1158 } else {
1159 headerBits = 0;
1160 }
1161
1162 /* Save previous raw data block data */
1163 rawDataBlockLengthPrevious = rawDataBlockLength;
1164 numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
1165
1166 /* Parse transport header (raw data block granularity) */
1167
1168 if (err == TRANSPORTDEC_OK) {
1169 err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
1170 &rawDataBlockLength, &fTraverseMoreFrames,
1171 &syncLayerFrameBits, &fConfigFound,
1172 &headerBits);
1173 if (headerBits > bitsAvail) {
1174 err = (headerBits < (INT)hBs->hBitBuf.bufBits)
1175 ? TRANSPORTDEC_NOT_ENOUGH_BITS
1176 : TRANSPORTDEC_SYNC_ERROR;
1177 }
1178 if (TPDEC_IS_FATAL_ERROR(err)) {
1179 /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1180 * next time. Ensure that the bit amount lands at a multiple of
1181 * TPDEC_SYNCSKIP. */
1182 FDKpushBiDirectional(
1183 hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP));
1184
1185 goto bail;
1186 }
1187 }
1188
1189 bitsAvail -= headerBits;
1190
1191 checkLengthBits = syncLayerFrameBits;
1192
1193 /* Check if the whole frame would fit the bitstream buffer */
1194 if (err == TRANSPORTDEC_OK) {
1195 if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
1196 /* We assume that the size of the transport bit buffer has been
1197 chosen to meet all system requirements, thus this condition
1198 is considered a synchronisation error. */
1199 err = TRANSPORTDEC_SYNC_ERROR;
1200 } else {
1201 if (bitsAvail < checkLengthBits) {
1202 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1203 }
1204 }
1205 }
1206
1207 if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1208 break;
1209 }
1210
1211 if (err == TRANSPORTDEC_SYNC_ERROR) {
1212 int bits;
1213
1214 /* Enforce re-sync of transport headers. */
1215 hTp->numberOfRawDataBlocks = 0;
1216
1217 /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
1218 bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
1219 /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1220 * next time. */
1221 FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
1222 headerBits = 0;
1223 }
1224
1225 /* Frame traversal */
1226 if (fTraverseMoreFrames) {
1227 /* Save parser context for early config discovery "rewind all frames" */
1228 if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
1229 !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
1230 /* ignore buffer fullness if just traversing additional frames for ECD
1231 */
1232 ignoreBufferFullness = 1;
1233
1234 /* Save context in order to return later */
1235 if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
1236 startPosFirstFrame = FDKgetValidBits(hBs);
1237 numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
1238 globalFramePosFirstFrame = hTp->globalFramePos;
1239 rawDataBlockLengthFirstFrame = rawDataBlockLength;
1240 headerBitsFirstFrame = headerBits;
1241 errFirstFrame = err;
1242 FDKmemcpy(contextFirstFrame, &hTp->parser,
1243 sizeof(transportdec_parser_t));
1244 }
1245
1246 /* Break when config was found or it is not possible anymore to find a
1247 * config */
1248 if (startPosFirstFrame != -1 &&
1249 (fConfigFound || err != TRANSPORTDEC_OK)) {
1250 /* In case of ECD and sync error, do not rewind anywhere. */
1251 if (err == TRANSPORTDEC_SYNC_ERROR) {
1252 startPosFirstFrame = -1;
1253 fConfigFound = 0;
1254 numFramesTraversed = 0;
1255 }
1256 break;
1257 }
1258 }
1259
1260 if (err == TRANSPORTDEC_OK) {
1261 FDKpushFor(hBs, rawDataBlockLength);
1262 numFramesTraversed++;
1263 endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
1264 /* Ignore error here itentionally. */
1265 transportDec_AdjustEndOfAccessUnit(hTp);
1266 endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
1267 }
1268 }
1269 } while (fTraverseMoreFrames ||
1270 (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
1271
1272 /* Restore context in case of ECD frame traversal */
1273 if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
1274 FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
1275 FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
1276 hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
1277 hTp->globalFramePos = globalFramePosFirstFrame;
1278 rawDataBlockLength = rawDataBlockLengthFirstFrame;
1279 headerBits = headerBitsFirstFrame;
1280 err = errFirstFrame;
1281 numFramesTraversed = 0;
1282 }
1283
1284 /* Additional burst data mode buffer fullness check. */
1285 if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
1286 TPDEC_SYNCOK)) &&
1287 err == TRANSPORTDEC_OK) {
1288 err =
1289 additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
1290 (INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
1291 if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1292 hTp->holdOffFrames++;
1293 }
1294 }
1295
1296 /* Rewind for retry because of not enough bits */
1297 if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1298 FDKpushBack(hBs, headerBits);
1299 hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1300 headerBits = 0;
1301 rawDataBlockLength = rawDataBlockLengthPrevious;
1302 } else {
1303 /* reset hold off frame counter */
1304 hTp->holdOffFrames = 0;
1305 }
1306
1307 /* Return to last good frame in case of frame traversal but not ECD. */
1308 if (numFramesTraversed > 0) {
1309 FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
1310 if (err != TRANSPORTDEC_OK) {
1311 hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1312 headerBits = headerBitsPrevious;
1313 rawDataBlockLength = rawDataBlockLengthPrevious;
1314 }
1315 err = TRANSPORTDEC_OK;
1316 }
1317
1318 bail:
1319 hTp->auLength[0] = rawDataBlockLength;
1320
1321 /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
1322 buffer is already full, or no new burst packet fits. Recover by advancing
1323 the bit buffer. */
1324 if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
1325 (FDKgetValidBits(hBs) >=
1326 (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
1327 7))) {
1328 FDKpushFor(hBs, TPDEC_SYNCSKIP);
1329 err = TRANSPORTDEC_SYNC_ERROR;
1330 }
1331
1332 if (err == TRANSPORTDEC_OK) {
1333 hTp->flags |= TPDEC_SYNCOK;
1334 }
1335
1336 if (fConfigFound) {
1337 hTp->flags |= TPDEC_CONFIG_FOUND;
1338 }
1339
1340 if (pHeaderBits != NULL) {
1341 *pHeaderBits = headerBits;
1342 }
1343
1344 if (err == TRANSPORTDEC_SYNC_ERROR) {
1345 hTp->flags &= ~TPDEC_SYNCOK;
1346 }
1347
1348 C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
1349
1350 return err;
1351 }
1352
1353 /**
1354 * \brief Synchronize to stream and estimate the amount of missing access units
1355 * due to a current synchronization error in case of constant average bit rate.
1356 */
transportDec_readStream(HANDLE_TRANSPORTDEC hTp,const UINT layer)1357 static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
1358 const UINT layer) {
1359 TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1360 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
1361
1362 INT headerBits;
1363 INT bitDistance, bfDelta;
1364
1365 /* Obtain distance to next synch word */
1366 bitDistance = (INT)FDKgetValidBits(hBs);
1367 error = synchronization(hTp, &headerBits);
1368 bitDistance -= (INT)FDKgetValidBits(hBs);
1369
1370 FDK_ASSERT(bitDistance >= 0);
1371
1372 INT nAU = -1;
1373
1374 if (error == TRANSPORTDEC_SYNC_ERROR ||
1375 (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1376 /* Check if estimating lost access units is feasible. */
1377 if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
1378 hTp->asc[0].m_samplingFrequency > 0) {
1379 if (error == TRANSPORTDEC_OK) {
1380 int aj;
1381
1382 aj = transportDec_GetBufferFullness(hTp);
1383 if (aj > 0) {
1384 bfDelta = aj;
1385 } else {
1386 bfDelta = 0;
1387 }
1388 /* sync was ok: last of a series of bad access units. */
1389 hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
1390 /* Add up bitDistance until end of the current frame. Later we substract
1391 this frame from the grand total, since this current successfully
1392 synchronized frame should not be skipped of course; but it must be
1393 accounted into the bufferfulness math. */
1394 bitDistance += hTp->auLength[0];
1395 } else {
1396 if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1397 /* sync not ok: one of many bad access units. */
1398 hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
1399 bfDelta = -(INT)hTp->lastValidBufferFullness;
1400 } else {
1401 bfDelta = 0;
1402 }
1403 }
1404
1405 {
1406 int num, denom;
1407
1408 /* Obtain estimate of number of lost frames */
1409 num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
1410 hTp->remainder;
1411 denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
1412 if (num > 0) {
1413 nAU = num / denom;
1414 hTp->remainder = num % denom;
1415 } else {
1416 hTp->remainder = num;
1417 }
1418
1419 if (error == TRANSPORTDEC_OK) {
1420 /* Final adjustment of remainder, taken -1 into account because
1421 current frame should not be skipped, thus substract -1 or do
1422 nothing instead of +1-1 accordingly. */
1423 if ((denom - hTp->remainder) >= hTp->remainder) {
1424 nAU--;
1425 }
1426
1427 if (nAU < 0) {
1428 /* There was one frame too much concealed, so unfortunately we will
1429 * have to skip one good frame. */
1430 transportDec_EndAccessUnit(hTp);
1431 error = synchronization(hTp, &headerBits);
1432 nAU = -1;
1433 }
1434 hTp->remainder = 0;
1435 /* Enforce last missed frames to be concealed. */
1436 if (nAU > 0) {
1437 FDKpushBack(hBs, headerBits);
1438 }
1439 }
1440 }
1441 }
1442 }
1443
1444 /* Be sure that lost frames are handled correctly. This is necessary due to
1445 some sync error sequences where later it turns out that there is not enough
1446 data, but the bits upto the sync word are discarded, thus causing a value
1447 of nAU > 0 */
1448 if (nAU > 0) {
1449 error = TRANSPORTDEC_SYNC_ERROR;
1450 }
1451
1452 hTp->missingAccessUnits = nAU;
1453
1454 return error;
1455 }
1456
1457 /* returns error code */
transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1458 TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
1459 const UINT layer) {
1460 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1461 HANDLE_FDK_BITSTREAM hBs;
1462
1463 if (!hTp) {
1464 return TRANSPORTDEC_INVALID_PARAMETER;
1465 }
1466
1467 hBs = &hTp->bitStream[layer];
1468
1469 if ((INT)FDKgetValidBits(hBs) <= 0) {
1470 /* This is only relevant for RAW and ADIF cases.
1471 * For streaming formats err will get overwritten. */
1472 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1473 hTp->numberOfRawDataBlocks = 0;
1474 }
1475
1476 switch (hTp->transportFmt) {
1477 case TT_MP4_ADIF:
1478 /* Read header if not already done */
1479 if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
1480 int i;
1481 CProgramConfig *pce;
1482 INT bsStart = FDKgetValidBits(hBs);
1483 UCHAR configChanged = 0;
1484 UCHAR configMode = AC_CM_DET_CFG_CHANGE;
1485
1486 for (i = 0; i < 2; i++) {
1487 if (i > 0) {
1488 FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
1489 configMode = AC_CM_ALLOC_MEM;
1490 }
1491
1492 AudioSpecificConfig_Init(&hTp->asc[0]);
1493 pce = &hTp->asc[0].m_progrConfigElement;
1494 err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
1495 if (err) goto bail;
1496
1497 /* Map adif header to ASC */
1498 hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
1499 hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
1500 hTp->asc[0].m_samplingFrequency =
1501 SamplingRateTable[pce->SamplingFrequencyIndex];
1502 hTp->asc[0].m_channelConfiguration = 0;
1503 hTp->asc[0].m_samplesPerFrame = 1024;
1504 hTp->avgBitRate = hTp->parser.adif.BitRate;
1505
1506 /* Call callback to decoder. */
1507 {
1508 int errC;
1509
1510 errC = hTp->callbacks.cbUpdateConfig(
1511 hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
1512 &configChanged);
1513 if (errC == 0) {
1514 hTp->flags |= TPDEC_CONFIG_FOUND;
1515 } else {
1516 err = TRANSPORTDEC_PARSE_ERROR;
1517 goto bail;
1518 }
1519 }
1520
1521 if (err == TRANSPORTDEC_OK) {
1522 if ((i == 0) && configChanged) {
1523 int errC;
1524 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
1525 &hTp->asc[0]);
1526 if (errC != 0) {
1527 err = TRANSPORTDEC_PARSE_ERROR;
1528 }
1529 }
1530 }
1531 }
1532 }
1533 hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
1534 break;
1535
1536 case TT_MP4_RAW:
1537 case TT_DRM:
1538 /* One Access Unit was filled into buffer.
1539 So get the length out of the buffer. */
1540 hTp->auLength[layer] = FDKgetValidBits(hBs);
1541 hTp->flags |= TPDEC_SYNCOK;
1542 break;
1543
1544 case TT_MP4_LATM_MCP0:
1545 case TT_MP4_LATM_MCP1:
1546 if (err == TRANSPORTDEC_OK) {
1547 int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
1548 err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
1549 NULL, NULL, &fConfigFound, NULL);
1550 if (fConfigFound) {
1551 hTp->flags |= TPDEC_CONFIG_FOUND;
1552 }
1553 }
1554 break;
1555
1556 case TT_MP4_ADTS:
1557 case TT_MP4_LOAS:
1558 err = transportDec_readStream(hTp, layer);
1559 break;
1560
1561 default:
1562 err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
1563 break;
1564 }
1565
1566 if (err == TRANSPORTDEC_OK) {
1567 hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
1568 } else {
1569 hTp->accessUnitAnchor[layer] = 0;
1570 }
1571
1572 bail:
1573 return err;
1574 }
1575
transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,const UINT layer,CSAudioSpecificConfig * asc)1576 TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
1577 const UINT layer,
1578 CSAudioSpecificConfig *asc) {
1579 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1580
1581 if (hTp != NULL) {
1582 *asc = hTp->asc[layer];
1583 err = TRANSPORTDEC_OK;
1584 } else {
1585 err = TRANSPORTDEC_INVALID_PARAMETER;
1586 }
1587 return err;
1588 }
1589
transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1590 INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
1591 const UINT layer) {
1592 INT bits;
1593
1594 if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
1595 bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
1596 if (bits >= 0) {
1597 bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
1598 }
1599 } else {
1600 bits = FDKgetValidBits(&hTp->bitStream[layer]);
1601 }
1602
1603 return bits;
1604 }
1605
transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1606 INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
1607 const UINT layer) {
1608 return hTp->auLength[layer];
1609 }
1610
transportDec_GetMissingAccessUnitCount(INT * pNAccessUnits,HANDLE_TRANSPORTDEC hTp)1611 TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
1612 INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
1613 *pNAccessUnits = hTp->missingAccessUnits;
1614
1615 return TRANSPORTDEC_OK;
1616 }
1617
1618 /* Inform the transportDec layer that reading of access unit has finished. */
transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp)1619 TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
1620 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1621
1622 switch (hTp->transportFmt) {
1623 case TT_MP4_LOAS:
1624 case TT_MP4_LATM_MCP0:
1625 case TT_MP4_LATM_MCP1: {
1626 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1627 if (hTp->numberOfRawDataBlocks == 0) {
1628 /* Read other data if available. */
1629 if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
1630 int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
1631
1632 if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
1633 FDKpushFor(hBs, otherDataLen);
1634 } else {
1635 /* Do byte align at the end of AudioMuxElement. */
1636 if (hTp->numberOfRawDataBlocks == 0) {
1637 FDKbyteAlign(hBs, hTp->globalFramePos);
1638 }
1639 return TRANSPORTDEC_NOT_ENOUGH_BITS;
1640 }
1641 }
1642 } else {
1643 /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
1644 then too many bits were read and obviously no more RawDataBlocks can
1645 be read. Set numberOfRawDataBlocks to zero to attempt a new sync
1646 attempt. */
1647 if ((INT)FDKgetValidBits(hBs) <= 0) {
1648 hTp->numberOfRawDataBlocks = 0;
1649 }
1650 }
1651 } break;
1652 default:
1653 break;
1654 }
1655
1656 err = transportDec_AdjustEndOfAccessUnit(hTp);
1657
1658 switch (hTp->transportFmt) {
1659 default:
1660 break;
1661 }
1662
1663 return err;
1664 }
1665
transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,const TPDEC_PARAM param,const INT value)1666 TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
1667 const TPDEC_PARAM param,
1668 const INT value) {
1669 TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1670
1671 if (hTp == NULL) {
1672 return TRANSPORTDEC_INVALID_PARAMETER;
1673 }
1674
1675 switch (param) {
1676 case TPDEC_PARAM_MINIMIZE_DELAY:
1677 if (value) {
1678 hTp->flags |= TPDEC_MINIMIZE_DELAY;
1679 } else {
1680 hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
1681 }
1682 break;
1683 case TPDEC_PARAM_EARLY_CONFIG:
1684 if (value) {
1685 hTp->flags |= TPDEC_EARLY_CONFIG;
1686 } else {
1687 hTp->flags &= ~TPDEC_EARLY_CONFIG;
1688 }
1689 break;
1690 case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
1691 if (value) {
1692 hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
1693 } else {
1694 hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
1695 }
1696 break;
1697 case TPDEC_PARAM_SET_BITRATE:
1698 hTp->avgBitRate = value;
1699 break;
1700 case TPDEC_PARAM_BURST_PERIOD:
1701 hTp->burstPeriod = value;
1702 break;
1703 case TPDEC_PARAM_RESET: {
1704 int i;
1705
1706 for (i = 0; i < (1 * 1); i++) {
1707 FDKresetBitbuffer(&hTp->bitStream[i]);
1708 hTp->auLength[i] = 0;
1709 hTp->accessUnitAnchor[i] = 0;
1710 }
1711 hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
1712 if (hTp->transportFmt != TT_MP4_ADIF) {
1713 hTp->flags &= ~TPDEC_CONFIG_FOUND;
1714 }
1715 hTp->remainder = 0;
1716 hTp->avgBitRate = 0;
1717 hTp->missingAccessUnits = 0;
1718 hTp->numberOfRawDataBlocks = 0;
1719 hTp->globalFramePos = 0;
1720 hTp->holdOffFrames = 0;
1721 } break;
1722 case TPDEC_PARAM_TARGETLAYOUT:
1723 hTp->targetLayout = value;
1724 break;
1725 case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
1726 hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
1727 break;
1728 case TPDEC_PARAM_USE_ELEM_SKIPPING:
1729 if (value) {
1730 hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
1731 } else {
1732 hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
1733 }
1734 break;
1735 }
1736
1737 return error;
1738 }
1739
transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp)1740 UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
1741 UINT nSubFrames = 0;
1742
1743 if (hTp == NULL) return 0;
1744
1745 if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
1746 hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
1747 nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
1748 else if (hTp->transportFmt == TT_MP4_ADTS)
1749 nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
1750
1751 return nSubFrames;
1752 }
1753
transportDec_Close(HANDLE_TRANSPORTDEC * phTp)1754 void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
1755 if (phTp != NULL) {
1756 if (*phTp != NULL) {
1757 FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
1758 FreeRam_TransportDecoder(phTp);
1759 }
1760 }
1761 }
1762
transportDec_GetLibInfo(LIB_INFO * info)1763 TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
1764 int i;
1765
1766 if (info == NULL) {
1767 return TRANSPORTDEC_UNKOWN_ERROR;
1768 }
1769
1770 /* search for next free tab */
1771 for (i = 0; i < FDK_MODULE_LAST; i++) {
1772 if (info[i].module_id == FDK_NONE) break;
1773 }
1774 if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
1775 info += i;
1776
1777 info->module_id = FDK_TPDEC;
1778 #ifdef SUPPRESS_BUILD_DATE_INFO
1779 info->build_date = "";
1780 info->build_time = "";
1781 #else
1782 info->build_date = __DATE__;
1783 info->build_time = __TIME__;
1784 #endif
1785 info->title = TP_LIB_TITLE;
1786 info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
1787 LIB_VERSION_STRING(info);
1788 info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
1789 CAPF_RAWPACKETS | CAPF_DRM;
1790
1791 return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
1792 }
1793
transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp,INT mBits)1794 int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
1795 switch (pTp->transportFmt) {
1796 case TT_MP4_ADTS:
1797 return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
1798 case TT_DRM:
1799 return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
1800 default:
1801 return -1;
1802 }
1803 }
1804
transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp,INT reg)1805 void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
1806 switch (pTp->transportFmt) {
1807 case TT_MP4_ADTS:
1808 adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
1809 break;
1810 case TT_DRM:
1811 drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
1812 break;
1813 default:
1814 break;
1815 }
1816 }
1817
transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)1818 TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
1819 switch (pTp->transportFmt) {
1820 case TT_MP4_ADTS:
1821 if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
1822 (pTp->parser.adts.bs.protection_absent == 0)) {
1823 transportDec_AdjustEndOfAccessUnit(pTp);
1824 }
1825 return adtsRead_CrcCheck(&pTp->parser.adts);
1826 case TT_DRM:
1827 return drmRead_CrcCheck(&pTp->parser.drm);
1828 default:
1829 return TRANSPORTDEC_OK;
1830 }
1831 }
1832
transportDec_DrmRawSdcAudioConfig_Check(UCHAR * conf,const UINT length)1833 TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
1834 const UINT length) {
1835 CSAudioSpecificConfig asc;
1836 FDK_BITSTREAM bs;
1837 HANDLE_FDK_BITSTREAM hBs = &bs;
1838
1839 FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);
1840
1841 TRANSPORTDEC_ERROR err =
1842 DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);
1843
1844 return err;
1845 }
1846