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