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