1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2019 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 amm-info@iis.fraunhofer.de
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
356 if (err == TRANSPORTDEC_OK && fConfigFound) {
357 hTp->flags |= TPDEC_CONFIG_FOUND;
358 }
359
360 return err;
361 }
362
transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,UCHAR * newConfig,const UINT newConfigLength,const UCHAR buildUpStatus,UCHAR * configChanged,UINT layer,UCHAR * implicitExplicitCfgDiff)363 TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
364 UCHAR *newConfig,
365 const UINT newConfigLength,
366 const UCHAR buildUpStatus,
367 UCHAR *configChanged, UINT layer,
368 UCHAR *implicitExplicitCfgDiff) {
369 int errC;
370 FDK_BITSTREAM bs;
371 HANDLE_FDK_BITSTREAM hBs = &bs;
372 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
373 int fConfigFound = 0;
374 UCHAR configMode = AC_CM_ALLOC_MEM;
375 *implicitExplicitCfgDiff = 0;
376
377 FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
378
379 FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
380 BS_READER);
381
382 if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
383 (hTp->ctrlCFGChange[layer].buildUpStatus !=
384 TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
385 if (hTp->asc->m_aot == AOT_USAC) {
386 if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
387 newConfigLength) {
388 if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
389 newConfigLength)) {
390 if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
391 LOAS/LATM parser */
392 hTp->parser.latm.usacExplicitCfgChanged = 0;
393 hTp->ctrlCFGChange[layer].flushCnt = 0;
394 hTp->ctrlCFGChange[layer].flushStatus =
395 TPDEC_USAC_DASH_IPF_FLUSH_ON;
396 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
397 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
398 } else {
399 *configChanged = 0;
400 return err;
401 }
402 } else {
403 *implicitExplicitCfgDiff = 1;
404 }
405 } else {
406 *implicitExplicitCfgDiff = 1;
407 }
408 /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
409 * config shall be identical. */
410 if (*implicitExplicitCfgDiff) {
411 switch (hTp->transportFmt) {
412 case TT_MP4_LATM_MCP0:
413 case TT_MP4_LATM_MCP1:
414 case TT_MP4_LOAS:
415 /* reset decoder to initial state to achieve definite behavior after
416 * error in config */
417 hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
418 &hTp->asc[layer]);
419 hTp->parser.latm.usacExplicitCfgChanged = 0;
420 hTp->parser.latm.applyAsc = 1;
421 err = TRANSPORTDEC_PARSE_ERROR;
422 goto bail;
423 default:
424 break;
425 }
426 }
427 }
428 }
429
430 {
431 if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
432 (hTp->ctrlCFGChange[layer].buildUpStatus !=
433 TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
434 hTp->ctrlCFGChange[layer].flushCnt = 0;
435 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
436 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
437 if (hTp->asc->m_aot == AOT_USAC) {
438 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
439 }
440 }
441
442 if ((hTp->ctrlCFGChange[layer].flushStatus ==
443 TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
444 (hTp->ctrlCFGChange[layer].flushStatus ==
445 TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
446 SCHAR counter = 0;
447 if (hTp->asc->m_aot == AOT_USAC) {
448 counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
449 }
450 if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
451 hTp->ctrlCFGChange[layer].flushCnt = 0;
452 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
453 hTp->ctrlCFGChange[layer].forceCfgChange = 0;
454 if (hTp->asc->m_aot == AOT_USAC) {
455 hTp->ctrlCFGChange[layer].buildUpCnt =
456 TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
457 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
458 }
459 }
460
461 /* Activate flush mode. After that continue with build up mode in core */
462 if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
463 &hTp->ctrlCFGChange[layer]) != 0) {
464 err = TRANSPORTDEC_PARSE_ERROR;
465 }
466
467 if ((hTp->ctrlCFGChange[layer].flushStatus ==
468 TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
469 (hTp->ctrlCFGChange[layer].flushStatus ==
470 TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
471 hTp->ctrlCFGChange[layer].flushCnt++;
472 return err;
473 }
474 }
475
476 if (hTp->asc->m_aot == AOT_USAC) {
477 fConfigFound = 1;
478
479 if (err == TRANSPORTDEC_OK) {
480 *configChanged = 0;
481 configMode = AC_CM_DET_CFG_CHANGE;
482
483 for (int i = 0; i < 2; i++) {
484 if (i > 0) {
485 FDKpushBack(hBs,
486 (INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
487 configMode = AC_CM_ALLOC_MEM;
488 }
489 /* config transport decoder */
490 err = AudioSpecificConfig_Parse(
491 &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
492 *configChanged, hTp->asc[layer].m_aot);
493 if (err == TRANSPORTDEC_OK) {
494 hTp->asc[layer] = hTp->asc[(1 * 1)];
495 errC = hTp->callbacks.cbUpdateConfig(
496 hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
497 hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
498 if (errC != 0) {
499 err = TRANSPORTDEC_PARSE_ERROR;
500 }
501 }
502
503 if (err == TRANSPORTDEC_OK) {
504 if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
505 hTp->asc[layer].SbrConfigChanged ||
506 hTp->asc[layer].SacConfigChanged)) {
507 *configChanged = 1;
508 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
509 &hTp->asc[layer]);
510 if (errC != 0) {
511 err = TRANSPORTDEC_PARSE_ERROR;
512 }
513 }
514 }
515
516 /* if an error is detected terminate config parsing to avoid that an
517 * invalid config is accepted in the second pass */
518 if (err != TRANSPORTDEC_OK) {
519 break;
520 }
521 }
522 }
523 }
524
525 bail:
526 /* save new config */
527 if (err == TRANSPORTDEC_OK) {
528 if (hTp->asc->m_aot == AOT_USAC) {
529 hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
530 FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
531 newConfigLength);
532 /* in case of USAC reset transportDecoder variables here because
533 * otherwise without IPF they are not reset */
534 hTp->ctrlCFGChange[layer].flushCnt = 0;
535 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
536 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
537 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
538 }
539 } else {
540 hTp->numberOfRawDataBlocks = 0;
541
542 /* If parsing error while config found, clear ctrlCFGChange-struct */
543 hTp->ctrlCFGChange[layer].flushCnt = 0;
544 hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
545 hTp->ctrlCFGChange[layer].buildUpCnt = 0;
546 hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
547 hTp->ctrlCFGChange[layer].cfgChanged = 0;
548 hTp->ctrlCFGChange[layer].contentChanged = 0;
549 hTp->ctrlCFGChange[layer].forceCfgChange = 0;
550
551 hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
552 &hTp->ctrlCFGChange[layer]);
553 }
554 }
555
556 if (err == TRANSPORTDEC_OK && fConfigFound) {
557 hTp->flags |= TPDEC_CONFIG_FOUND;
558 }
559
560 return err;
561 }
562
transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUpdateConfig_t cbUpdateConfig,void * user_data)563 int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
564 const cbUpdateConfig_t cbUpdateConfig,
565 void *user_data) {
566 if (hTpDec == NULL) {
567 return -1;
568 }
569 hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
570 hTpDec->callbacks.cbUpdateConfigData = user_data;
571 return 0;
572 }
573
transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,const cbFreeMem_t cbFreeMem,void * user_data)574 int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
575 const cbFreeMem_t cbFreeMem,
576 void *user_data) {
577 if (hTpDec == NULL) {
578 return -1;
579 }
580 hTpDec->callbacks.cbFreeMem = cbFreeMem;
581 hTpDec->callbacks.cbFreeMemData = user_data;
582 return 0;
583 }
584
transportDec_RegisterCtrlCFGChangeCallback(HANDLE_TRANSPORTDEC hTpDec,const cbCtrlCFGChange_t cbCtrlCFGChange,void * user_data)585 int transportDec_RegisterCtrlCFGChangeCallback(
586 HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
587 void *user_data) {
588 if (hTpDec == NULL) {
589 return -1;
590 }
591 hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
592 hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
593 return 0;
594 }
595
transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,const cbSsc_t cbSsc,void * user_data)596 int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
597 const cbSsc_t cbSsc, void *user_data) {
598 if (hTpDec == NULL) {
599 return -1;
600 }
601 hTpDec->callbacks.cbSsc = cbSsc;
602 hTpDec->callbacks.cbSscData = user_data;
603 return 0;
604 }
605
transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,const cbSbr_t cbSbr,void * user_data)606 int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
607 const cbSbr_t cbSbr, void *user_data) {
608 if (hTpDec == NULL) {
609 return -1;
610 }
611 hTpDec->callbacks.cbSbr = cbSbr;
612 hTpDec->callbacks.cbSbrData = user_data;
613 return 0;
614 }
615
transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUsac_t cbUsac,void * user_data)616 int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
617 const cbUsac_t cbUsac, void *user_data) {
618 if (hTpDec == NULL) {
619 return -1;
620 }
621 hTpDec->callbacks.cbUsac = cbUsac;
622 hTpDec->callbacks.cbUsacData = user_data;
623 return 0;
624 }
625
transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUniDrc_t cbUniDrc,void * user_data,UINT * pLoudnessInfoSetPosition)626 int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
627 const cbUniDrc_t cbUniDrc,
628 void *user_data,
629 UINT *pLoudnessInfoSetPosition) {
630 if (hTpDec == NULL) {
631 return -1;
632 }
633
634 hTpDec->callbacks.cbUniDrc = cbUniDrc;
635 hTpDec->callbacks.cbUniDrcData = user_data;
636
637 hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
638 return 0;
639 }
640
transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,UCHAR * pBuffer,const UINT bufferSize,UINT * pBytesValid,const INT layer)641 TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
642 UCHAR *pBuffer, const UINT bufferSize,
643 UINT *pBytesValid, const INT layer) {
644 HANDLE_FDK_BITSTREAM hBs;
645
646 if ((hTp == NULL) || (layer >= 1)) {
647 return TRANSPORTDEC_INVALID_PARAMETER;
648 }
649
650 /* set bitbuffer shortcut */
651 hBs = &hTp->bitStream[layer];
652
653 if (TT_IS_PACKET(hTp->transportFmt)) {
654 if (hTp->numberOfRawDataBlocks == 0) {
655 FDKresetBitbuffer(hBs);
656 FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
657 if (*pBytesValid != 0) {
658 return TRANSPORTDEC_TOO_MANY_BITS;
659 }
660 }
661 } else {
662 /* ... else feed bitbuffer with new stream data (append). */
663
664 if (*pBytesValid == 0) {
665 /* nothing to do */
666 return TRANSPORTDEC_OK;
667 } else {
668 const int bytesValid = *pBytesValid;
669 FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
670
671 if (hTp->numberOfRawDataBlocks > 0) {
672 hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
673 hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
674 }
675 }
676 }
677
678 return TRANSPORTDEC_OK;
679 }
680
transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,const UINT layer)681 HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
682 const UINT layer) {
683 return &hTp->bitStream[layer];
684 }
685
transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp)686 TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
687 return hTp->transportFmt;
688 }
689
transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp)690 INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
691 INT bufferFullness = -1;
692
693 switch (hTp->transportFmt) {
694 case TT_MP4_ADTS:
695 if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
696 bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
697 hTp->parser.adts.bs.adts_fullness * 32 *
698 getNumberOfEffectiveChannels(
699 hTp->parser.adts.bs.channel_config);
700 }
701 break;
702 case TT_MP4_LOAS:
703 case TT_MP4_LATM_MCP0:
704 case TT_MP4_LATM_MCP1:
705 if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
706 bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
707 }
708 break;
709 default:
710 break;
711 }
712
713 return bufferFullness;
714 }
715
716 /**
717 * \brief adjust bit stream position and the end of an access unit.
718 * \param hTp transport decoder handle.
719 * \return error code.
720 */
transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)721 static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
722 HANDLE_TRANSPORTDEC hTp) {
723 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
724 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
725
726 switch (hTp->transportFmt) {
727 case TT_MP4_ADIF:
728 /* Do byte align at the end of raw_data_block() because UsacFrame() is not
729 * byte aligned. */
730 FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
731 break;
732 case TT_MP4_LOAS:
733 case TT_MP4_LATM_MCP0:
734 case TT_MP4_LATM_MCP1:
735 if (hTp->numberOfRawDataBlocks == 0) {
736 /* Do byte align at the end of AudioMuxElement. */
737 FDKbyteAlign(hBs, hTp->globalFramePos);
738
739 /* Check global frame length */
740 if (hTp->transportFmt == TT_MP4_LOAS &&
741 hTp->parser.latm.m_audioMuxLengthBytes > 0) {
742 int loasOffset;
743
744 loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
745 (INT)FDKgetValidBits(hBs)) -
746 (INT)hTp->globalFramePos;
747 if (loasOffset != 0) {
748 FDKpushBiDirectional(hBs, loasOffset);
749 /* For ELD and other payloads there is an unknown amount of padding,
750 so ignore unread bits, but throw an error only if too many bits
751 where read. */
752 if (loasOffset < 0) {
753 err = TRANSPORTDEC_PARSE_ERROR;
754 }
755 }
756 }
757 }
758 break;
759
760 case TT_MP4_ADTS:
761 if (hTp->parser.adts.bs.protection_absent == 0) {
762 int offset;
763
764 /* Calculate offset to end of AU */
765 offset = hTp->parser.adts
766 .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
767 hTp->numberOfRawDataBlocks]
768 << 3;
769 /* CAUTION: The PCE (if available) is declared to be a part of the
770 * header! */
771 offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
772 16 + hTp->parser.adts.bs.num_pce_bits;
773 FDKpushBiDirectional(hBs, offset);
774 }
775 if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
776 hTp->parser.adts.bs.protection_absent == 0) {
777 /* Note this CRC read currently happens twice because of
778 * transportDec_CrcCheck() */
779 hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
780 }
781 if (hTp->numberOfRawDataBlocks == 0) {
782 /* Check global frame length */
783 if (hTp->parser.adts.bs.protection_absent == 0) {
784 int offset;
785
786 offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
787 (INT)FDKgetValidBits(hBs)) -
788 (INT)hTp->globalFramePos;
789 if (offset != 0) {
790 FDKpushBiDirectional(hBs, offset);
791 }
792 }
793 }
794 break;
795
796 default:
797 break;
798 }
799
800 return err;
801 }
802
803 /**
804 * \brief Determine additional buffer fullness contraint due to burst data
805 * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
806 * precondition.
807 * \param hTp transport decoder handle.
808 * \param bufferFullness the buffer fullness value of the first frame to be
809 * decoded.
810 * \param bitsAvail the amount of available bits at the end of the first frame
811 * to be decoded.
812 * \return error code
813 */
additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,INT bufferFullness,INT bitsAvail)814 static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
815 INT bufferFullness,
816 INT bitsAvail) {
817 INT checkLengthBits, avgBitsPerFrame;
818 INT maxAU; /* maximum number of frames per Master Frame */
819 INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
820 INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
821
822 if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
823 return TRANSPORTDEC_OK;
824 }
825 if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
826 return TRANSPORTDEC_NOT_ENOUGH_BITS;
827 }
828
829 /* One Master Frame is sent every hTp->burstPeriod ms */
830 maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
831 maxAU = maxAU / (samplesPerFrame * 1000);
832 /* Subtract number of frames which were already held off. */
833 maxAU -= hTp->holdOffFrames;
834
835 avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
836 avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
837
838 /* Consider worst case of bufferFullness quantization. */
839 switch (hTp->transportFmt) {
840 case TT_MP4_ADIF:
841 case TT_MP4_ADTS:
842 case TT_MP4_LOAS:
843 case TT_MP4_LATM_MCP0:
844 case TT_MP4_LATM_MCP1:
845 bufferFullness += 31;
846 break;
847 default: /* added to avoid compiler warning */
848 break; /* added to avoid compiler warning */
849 }
850
851 checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;
852
853 /* Check if buffer is big enough to fullfill buffer fullness condition */
854 if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
855 return TRANSPORTDEC_SYNC_ERROR;
856 }
857
858 if (bitsAvail < checkLengthBits) {
859 return TRANSPORTDEC_NOT_ENOUGH_BITS;
860 } else {
861 return TRANSPORTDEC_OK;
862 }
863 }
864
transportDec_readHeader(HANDLE_TRANSPORTDEC hTp,HANDLE_FDK_BITSTREAM hBs,int syncLength,int ignoreBufferFullness,int * pRawDataBlockLength,int * pfTraverseMoreFrames,int * pSyncLayerFrameBits,int * pfConfigFound,int * pHeaderBits)865 static TRANSPORTDEC_ERROR transportDec_readHeader(
866 HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
867 int ignoreBufferFullness, int *pRawDataBlockLength,
868 int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
869 int *pHeaderBits) {
870 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
871 int rawDataBlockLength = *pRawDataBlockLength;
872 int fTraverseMoreFrames =
873 (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
874 int syncLayerFrameBits =
875 (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
876 int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
877 int startPos;
878
879 startPos = (INT)FDKgetValidBits(hBs);
880
881 switch (hTp->transportFmt) {
882 case TT_MP4_ADTS:
883 if (hTp->numberOfRawDataBlocks <= 0) {
884 int i, errC;
885
886 hTp->globalFramePos = FDKgetValidBits(hBs);
887
888 UCHAR configChanged = 0;
889 UCHAR configMode = AC_CM_DET_CFG_CHANGE;
890
891 for (i = 0; i < 2; i++) {
892 if (i > 0) {
893 FDKpushBack(hBs,
894 (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
895 configMode = AC_CM_ALLOC_MEM;
896 }
897
898 /* Parse ADTS header */
899 err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
900 ignoreBufferFullness);
901 if (err != TRANSPORTDEC_OK) {
902 if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
903 err = TRANSPORTDEC_SYNC_ERROR;
904 }
905 } else {
906 errC = hTp->callbacks.cbUpdateConfig(
907 hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
908 &configChanged);
909 if (errC != 0) {
910 if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
911 err = TRANSPORTDEC_NEED_TO_RESTART;
912 goto bail;
913 } else {
914 err = TRANSPORTDEC_SYNC_ERROR;
915 }
916 } else {
917 fConfigFound = 1;
918 hTp->numberOfRawDataBlocks =
919 hTp->parser.adts.bs.num_raw_blocks + 1;
920 }
921 }
922
923 if (err == TRANSPORTDEC_OK) {
924 if ((i == 0) && configChanged) {
925 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
926 &hTp->asc[0]);
927 if (errC != 0) {
928 err = TRANSPORTDEC_PARSE_ERROR;
929 }
930 }
931 }
932 /* if an error is detected terminate config parsing to avoid that an
933 * invalid config is accepted in the second pass */
934 if (err != TRANSPORTDEC_OK) {
935 break;
936 }
937 }
938 } else {
939 /* Reset CRC because the next bits are the beginning of a
940 * raw_data_block() */
941 FDKcrcReset(&hTp->parser.adts.crcInfo);
942 hTp->parser.adts.bs.num_pce_bits = 0;
943 }
944 if (err == TRANSPORTDEC_OK) {
945 hTp->numberOfRawDataBlocks--;
946 rawDataBlockLength = adtsRead_GetRawDataBlockLength(
947 &hTp->parser.adts,
948 (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
949 if (rawDataBlockLength <= 0) {
950 /* No further frame traversal possible. */
951 fTraverseMoreFrames = 0;
952 }
953 syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
954 (startPos - (INT)FDKgetValidBits(hBs)) -
955 syncLength;
956 if (syncLayerFrameBits <= 0) {
957 err = TRANSPORTDEC_SYNC_ERROR;
958 }
959 } else {
960 hTp->numberOfRawDataBlocks = 0;
961 }
962 break;
963 case TT_MP4_LOAS:
964 if (hTp->numberOfRawDataBlocks <= 0) {
965 syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
966 hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
967 syncLayerFrameBits <<= 3;
968 }
969 FDK_FALLTHROUGH;
970 case TT_MP4_LATM_MCP1:
971 case TT_MP4_LATM_MCP0:
972 if (hTp->numberOfRawDataBlocks <= 0) {
973 hTp->globalFramePos = FDKgetValidBits(hBs);
974
975 err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
976 &hTp->callbacks, hTp->asc, &fConfigFound,
977 ignoreBufferFullness);
978
979 if (err != TRANSPORTDEC_OK) {
980 if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
981 !TPDEC_IS_FATAL_ERROR(err)) {
982 err = TRANSPORTDEC_SYNC_ERROR;
983 }
984 } else {
985 hTp->numberOfRawDataBlocks =
986 CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
987 if (hTp->transportFmt == TT_MP4_LOAS) {
988 syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
989 if (syncLayerFrameBits <= 0) {
990 err = TRANSPORTDEC_SYNC_ERROR;
991 }
992 }
993 }
994 } else {
995 err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
996 if (err != TRANSPORTDEC_OK) {
997 err = TRANSPORTDEC_SYNC_ERROR;
998 }
999 }
1000 if (err == TRANSPORTDEC_OK) {
1001 int layer;
1002 rawDataBlockLength = 0;
1003 for (layer = 0;
1004 layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
1005 layer += 1) {
1006 rawDataBlockLength +=
1007 CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
1008 }
1009 hTp->numberOfRawDataBlocks--;
1010 } else {
1011 hTp->numberOfRawDataBlocks = 0;
1012 }
1013 break;
1014 default: { syncLayerFrameBits = 0; } break;
1015 }
1016
1017 bail:
1018
1019 *pRawDataBlockLength = rawDataBlockLength;
1020
1021 if (pHeaderBits != NULL) {
1022 *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
1023 }
1024
1025 for (int i = 0; i < (1 * 1); i++) {
1026 /* If parsing error while config found, clear ctrlCFGChange-struct */
1027 if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
1028 hTp->numberOfRawDataBlocks = 0;
1029 hTp->ctrlCFGChange[i].flushCnt = 0;
1030 hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
1031 hTp->ctrlCFGChange[i].buildUpCnt = 0;
1032 hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
1033 hTp->ctrlCFGChange[i].cfgChanged = 0;
1034 hTp->ctrlCFGChange[i].contentChanged = 0;
1035 hTp->ctrlCFGChange[i].forceCfgChange = 0;
1036
1037 hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
1038 &hTp->ctrlCFGChange[i]);
1039 }
1040 }
1041
1042 if (pfConfigFound != NULL) {
1043 *pfConfigFound = fConfigFound;
1044 }
1045
1046 if (pfTraverseMoreFrames != NULL) {
1047 *pfTraverseMoreFrames = fTraverseMoreFrames;
1048 }
1049 if (pSyncLayerFrameBits != NULL) {
1050 *pSyncLayerFrameBits = syncLayerFrameBits;
1051 }
1052
1053 return err;
1054 }
1055
1056 /* How many bits to advance for synchronization search. */
1057 #define TPDEC_SYNCSKIP 8
1058
synchronization(HANDLE_TRANSPORTDEC hTp,INT * pHeaderBits)1059 static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
1060 INT *pHeaderBits) {
1061 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
1062 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1063
1064 INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
1065 INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
1066 INT totalBits;
1067 INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
1068 INT numFramesTraversed = 0, fTraverseMoreFrames,
1069 fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
1070 INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
1071 globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
1072 INT ignoreBufferFullness =
1073 hTp->flags &
1074 (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
1075 UINT endTpFrameBitsPrevious = 0;
1076
1077 /* Synch parameters */
1078 INT syncLength; /* Length of sync word in bits */
1079 UINT syncWord; /* Sync word to be found */
1080 UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one
1081 bit less) */
1082 C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
1083
1084 totalBits = (INT)FDKgetValidBits(hBs);
1085
1086 if (totalBits <= 0) {
1087 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1088 goto bail;
1089 }
1090
1091 fTraverseMoreFrames =
1092 (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
1093 !(hTp->flags & TPDEC_SYNCOK);
1094
1095 /* Set transport specific sync parameters */
1096 switch (hTp->transportFmt) {
1097 case TT_MP4_ADTS:
1098 syncWord = ADTS_SYNCWORD;
1099 syncLength = ADTS_SYNCLENGTH;
1100 break;
1101 case TT_MP4_LOAS:
1102 syncWord = 0x2B7;
1103 syncLength = 11;
1104 break;
1105 default:
1106 syncWord = 0;
1107 syncLength = 0;
1108 break;
1109 }
1110
1111 syncMask = (1 << syncLength) - 1;
1112
1113 do {
1114 INT bitsAvail = 0; /* Bits available in bitstream buffer */
1115 INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
1116 */
1117 UINT synch; /* Current sync word read from bitstream */
1118
1119 headerBitsPrevious = headerBits;
1120
1121 bitsAvail = (INT)FDKgetValidBits(hBs);
1122
1123 if (hTp->numberOfRawDataBlocks == 0) {
1124 /* search synchword */
1125
1126 FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
1127
1128 if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
1129 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1130 headerBits = 0;
1131 } else {
1132 synch = FDKreadBits(hBs, syncLength);
1133
1134 if (!(hTp->flags & TPDEC_SYNCOK)) {
1135 for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
1136 bitsAvail -= TPDEC_SYNCSKIP) {
1137 if (synch == syncWord) {
1138 break;
1139 }
1140 synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
1141 FDKreadBits(hBs, TPDEC_SYNCSKIP);
1142 }
1143 }
1144 if (synch != syncWord) {
1145 /* No correct syncword found. */
1146 err = TRANSPORTDEC_SYNC_ERROR;
1147 } else {
1148 err = TRANSPORTDEC_OK;
1149 }
1150 headerBits = syncLength;
1151 }
1152 } else {
1153 headerBits = 0;
1154 }
1155
1156 /* Save previous raw data block data */
1157 rawDataBlockLengthPrevious = rawDataBlockLength;
1158 numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
1159
1160 /* Parse transport header (raw data block granularity) */
1161
1162 if (err == TRANSPORTDEC_OK) {
1163 err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
1164 &rawDataBlockLength, &fTraverseMoreFrames,
1165 &syncLayerFrameBits, &fConfigFound,
1166 &headerBits);
1167 if (headerBits > bitsAvail) {
1168 err = (headerBits < (INT)hBs->hBitBuf.bufBits)
1169 ? TRANSPORTDEC_NOT_ENOUGH_BITS
1170 : TRANSPORTDEC_SYNC_ERROR;
1171 }
1172 if (TPDEC_IS_FATAL_ERROR(err)) {
1173 /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1174 * next time. Ensure that the bit amount lands at a multiple of
1175 * TPDEC_SYNCSKIP. */
1176 FDKpushBiDirectional(
1177 hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP));
1178
1179 goto bail;
1180 }
1181 }
1182
1183 bitsAvail -= headerBits;
1184
1185 checkLengthBits = syncLayerFrameBits;
1186
1187 /* Check if the whole frame would fit the bitstream buffer */
1188 if (err == TRANSPORTDEC_OK) {
1189 if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
1190 /* We assume that the size of the transport bit buffer has been
1191 chosen to meet all system requirements, thus this condition
1192 is considered a synchronisation error. */
1193 err = TRANSPORTDEC_SYNC_ERROR;
1194 } else {
1195 if (bitsAvail < checkLengthBits) {
1196 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1197 }
1198 }
1199 }
1200
1201 if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1202 break;
1203 }
1204
1205 if (err == TRANSPORTDEC_SYNC_ERROR) {
1206 int bits;
1207
1208 /* Enforce re-sync of transport headers. */
1209 hTp->numberOfRawDataBlocks = 0;
1210
1211 /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
1212 bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
1213 /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1214 * next time. */
1215 FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
1216 headerBits = 0;
1217 }
1218
1219 /* Frame traversal */
1220 if (fTraverseMoreFrames) {
1221 /* Save parser context for early config discovery "rewind all frames" */
1222 if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
1223 !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
1224 /* ignore buffer fullness if just traversing additional frames for ECD
1225 */
1226 ignoreBufferFullness = 1;
1227
1228 /* Save context in order to return later */
1229 if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
1230 startPosFirstFrame = FDKgetValidBits(hBs);
1231 numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
1232 globalFramePosFirstFrame = hTp->globalFramePos;
1233 rawDataBlockLengthFirstFrame = rawDataBlockLength;
1234 headerBitsFirstFrame = headerBits;
1235 errFirstFrame = err;
1236 FDKmemcpy(contextFirstFrame, &hTp->parser,
1237 sizeof(transportdec_parser_t));
1238 }
1239
1240 /* Break when config was found or it is not possible anymore to find a
1241 * config */
1242 if (startPosFirstFrame != -1 &&
1243 (fConfigFound || err != TRANSPORTDEC_OK)) {
1244 /* In case of ECD and sync error, do not rewind anywhere. */
1245 if (err == TRANSPORTDEC_SYNC_ERROR) {
1246 startPosFirstFrame = -1;
1247 fConfigFound = 0;
1248 numFramesTraversed = 0;
1249 }
1250 break;
1251 }
1252 }
1253
1254 if (err == TRANSPORTDEC_OK) {
1255 FDKpushFor(hBs, rawDataBlockLength);
1256 numFramesTraversed++;
1257 endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
1258 /* Ignore error here itentionally. */
1259 transportDec_AdjustEndOfAccessUnit(hTp);
1260 endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
1261 }
1262 }
1263 } while (fTraverseMoreFrames ||
1264 (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
1265
1266 /* Restore context in case of ECD frame traversal */
1267 if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
1268 FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
1269 FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
1270 hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
1271 hTp->globalFramePos = globalFramePosFirstFrame;
1272 rawDataBlockLength = rawDataBlockLengthFirstFrame;
1273 headerBits = headerBitsFirstFrame;
1274 err = errFirstFrame;
1275 numFramesTraversed = 0;
1276 }
1277
1278 /* Additional burst data mode buffer fullness check. */
1279 if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
1280 TPDEC_SYNCOK)) &&
1281 err == TRANSPORTDEC_OK) {
1282 err =
1283 additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
1284 (INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
1285 if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1286 hTp->holdOffFrames++;
1287 }
1288 }
1289
1290 /* Rewind for retry because of not enough bits */
1291 if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1292 FDKpushBack(hBs, headerBits);
1293 hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1294 headerBits = 0;
1295 rawDataBlockLength = rawDataBlockLengthPrevious;
1296 } else {
1297 /* reset hold off frame counter */
1298 hTp->holdOffFrames = 0;
1299 }
1300
1301 /* Return to last good frame in case of frame traversal but not ECD. */
1302 if (numFramesTraversed > 0) {
1303 FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
1304 if (err != TRANSPORTDEC_OK) {
1305 hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1306 headerBits = headerBitsPrevious;
1307 rawDataBlockLength = rawDataBlockLengthPrevious;
1308 }
1309 err = TRANSPORTDEC_OK;
1310 }
1311
1312 bail:
1313 hTp->auLength[0] = rawDataBlockLength;
1314
1315 /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
1316 buffer is already full, or no new burst packet fits. Recover by advancing
1317 the bit buffer. */
1318 if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
1319 (FDKgetValidBits(hBs) >=
1320 (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
1321 7))) {
1322 FDKpushFor(hBs, TPDEC_SYNCSKIP);
1323 err = TRANSPORTDEC_SYNC_ERROR;
1324 }
1325
1326 if (err == TRANSPORTDEC_OK) {
1327 hTp->flags |= TPDEC_SYNCOK;
1328 }
1329
1330 if (fConfigFound) {
1331 hTp->flags |= TPDEC_CONFIG_FOUND;
1332 }
1333
1334 if (pHeaderBits != NULL) {
1335 *pHeaderBits = headerBits;
1336 }
1337
1338 if (err == TRANSPORTDEC_SYNC_ERROR) {
1339 hTp->flags &= ~TPDEC_SYNCOK;
1340 }
1341
1342 C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
1343
1344 return err;
1345 }
1346
1347 /**
1348 * \brief Synchronize to stream and estimate the amount of missing access units
1349 * due to a current synchronization error in case of constant average bit rate.
1350 */
transportDec_readStream(HANDLE_TRANSPORTDEC hTp,const UINT layer)1351 static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
1352 const UINT layer) {
1353 TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1354 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
1355
1356 INT headerBits;
1357 INT bitDistance, bfDelta;
1358
1359 /* Obtain distance to next synch word */
1360 bitDistance = (INT)FDKgetValidBits(hBs);
1361 error = synchronization(hTp, &headerBits);
1362 bitDistance -= (INT)FDKgetValidBits(hBs);
1363
1364 FDK_ASSERT(bitDistance >= 0);
1365
1366 INT nAU = -1;
1367
1368 if (error == TRANSPORTDEC_SYNC_ERROR ||
1369 (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1370 /* Check if estimating lost access units is feasible. */
1371 if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
1372 hTp->asc[0].m_samplingFrequency > 0) {
1373 if (error == TRANSPORTDEC_OK) {
1374 int aj;
1375
1376 aj = transportDec_GetBufferFullness(hTp);
1377 if (aj > 0) {
1378 bfDelta = aj;
1379 } else {
1380 bfDelta = 0;
1381 }
1382 /* sync was ok: last of a series of bad access units. */
1383 hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
1384 /* Add up bitDistance until end of the current frame. Later we substract
1385 this frame from the grand total, since this current successfully
1386 synchronized frame should not be skipped of course; but it must be
1387 accounted into the bufferfulness math. */
1388 bitDistance += hTp->auLength[0];
1389 } else {
1390 if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1391 /* sync not ok: one of many bad access units. */
1392 hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
1393 bfDelta = -(INT)hTp->lastValidBufferFullness;
1394 } else {
1395 bfDelta = 0;
1396 }
1397 }
1398
1399 {
1400 int num, denom;
1401
1402 /* Obtain estimate of number of lost frames */
1403 num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
1404 hTp->remainder;
1405 denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
1406 if (num > 0) {
1407 nAU = num / denom;
1408 hTp->remainder = num % denom;
1409 } else {
1410 hTp->remainder = num;
1411 }
1412
1413 if (error == TRANSPORTDEC_OK) {
1414 /* Final adjustment of remainder, taken -1 into account because
1415 current frame should not be skipped, thus substract -1 or do
1416 nothing instead of +1-1 accordingly. */
1417 if ((denom - hTp->remainder) >= hTp->remainder) {
1418 nAU--;
1419 }
1420
1421 if (nAU < 0) {
1422 /* There was one frame too much concealed, so unfortunately we will
1423 * have to skip one good frame. */
1424 transportDec_EndAccessUnit(hTp);
1425 error = synchronization(hTp, &headerBits);
1426 nAU = -1;
1427 }
1428 hTp->remainder = 0;
1429 /* Enforce last missed frames to be concealed. */
1430 if (nAU > 0) {
1431 FDKpushBack(hBs, headerBits);
1432 }
1433 }
1434 }
1435 }
1436 }
1437
1438 /* Be sure that lost frames are handled correctly. This is necessary due to
1439 some sync error sequences where later it turns out that there is not enough
1440 data, but the bits upto the sync word are discarded, thus causing a value
1441 of nAU > 0 */
1442 if (nAU > 0) {
1443 error = TRANSPORTDEC_SYNC_ERROR;
1444 }
1445
1446 hTp->missingAccessUnits = nAU;
1447
1448 return error;
1449 }
1450
1451 /* returns error code */
transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1452 TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
1453 const UINT layer) {
1454 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1455 HANDLE_FDK_BITSTREAM hBs;
1456
1457 if (!hTp) {
1458 return TRANSPORTDEC_INVALID_PARAMETER;
1459 }
1460
1461 hBs = &hTp->bitStream[layer];
1462
1463 if ((INT)FDKgetValidBits(hBs) <= 0) {
1464 /* This is only relevant for RAW and ADIF cases.
1465 * For streaming formats err will get overwritten. */
1466 err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1467 hTp->numberOfRawDataBlocks = 0;
1468 }
1469
1470 switch (hTp->transportFmt) {
1471 case TT_MP4_ADIF:
1472 /* Read header if not already done */
1473 if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
1474 int i;
1475 CProgramConfig *pce;
1476 INT bsStart = FDKgetValidBits(hBs);
1477 UCHAR configChanged = 0;
1478 UCHAR configMode = AC_CM_DET_CFG_CHANGE;
1479
1480 for (i = 0; i < 2; i++) {
1481 if (i > 0) {
1482 FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
1483 configMode = AC_CM_ALLOC_MEM;
1484 }
1485
1486 AudioSpecificConfig_Init(&hTp->asc[0]);
1487 pce = &hTp->asc[0].m_progrConfigElement;
1488 err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
1489 if (err) goto bail;
1490
1491 /* Map adif header to ASC */
1492 hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
1493 hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
1494 hTp->asc[0].m_samplingFrequency =
1495 SamplingRateTable[pce->SamplingFrequencyIndex];
1496 hTp->asc[0].m_channelConfiguration = 0;
1497 hTp->asc[0].m_samplesPerFrame = 1024;
1498 hTp->avgBitRate = hTp->parser.adif.BitRate;
1499
1500 /* Call callback to decoder. */
1501 {
1502 int errC;
1503
1504 errC = hTp->callbacks.cbUpdateConfig(
1505 hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
1506 &configChanged);
1507 if (errC == 0) {
1508 hTp->flags |= TPDEC_CONFIG_FOUND;
1509 } else {
1510 err = TRANSPORTDEC_PARSE_ERROR;
1511 goto bail;
1512 }
1513 }
1514
1515 if (err == TRANSPORTDEC_OK) {
1516 if ((i == 0) && configChanged) {
1517 int errC;
1518 errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
1519 &hTp->asc[0]);
1520 if (errC != 0) {
1521 err = TRANSPORTDEC_PARSE_ERROR;
1522 }
1523 }
1524 }
1525 }
1526 }
1527 hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
1528 break;
1529
1530 case TT_MP4_RAW:
1531 case TT_DRM:
1532 /* One Access Unit was filled into buffer.
1533 So get the length out of the buffer. */
1534 hTp->auLength[layer] = FDKgetValidBits(hBs);
1535 hTp->flags |= TPDEC_SYNCOK;
1536 break;
1537
1538 case TT_MP4_LATM_MCP0:
1539 case TT_MP4_LATM_MCP1:
1540 if (err == TRANSPORTDEC_OK) {
1541 int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
1542 err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
1543 NULL, NULL, &fConfigFound, NULL);
1544 if (fConfigFound) {
1545 hTp->flags |= TPDEC_CONFIG_FOUND;
1546 }
1547 }
1548 break;
1549
1550 case TT_MP4_ADTS:
1551 case TT_MP4_LOAS:
1552 err = transportDec_readStream(hTp, layer);
1553 break;
1554
1555 default:
1556 err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
1557 break;
1558 }
1559
1560 if (err == TRANSPORTDEC_OK) {
1561 hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
1562 } else {
1563 hTp->accessUnitAnchor[layer] = 0;
1564 }
1565
1566 bail:
1567 return err;
1568 }
1569
transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,const UINT layer,CSAudioSpecificConfig * asc)1570 TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
1571 const UINT layer,
1572 CSAudioSpecificConfig *asc) {
1573 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1574
1575 if (hTp != NULL) {
1576 *asc = hTp->asc[layer];
1577 err = TRANSPORTDEC_OK;
1578 } else {
1579 err = TRANSPORTDEC_INVALID_PARAMETER;
1580 }
1581 return err;
1582 }
1583
transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1584 INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
1585 const UINT layer) {
1586 INT bits;
1587
1588 if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
1589 bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
1590 if (bits >= 0) {
1591 bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
1592 }
1593 } else {
1594 bits = FDKgetValidBits(&hTp->bitStream[layer]);
1595 }
1596
1597 return bits;
1598 }
1599
transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1600 INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
1601 const UINT layer) {
1602 return hTp->auLength[layer];
1603 }
1604
transportDec_GetMissingAccessUnitCount(INT * pNAccessUnits,HANDLE_TRANSPORTDEC hTp)1605 TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
1606 INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
1607 *pNAccessUnits = hTp->missingAccessUnits;
1608
1609 return TRANSPORTDEC_OK;
1610 }
1611
1612 /* Inform the transportDec layer that reading of access unit has finished. */
transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp)1613 TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
1614 TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1615
1616 switch (hTp->transportFmt) {
1617 case TT_MP4_LOAS:
1618 case TT_MP4_LATM_MCP0:
1619 case TT_MP4_LATM_MCP1: {
1620 HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1621 if (hTp->numberOfRawDataBlocks == 0) {
1622 /* Read other data if available. */
1623 if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
1624 int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
1625
1626 if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
1627 FDKpushFor(hBs, otherDataLen);
1628 } else {
1629 /* Do byte align at the end of AudioMuxElement. */
1630 if (hTp->numberOfRawDataBlocks == 0) {
1631 FDKbyteAlign(hBs, hTp->globalFramePos);
1632 }
1633 return TRANSPORTDEC_NOT_ENOUGH_BITS;
1634 }
1635 }
1636 } else {
1637 /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
1638 then too many bits were read and obviously no more RawDataBlocks can
1639 be read. Set numberOfRawDataBlocks to zero to attempt a new sync
1640 attempt. */
1641 if ((INT)FDKgetValidBits(hBs) <= 0) {
1642 hTp->numberOfRawDataBlocks = 0;
1643 }
1644 }
1645 } break;
1646 default:
1647 break;
1648 }
1649
1650 err = transportDec_AdjustEndOfAccessUnit(hTp);
1651
1652 switch (hTp->transportFmt) {
1653 default:
1654 break;
1655 }
1656
1657 return err;
1658 }
1659
transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,const TPDEC_PARAM param,const INT value)1660 TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
1661 const TPDEC_PARAM param,
1662 const INT value) {
1663 TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1664
1665 if (hTp == NULL) {
1666 return TRANSPORTDEC_INVALID_PARAMETER;
1667 }
1668
1669 switch (param) {
1670 case TPDEC_PARAM_MINIMIZE_DELAY:
1671 if (value) {
1672 hTp->flags |= TPDEC_MINIMIZE_DELAY;
1673 } else {
1674 hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
1675 }
1676 break;
1677 case TPDEC_PARAM_EARLY_CONFIG:
1678 if (value) {
1679 hTp->flags |= TPDEC_EARLY_CONFIG;
1680 } else {
1681 hTp->flags &= ~TPDEC_EARLY_CONFIG;
1682 }
1683 break;
1684 case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
1685 if (value) {
1686 hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
1687 } else {
1688 hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
1689 }
1690 break;
1691 case TPDEC_PARAM_SET_BITRATE:
1692 hTp->avgBitRate = value;
1693 break;
1694 case TPDEC_PARAM_BURST_PERIOD:
1695 hTp->burstPeriod = value;
1696 break;
1697 case TPDEC_PARAM_RESET: {
1698 int i;
1699
1700 for (i = 0; i < (1 * 1); i++) {
1701 FDKresetBitbuffer(&hTp->bitStream[i]);
1702 hTp->auLength[i] = 0;
1703 hTp->accessUnitAnchor[i] = 0;
1704 }
1705 hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
1706 if (hTp->transportFmt != TT_MP4_ADIF) {
1707 hTp->flags &= ~TPDEC_CONFIG_FOUND;
1708 }
1709 hTp->remainder = 0;
1710 hTp->avgBitRate = 0;
1711 hTp->missingAccessUnits = 0;
1712 hTp->numberOfRawDataBlocks = 0;
1713 hTp->globalFramePos = 0;
1714 hTp->holdOffFrames = 0;
1715 } break;
1716 case TPDEC_PARAM_TARGETLAYOUT:
1717 hTp->targetLayout = value;
1718 break;
1719 case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
1720 hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
1721 break;
1722 case TPDEC_PARAM_USE_ELEM_SKIPPING:
1723 if (value) {
1724 hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
1725 } else {
1726 hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
1727 }
1728 break;
1729 }
1730
1731 return error;
1732 }
1733
transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp)1734 UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
1735 UINT nSubFrames = 0;
1736
1737 if (hTp == NULL) return 0;
1738
1739 if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
1740 hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
1741 nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
1742 else if (hTp->transportFmt == TT_MP4_ADTS)
1743 nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
1744
1745 return nSubFrames;
1746 }
1747
transportDec_Close(HANDLE_TRANSPORTDEC * phTp)1748 void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
1749 if (phTp != NULL) {
1750 if (*phTp != NULL) {
1751 FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
1752 FreeRam_TransportDecoder(phTp);
1753 }
1754 }
1755 }
1756
transportDec_GetLibInfo(LIB_INFO * info)1757 TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
1758 int i;
1759
1760 if (info == NULL) {
1761 return TRANSPORTDEC_UNKOWN_ERROR;
1762 }
1763
1764 /* search for next free tab */
1765 for (i = 0; i < FDK_MODULE_LAST; i++) {
1766 if (info[i].module_id == FDK_NONE) break;
1767 }
1768 if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
1769 info += i;
1770
1771 info->module_id = FDK_TPDEC;
1772 #ifdef SUPPRESS_BUILD_DATE_INFO
1773 info->build_date = "";
1774 info->build_time = "";
1775 #else
1776 info->build_date = __DATE__;
1777 info->build_time = __TIME__;
1778 #endif
1779 info->title = TP_LIB_TITLE;
1780 info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
1781 LIB_VERSION_STRING(info);
1782 info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
1783 CAPF_RAWPACKETS | CAPF_DRM;
1784
1785 return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
1786 }
1787
transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp,INT mBits)1788 int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
1789 switch (pTp->transportFmt) {
1790 case TT_MP4_ADTS:
1791 return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
1792 case TT_DRM:
1793 return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
1794 default:
1795 return -1;
1796 }
1797 }
1798
transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp,INT reg)1799 void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
1800 switch (pTp->transportFmt) {
1801 case TT_MP4_ADTS:
1802 adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
1803 break;
1804 case TT_DRM:
1805 drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
1806 break;
1807 default:
1808 break;
1809 }
1810 }
1811
transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)1812 TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
1813 switch (pTp->transportFmt) {
1814 case TT_MP4_ADTS:
1815 if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
1816 (pTp->parser.adts.bs.protection_absent == 0)) {
1817 transportDec_AdjustEndOfAccessUnit(pTp);
1818 }
1819 return adtsRead_CrcCheck(&pTp->parser.adts);
1820 case TT_DRM:
1821 return drmRead_CrcCheck(&pTp->parser.drm);
1822 default:
1823 return TRANSPORTDEC_OK;
1824 }
1825 }
1826
transportDec_DrmRawSdcAudioConfig_Check(UCHAR * conf,const UINT length)1827 TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
1828 const UINT length) {
1829 CSAudioSpecificConfig asc;
1830 FDK_BITSTREAM bs;
1831 HANDLE_FDK_BITSTREAM hBs = &bs;
1832
1833 FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);
1834
1835 TRANSPORTDEC_ERROR err =
1836 DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);
1837
1838 return err;
1839 }
1840