Coverage Report

Created: 2026-06-10 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libMpegTPDec/src/tpdec_latm.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2021 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):   Daniel Homm
98
99
   Description:
100
101
*******************************************************************************/
102
103
#include "tpdec_latm.h"
104
105
#include "FDK_bitstream.h"
106
107
5.03M
#define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l))
108
109
34.2k
static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) {
110
34.2k
  UCHAR bytesForValue = 0, tmp = 0;
111
34.2k
  int value = 0;
112
113
34.2k
  bytesForValue = (UCHAR)FDKreadBits(bs, 2);
114
115
102k
  for (UINT i = 0; i <= bytesForValue; i++) {
116
68.7k
    value <<= 8;
117
68.7k
    tmp = (UCHAR)FDKreadBits(bs, 8);
118
68.7k
    value += tmp;
119
68.7k
  }
120
121
34.2k
  return value;
122
34.2k
}
123
124
static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement(
125
    HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent,
126
    CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
127
568k
    int *pfConfigFound) {
128
568k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
129
130
568k
  if (m_muxConfigPresent) {
131
568k
    pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1);
132
133
568k
    if (!pLatmDemux->m_useSameStreamMux) {
134
538k
      int i;
135
538k
      UCHAR configChanged = 0;
136
538k
      UCHAR configMode = 0;
137
138
538k
      FDK_BITSTREAM bsAnchor;
139
140
538k
      FDK_BITSTREAM bsAnchorDummyParse;
141
142
538k
      if (!pLatmDemux->applyAsc) {
143
106k
        bsAnchorDummyParse = *bs;
144
106k
        pLatmDemux->newCfgHasAudioPreRoll = 0;
145
        /* do dummy-parsing of ASC to determine if there is an audioPreRoll */
146
106k
        configMode |= AC_CM_DET_CFG_CHANGE;
147
106k
        if (TRANSPORTDEC_OK !=
148
106k
            (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
149
106k
                 bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
150
106k
                 configMode, configChanged))) {
151
3.80k
          goto bail;
152
3.80k
        }
153
154
        /* Allow flushing only when audioPreroll functionality is enabled in
155
         * current and new config otherwise the new config can be applied
156
         * immediately. */
157
103k
        if (pAsc->m_sc.m_usacConfig.element[0]
158
103k
                .extElement.usacExtElementHasAudioPreRoll &&
159
594
            pLatmDemux->newCfgHasAudioPreRoll) {
160
256
          pLatmDemux->newCfgHasAudioPreRoll = 0;
161
          /* with audioPreRoll we must flush before applying new cfg */
162
256
          pLatmDemux->applyAsc = 0;
163
102k
        } else {
164
102k
          *bs = bsAnchorDummyParse;
165
102k
          pLatmDemux->applyAsc = 1; /* apply new config immediate */
166
102k
        }
167
103k
      }
168
169
535k
      if (pLatmDemux->applyAsc) {
170
1.21M
        for (i = 0; i < 2; i++) {
171
880k
          configMode = 0;
172
173
880k
          if (i == 0) {
174
534k
            configMode |= AC_CM_DET_CFG_CHANGE;
175
534k
            bsAnchor = *bs;
176
534k
          } else {
177
345k
            configMode |= AC_CM_ALLOC_MEM;
178
345k
            *bs = bsAnchor;
179
345k
          }
180
181
880k
          if (TRANSPORTDEC_OK !=
182
880k
              (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
183
880k
                   bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
184
880k
                   configMode, configChanged))) {
185
199k
            goto bail;
186
199k
          }
187
188
681k
          if (ErrorStatus == TRANSPORTDEC_OK) {
189
681k
            if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged ||
190
256k
                             pAsc->SacConfigChanged)) {
191
256k
              int errC;
192
193
256k
              configChanged = 1;
194
256k
              errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData,
195
256k
                                                pAsc);
196
256k
              if (errC != 0) {
197
0
                ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
198
0
                goto bail;
199
0
              }
200
256k
            }
201
681k
          }
202
681k
        }
203
534k
      }
204
535k
    }
205
568k
  }
206
207
  /* If there was no configuration read, its not possible to parse
208
   * PayloadLengthInfo below. */
209
365k
  if (!*pfConfigFound) {
210
26.3k
    ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
211
26.3k
    goto bail;
212
26.3k
  }
213
214
339k
  if (pLatmDemux->m_AudioMuxVersionA == 0) {
215
    /* Do only once per call, because parsing and decoding is done in-line. */
216
339k
    if (TRANSPORTDEC_OK !=
217
339k
        (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) {
218
214k
      *pfConfigFound = 0;
219
214k
      goto bail;
220
214k
    }
221
339k
  } else {
222
    /* audioMuxVersionA > 0 is reserved for future extensions */
223
0
    ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
224
0
    *pfConfigFound = 0;
225
0
    goto bail;
226
0
  }
227
228
568k
bail:
229
568k
  if (ErrorStatus != TRANSPORTDEC_OK) {
230
443k
    pLatmDemux->applyAsc = 1;
231
443k
  }
232
233
568k
  return (ErrorStatus);
234
339k
}
235
236
TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
237
                                   CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
238
                                   CSTpCallBacks *pTpDecCallbacks,
239
                                   CSAudioSpecificConfig *pAsc,
240
                                   int *pfConfigFound,
241
569k
                                   const INT ignoreBufferFullness) {
242
569k
  UINT cntBits;
243
569k
  UINT cmpBufferFullness;
244
569k
  UINT audioMuxLengthBytesLast = 0;
245
569k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
246
247
569k
  cntBits = FDKgetValidBits(bs);
248
249
569k
  if ((INT)cntBits < MIN_LATM_HEADERLENGTH) {
250
254
    return TRANSPORTDEC_NOT_ENOUGH_BITS;
251
254
  }
252
253
568k
  if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement(
254
568k
                              bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0),
255
568k
                              pTpDecCallbacks, pAsc, pfConfigFound)))
256
443k
    return (ErrorStatus);
257
258
125k
  if (!ignoreBufferFullness) {
259
43.1k
    cmpBufferFullness =
260
43.1k
        24 + audioMuxLengthBytesLast * 8 +
261
43.1k
        pLatmDemux->m_linfo[0][0].m_bufferFullness *
262
43.1k
            pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32;
263
264
    /* evaluate buffer fullness */
265
266
43.1k
    if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) {
267
42.5k
      if (!pLatmDemux->BufferFullnessAchieved) {
268
29.2k
        if (cntBits < cmpBufferFullness) {
269
          /* condition for start of decoding is not fulfilled */
270
271
          /* the current frame will not be decoded */
272
97
          return TRANSPORTDEC_NOT_ENOUGH_BITS;
273
29.1k
        } else {
274
29.1k
          pLatmDemux->BufferFullnessAchieved = 1;
275
29.1k
        }
276
29.2k
      }
277
42.5k
    }
278
43.1k
  }
279
280
125k
  return (ErrorStatus);
281
125k
}
282
283
TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
284
    HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
285
    CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
286
987k
    int *pfConfigFound, UCHAR configMode, UCHAR configChanged) {
287
987k
  CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing,
288
                                     after that new config can be parsed */
289
987k
  CSAudioSpecificConfig *pAscDummy;
290
987k
  pAscDummy = &ascDummy;
291
987k
  pLatmDemux->usacExplicitCfgChanged = 0;
292
987k
  LATM_LAYER_INFO *p_linfo = NULL;
293
987k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
294
987k
  UCHAR updateConfig[1 * 1] = {0};
295
296
987k
  pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1);
297
298
987k
  if (pLatmDemux->m_AudioMuxVersion == 0) {
299
964k
    pLatmDemux->m_AudioMuxVersionA = 0;
300
964k
  } else {
301
22.9k
    pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1);
302
22.9k
  }
303
304
987k
  if (pLatmDemux->m_AudioMuxVersionA == 0) {
305
984k
    if (pLatmDemux->m_AudioMuxVersion == 1) {
306
19.8k
      pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs);
307
19.8k
    }
308
984k
    pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1);
309
984k
    pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1;
310
984k
    pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1;
311
312
984k
    if (pLatmDemux->m_numProgram > LATM_MAX_PROG) {
313
20.8k
      ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
314
20.8k
      goto bail;
315
20.8k
    }
316
317
963k
    int idCnt = 0;
318
1.76M
    for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
319
963k
      pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1;
320
963k
      if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) {
321
7.14k
        ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
322
7.14k
        goto bail;
323
7.14k
      }
324
325
1.76M
      for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
326
956k
        int useSameConfig;
327
956k
        p_linfo = &pLatmDemux->m_linfo[prog][lay];
328
329
956k
        p_linfo->m_streamID = idCnt++;
330
956k
        p_linfo->m_frameLengthInBits = 0;
331
332
956k
        if ((prog == 0) && (lay == 0)) {
333
956k
          useSameConfig = 0;
334
956k
        } else {
335
0
          useSameConfig = FDKreadBits(bs, 1);
336
0
        }
337
338
956k
        if (useSameConfig) {
339
0
          if (lay > 0) {
340
0
            FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)],
341
0
                      &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)],
342
0
                      sizeof(CSAudioSpecificConfig));
343
0
          } else {
344
0
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
345
0
            goto bail;
346
0
          }
347
956k
        } else {
348
956k
          UINT usacConfigLengthPrev = 0;
349
956k
          UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN];
350
351
956k
          if (!(pLatmDemux->applyAsc) &&
352
105k
              (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) {
353
38.9k
            usacConfigLengthPrev =
354
38.9k
                (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)]
355
38.9k
                           .m_sc.m_usacConfig.UsacConfigBits +
356
38.9k
                       7) >>
357
38.9k
                3; /* store previous USAC config length */
358
38.9k
            if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) {
359
0
              ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
360
0
              goto bail;
361
0
            }
362
38.9k
            FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN);
363
38.9k
            FDKmemcpy(
364
38.9k
                usacConfigPrev,
365
38.9k
                &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig,
366
38.9k
                usacConfigLengthPrev); /* store previous USAC config */
367
38.9k
          }
368
956k
          if (pLatmDemux->m_AudioMuxVersion == 1) {
369
13.3k
            FDK_BITSTREAM tmpBs;
370
13.3k
            INT ascLen = 0;
371
13.3k
            ascLen = CLatmDemux_GetValue(bs);
372
            /* The ascLen could be wrong, so check if validBits<=bufBits*/
373
13.3k
            if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) {
374
1.26k
              ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
375
1.26k
              goto bail;
376
1.26k
            }
377
12.0k
            FDKsyncCache(bs);
378
12.0k
            tmpBs = *bs;
379
12.0k
            tmpBs.hBitBuf.ValidBits = ascLen;
380
381
            /* Read ASC */
382
12.0k
            if (pLatmDemux->applyAsc) {
383
11.6k
              if (TRANSPORTDEC_OK !=
384
11.6k
                  (ErrorStatus = AudioSpecificConfig_Parse(
385
11.6k
                       &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1,
386
11.6k
                       pTpDecCallbacks, configMode, configChanged,
387
11.6k
                       AOT_NULL_OBJECT)))
388
3.82k
                goto bail;
389
11.6k
            } else {
390
377
              if (TRANSPORTDEC_OK !=
391
377
                  (ErrorStatus = AudioSpecificConfig_Parse(
392
377
                       pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode,
393
377
                       configChanged, AOT_NULL_OBJECT)))
394
238
                goto bail;
395
377
            }
396
397
            /* The field p_linfo->m_ascLen could be wrong, so check if */
398
7.97k
            if (0 > (INT)FDKgetValidBits(&tmpBs)) {
399
3.02k
              ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
400
3.02k
              goto bail;
401
3.02k
            }
402
4.94k
            FDKpushFor(bs, ascLen); /* position bitstream after ASC */
403
943k
          } else {
404
            /* Read ASC */
405
943k
            if (pLatmDemux->applyAsc) {
406
837k
              if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse(
407
837k
                                          &pAsc[TPDEC_TRACKINDEX(prog, lay)],
408
837k
                                          bs, 0, pTpDecCallbacks, configMode,
409
837k
                                          configChanged, AOT_NULL_OBJECT)))
410
128k
                goto bail;
411
837k
            } else {
412
105k
              if (TRANSPORTDEC_OK !=
413
105k
                  (ErrorStatus = AudioSpecificConfig_Parse(
414
105k
                       pAscDummy, bs, 0, pTpDecCallbacks, configMode,
415
105k
                       configChanged, AOT_NULL_OBJECT)))
416
2.47k
                goto bail;
417
105k
            }
418
943k
          }
419
817k
          if (!pLatmDemux->applyAsc) {
420
103k
            updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0;
421
713k
          } else {
422
713k
            updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1;
423
713k
          }
424
425
817k
          if (!pLatmDemux->applyAsc) {
426
103k
            if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
427
103k
                AOT_USAC) { /* flush in case SMC has changed */
428
38.3k
              const UINT usacConfigLength =
429
38.3k
                  (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3;
430
38.3k
              if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) {
431
0
                ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
432
0
                goto bail;
433
0
              }
434
38.3k
              if (usacConfigLength != usacConfigLengthPrev) {
435
978
                FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
436
978
                                 .m_sc.m_usacConfig.UsacConfig,
437
978
                            TP_USAC_MAX_CONFIG_LEN);
438
978
                FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
439
978
                               .m_sc.m_usacConfig.UsacConfig,
440
978
                          &pAscDummy->m_sc.m_usacConfig.UsacConfig,
441
978
                          usacConfigLength); /* store new USAC config */
442
978
                pAsc[TPDEC_TRACKINDEX(prog, lay)]
443
978
                    .m_sc.m_usacConfig.UsacConfigBits =
444
978
                    pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
445
978
                pLatmDemux->usacExplicitCfgChanged = 1;
446
37.3k
              } else {
447
37.3k
                if (FDKmemcmp(usacConfigPrev,
448
37.3k
                              pAscDummy->m_sc.m_usacConfig.UsacConfig,
449
37.3k
                              usacConfigLengthPrev)) {
450
20.9k
                  FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
451
20.9k
                                   .m_sc.m_usacConfig.UsacConfig,
452
20.9k
                              TP_USAC_MAX_CONFIG_LEN);
453
20.9k
                  FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
454
20.9k
                                 .m_sc.m_usacConfig.UsacConfig,
455
20.9k
                            &pAscDummy->m_sc.m_usacConfig.UsacConfig,
456
20.9k
                            usacConfigLength); /* store new USAC config */
457
20.9k
                  pAsc[TPDEC_TRACKINDEX(prog, lay)]
458
20.9k
                      .m_sc.m_usacConfig.UsacConfigBits =
459
20.9k
                      pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
460
20.9k
                  pLatmDemux->usacExplicitCfgChanged = 1;
461
20.9k
                }
462
37.3k
              }
463
464
38.3k
              if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
465
38.3k
                      .m_sc.m_usacConfig.m_usacNumElements) {
466
38.3k
                if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
467
38.3k
                        .m_sc.m_usacConfig.element[0]
468
38.3k
                        .extElement.usacExtElementHasAudioPreRoll) {
469
563
                  pLatmDemux->newCfgHasAudioPreRoll =
470
563
                      1; /* if dummy parsed cfg has audioPreRoll we first flush
471
                            before applying new cfg */
472
563
                }
473
38.3k
              }
474
38.3k
            }
475
103k
          }
476
817k
        }
477
478
817k
        p_linfo->m_frameLengthType = FDKreadBits(bs, 3);
479
817k
        switch (p_linfo->m_frameLengthType) {
480
773k
          case 0:
481
773k
            p_linfo->m_bufferFullness = FDKreadBits(bs, 8);
482
483
773k
            if (!pLatmDemux->m_allStreamsSameTimeFraming) {
484
304k
              if ((lay > 0) &&
485
0
                  (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL ||
486
0
                   pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
487
0
                       AOT_ER_AAC_SCAL) &&
488
0
                  (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP ||
489
0
                   pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot ==
490
0
                       AOT_ER_CELP)) { /* The layer maybe
491
                                          ignored later so
492
                                          read it anyway: */
493
0
                /* coreFrameOffset = */ FDKreadBits(bs, 6);
494
0
              }
495
304k
            }
496
773k
            break;
497
31.1k
          case 1:
498
31.1k
            p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9);
499
31.1k
            break;
500
1.22k
          case 3:
501
3.75k
          case 4:
502
4.86k
          case 5:
503
            /* CELP */
504
7.88k
          case 6:
505
9.93k
          case 7:
506
            /* HVXC */
507
12.5k
          default:
508
12.5k
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
509
12.5k
            goto bail;
510
817k
        } /* switch framelengthtype*/
511
512
817k
      } /* layer loop */
513
956k
    }   /* prog loop */
514
515
804k
    pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1);
516
804k
    pLatmDemux->m_otherDataLength = 0;
517
518
804k
    if (pLatmDemux->m_otherDataPresent) {
519
299k
      if (pLatmDemux->m_AudioMuxVersion == 1) {
520
1.03k
        pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs);
521
298k
      } else {
522
298k
        int otherDataLenEsc = 0;
523
467k
        do {
524
467k
          pLatmDemux->m_otherDataLength <<= 8;  // *= 256
525
467k
          otherDataLenEsc = FDKreadBits(bs, 1);
526
467k
          pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8);
527
467k
        } while (otherDataLenEsc);
528
298k
      }
529
299k
      if (pLatmDemux->m_audioMuxLengthBytes <
530
299k
          (pLatmDemux->m_otherDataLength >> 3)) {
531
3.33k
        ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
532
3.33k
        goto bail;
533
3.33k
      }
534
299k
    }
535
536
801k
    pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1);
537
538
801k
    if (pLatmDemux->m_crcCheckPresent) {
539
431k
      FDKreadBits(bs, 8);
540
431k
    }
541
542
801k
  } else {
543
    /* audioMuxVersionA > 0 is reserved for future extensions */
544
3.00k
    ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
545
3.00k
  }
546
547
  /* Configure source decoder: */
548
804k
  if (ErrorStatus == TRANSPORTDEC_OK) {
549
801k
    UINT prog;
550
1.58M
    for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
551
801k
      UINT lay;
552
1.58M
      for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
553
801k
        if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) {
554
698k
          int cbError;
555
698k
          cbError = pTpDecCallbacks->cbUpdateConfig(
556
698k
              pTpDecCallbacks->cbUpdateConfigData,
557
698k
              &pAsc[TPDEC_TRACKINDEX(prog, lay)],
558
698k
              pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode,
559
698k
              &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged);
560
698k
          if (cbError == TRANSPORTDEC_NEED_TO_RESTART) {
561
0
            *pfConfigFound = 0;
562
0
            ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART;
563
0
            goto bail;
564
0
          }
565
698k
          if (cbError != 0) {
566
16.8k
            *pfConfigFound = 0;
567
16.8k
            if (lay == 0) {
568
16.8k
              ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
569
16.8k
              goto bail;
570
16.8k
            }
571
681k
          } else {
572
681k
            *pfConfigFound = 1;
573
681k
          }
574
698k
        } else {
575
103k
          *pfConfigFound = 1;
576
103k
        }
577
801k
      }
578
801k
    }
579
801k
  }
580
581
987k
bail:
582
987k
  if (ErrorStatus != TRANSPORTDEC_OK) {
583
202k
    UCHAR applyAsc = pLatmDemux->applyAsc;
584
202k
    FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */
585
202k
    pLatmDemux->applyAsc = applyAsc;
586
784k
  } else {
587
    /* no error and config parsing is finished */
588
784k
    if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0;
589
784k
  }
590
591
987k
  return (ErrorStatus);
592
804k
}
593
594
452k
static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
595
452k
  int len = 0, tmp = 255;
596
452k
  int validBytes = (int)FDKgetValidBits(bs) >> 3;
597
598
968k
  while (tmp == 255 && validBytes-- > 0) {
599
516k
    tmp = (int)FDKreadBits(bs, 8);
600
516k
    len += tmp;
601
516k
  }
602
603
452k
  return ((tmp == 255) ? -1 : (len << 3));
604
452k
}
605
606
TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
607
601k
                                                    CLatmDemux *pLatmDemux) {
608
601k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
609
601k
  int totalPayloadBits = 0;
610
611
601k
  if (pLatmDemux->m_allStreamsSameTimeFraming == 1) {
612
460k
    FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG);
613
910k
    for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
614
460k
      FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER);
615
910k
      for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
616
460k
        LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
617
460k
        int auChunkLengthInfo = 0;
618
619
460k
        switch (p_linfo->m_frameLengthType) {
620
452k
          case 0:
621
452k
            auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs);
622
452k
            if (auChunkLengthInfo >= 0) {
623
449k
              p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo;
624
449k
              totalPayloadBits += p_linfo->m_frameLengthInBits;
625
449k
            } else {
626
2.86k
              return TRANSPORTDEC_PARSE_ERROR;
627
2.86k
            }
628
449k
            break;
629
449k
          case 3:
630
0
          case 5:
631
0
          case 7:
632
8.02k
          default:
633
8.02k
            return TRANSPORTDEC_PARSE_ERROR;  // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE;
634
460k
        }
635
460k
      }
636
460k
    }
637
460k
  } else {
638
141k
    ErrorStatus = TRANSPORTDEC_PARSE_ERROR;  // AAC_DEC_LATM_TIMEFRAMING;
639
141k
  }
640
591k
  if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 &&
641
568k
      totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) {
642
65.2k
    return TRANSPORTDEC_PARSE_ERROR;
643
65.2k
  }
644
645
525k
  return (ErrorStatus);
646
591k
}
647
648
UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
649
358k
                                     const UINT layer) {
650
358k
  UINT nFrameLenBits = 0;
651
358k
  if (prog < pLatmDemux->m_numProgram) {
652
358k
    if (layer < pLatmDemux->m_numLayer[prog]) {
653
358k
      nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits;
654
358k
    }
655
358k
  }
656
358k
  return nFrameLenBits;
657
358k
}
658
659
8.57k
UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) {
660
8.57k
  return pLatmDemux->m_otherDataPresent ? 1 : 0;
661
8.57k
}
662
663
2.48k
UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) {
664
2.48k
  return pLatmDemux->m_otherDataLength;
665
2.48k
}
666
667
125k
UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) {
668
125k
  return pLatmDemux->m_noSubFrames;
669
125k
}
670
671
716k
UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) {
672
716k
  UINT numLayer = 0;
673
716k
  if (prog < pLatmDemux->m_numProgram) {
674
716k
    numLayer = pLatmDemux->m_numLayer[prog];
675
716k
  }
676
716k
  return numLayer;
677
716k
}