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