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