Coverage Report

Created: 2026-08-13 06:43

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
6.58M
#define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l))
108
109
144k
static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) {
110
144k
  UCHAR bytesForValue = 0, tmp = 0;
111
144k
  int value = 0;
112
113
144k
  bytesForValue = (UCHAR)FDKreadBits(bs, 2);
114
115
450k
  for (UINT i = 0; i <= bytesForValue; i++) {
116
305k
    value <<= 8;
117
305k
    tmp = (UCHAR)FDKreadBits(bs, 8);
118
305k
    value += tmp;
119
305k
  }
120
121
144k
  return value;
122
144k
}
123
124
static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement(
125
    HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent,
126
    CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
127
818k
    int *pfConfigFound) {
128
818k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
129
130
818k
  if (m_muxConfigPresent) {
131
818k
    pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1);
132
133
818k
    if (!pLatmDemux->m_useSameStreamMux) {
134
787k
      int i;
135
787k
      UCHAR configChanged = 0;
136
787k
      UCHAR configMode = 0;
137
138
787k
      FDK_BITSTREAM bsAnchor;
139
140
787k
      FDK_BITSTREAM bsAnchorDummyParse;
141
142
787k
      if (!pLatmDemux->applyAsc) {
143
246k
        bsAnchorDummyParse = *bs;
144
246k
        pLatmDemux->newCfgHasAudioPreRoll = 0;
145
        /* do dummy-parsing of ASC to determine if there is an audioPreRoll */
146
246k
        configMode |= AC_CM_DET_CFG_CHANGE;
147
246k
        if (TRANSPORTDEC_OK !=
148
246k
            (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
149
246k
                 bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
150
246k
                 configMode, configChanged))) {
151
124k
          goto bail;
152
124k
        }
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
121k
        if (pAsc->m_sc.m_usacConfig.element[0]
158
121k
                .extElement.usacExtElementHasAudioPreRoll &&
159
782
            pLatmDemux->newCfgHasAudioPreRoll) {
160
379
          pLatmDemux->newCfgHasAudioPreRoll = 0;
161
          /* with audioPreRoll we must flush before applying new cfg */
162
379
          pLatmDemux->applyAsc = 0;
163
120k
        } else {
164
120k
          *bs = bsAnchorDummyParse;
165
120k
          pLatmDemux->applyAsc = 1; /* apply new config immediate */
166
120k
        }
167
121k
      }
168
169
662k
      if (pLatmDemux->applyAsc) {
170
1.56M
        for (i = 0; i < 2; i++) {
171
1.11M
          configMode = 0;
172
173
1.11M
          if (i == 0) {
174
662k
            configMode |= AC_CM_DET_CFG_CHANGE;
175
662k
            bsAnchor = *bs;
176
662k
          } else {
177
455k
            configMode |= AC_CM_ALLOC_MEM;
178
455k
            *bs = bsAnchor;
179
455k
          }
180
181
1.11M
          if (TRANSPORTDEC_OK !=
182
1.11M
              (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
183
1.11M
                   bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
184
1.11M
                   configMode, configChanged))) {
185
219k
            goto bail;
186
219k
          }
187
188
898k
          if (ErrorStatus == TRANSPORTDEC_OK) {
189
898k
            if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged ||
190
233k
                             pAsc->SacConfigChanged)) {
191
233k
              int errC;
192
193
233k
              configChanged = 1;
194
233k
              errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData,
195
233k
                                                pAsc);
196
233k
              if (errC != 0) {
197
0
                ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
198
0
                goto bail;
199
0
              }
200
233k
            }
201
898k
          }
202
898k
        }
203
662k
      }
204
662k
    }
205
818k
  }
206
207
  /* If there was no configuration read, its not possible to parse
208
   * PayloadLengthInfo below. */
209
473k
  if (!*pfConfigFound) {
210
21.2k
    ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
211
21.2k
    goto bail;
212
21.2k
  }
213
214
452k
  if (pLatmDemux->m_AudioMuxVersionA == 0) {
215
    /* Do only once per call, because parsing and decoding is done in-line. */
216
452k
    if (TRANSPORTDEC_OK !=
217
452k
        (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) {
218
187k
      *pfConfigFound = 0;
219
187k
      goto bail;
220
187k
    }
221
452k
  } 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
818k
bail:
229
818k
  if (ErrorStatus != TRANSPORTDEC_OK) {
230
553k
    pLatmDemux->applyAsc = 1;
231
553k
  }
232
233
818k
  return (ErrorStatus);
234
452k
}
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
818k
                                   const INT ignoreBufferFullness) {
242
818k
  UINT cntBits;
243
818k
  UINT cmpBufferFullness;
244
818k
  UINT audioMuxLengthBytesLast = 0;
245
818k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
246
247
818k
  cntBits = FDKgetValidBits(bs);
248
249
818k
  if ((INT)cntBits < MIN_LATM_HEADERLENGTH) {
250
257
    return TRANSPORTDEC_NOT_ENOUGH_BITS;
251
257
  }
252
253
818k
  if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement(
254
818k
                              bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0),
255
818k
                              pTpDecCallbacks, pAsc, pfConfigFound)))
256
553k
    return (ErrorStatus);
257
258
265k
  if (!ignoreBufferFullness) {
259
177k
    cmpBufferFullness =
260
177k
        24 + audioMuxLengthBytesLast * 8 +
261
177k
        pLatmDemux->m_linfo[0][0].m_bufferFullness *
262
177k
            pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32;
263
264
    /* evaluate buffer fullness */
265
266
177k
    if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) {
267
176k
      if (!pLatmDemux->BufferFullnessAchieved) {
268
152k
        if (cntBits < cmpBufferFullness) {
269
          /* condition for start of decoding is not fulfilled */
270
271
          /* the current frame will not be decoded */
272
111
          return TRANSPORTDEC_NOT_ENOUGH_BITS;
273
151k
        } else {
274
151k
          pLatmDemux->BufferFullnessAchieved = 1;
275
151k
        }
276
152k
      }
277
176k
    }
278
177k
  }
279
280
265k
  return (ErrorStatus);
281
265k
}
282
283
TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
284
    HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
285
    CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
286
1.36M
    int *pfConfigFound, UCHAR configMode, UCHAR configChanged) {
287
1.36M
  CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing,
288
                                     after that new config can be parsed */
289
1.36M
  CSAudioSpecificConfig *pAscDummy;
290
1.36M
  pAscDummy = &ascDummy;
291
1.36M
  pLatmDemux->usacExplicitCfgChanged = 0;
292
1.36M
  LATM_LAYER_INFO *p_linfo = NULL;
293
1.36M
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
294
1.36M
  UCHAR updateConfig[1 * 1] = {0};
295
296
1.36M
  pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1);
297
298
1.36M
  if (pLatmDemux->m_AudioMuxVersion == 0) {
299
1.28M
    pLatmDemux->m_AudioMuxVersionA = 0;
300
1.28M
  } else {
301
77.5k
    pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1);
302
77.5k
  }
303
304
1.36M
  if (pLatmDemux->m_AudioMuxVersionA == 0) {
305
1.36M
    if (pLatmDemux->m_AudioMuxVersion == 1) {
306
76.3k
      pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs);
307
76.3k
    }
308
1.36M
    pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1);
309
1.36M
    pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1;
310
1.36M
    pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1;
311
312
1.36M
    if (pLatmDemux->m_numProgram > LATM_MAX_PROG) {
313
146k
      ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
314
146k
      goto bail;
315
146k
    }
316
317
1.21M
    int idCnt = 0;
318
2.26M
    for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
319
1.21M
      pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1;
320
1.21M
      if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) {
321
7.94k
        ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
322
7.94k
        goto bail;
323
7.94k
      }
324
325
2.25M
      for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
326
1.20M
        int useSameConfig;
327
1.20M
        p_linfo = &pLatmDemux->m_linfo[prog][lay];
328
329
1.20M
        p_linfo->m_streamID = idCnt++;
330
1.20M
        p_linfo->m_frameLengthInBits = 0;
331
332
1.20M
        if ((prog == 0) && (lay == 0)) {
333
1.20M
          useSameConfig = 0;
334
1.20M
        } else {
335
0
          useSameConfig = FDKreadBits(bs, 1);
336
0
        }
337
338
1.20M
        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
1.20M
        } else {
348
1.20M
          UINT usacConfigLengthPrev = 0;
349
1.20M
          UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN];
350
351
1.20M
          if (!(pLatmDemux->applyAsc) &&
352
132k
              (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) {
353
43.1k
            usacConfigLengthPrev =
354
43.1k
                (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)]
355
43.1k
                           .m_sc.m_usacConfig.UsacConfigBits +
356
43.1k
                       7) >>
357
43.1k
                3; /* store previous USAC config length */
358
43.1k
            if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) {
359
0
              ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
360
0
              goto bail;
361
0
            }
362
43.1k
            FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN);
363
43.1k
            FDKmemcpy(
364
43.1k
                usacConfigPrev,
365
43.1k
                &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig,
366
43.1k
                usacConfigLengthPrev); /* store previous USAC config */
367
43.1k
          }
368
1.20M
          if (pLatmDemux->m_AudioMuxVersion == 1) {
369
66.7k
            FDK_BITSTREAM tmpBs;
370
66.7k
            INT ascLen = 0;
371
66.7k
            ascLen = CLatmDemux_GetValue(bs);
372
            /* The ascLen could be wrong, so check if validBits<=bufBits*/
373
66.7k
            if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) {
374
7.46k
              ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
375
7.46k
              goto bail;
376
7.46k
            }
377
59.2k
            FDKsyncCache(bs);
378
59.2k
            tmpBs = *bs;
379
59.2k
            tmpBs.hBitBuf.ValidBits = ascLen;
380
381
            /* Read ASC */
382
59.2k
            if (pLatmDemux->applyAsc) {
383
44.5k
              if (TRANSPORTDEC_OK !=
384
44.5k
                  (ErrorStatus = AudioSpecificConfig_Parse(
385
44.5k
                       &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1,
386
44.5k
                       pTpDecCallbacks, configMode, configChanged,
387
44.5k
                       AOT_NULL_OBJECT)))
388
4.81k
                goto bail;
389
44.5k
            } else {
390
14.7k
              if (TRANSPORTDEC_OK !=
391
14.7k
                  (ErrorStatus = AudioSpecificConfig_Parse(
392
14.7k
                       pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode,
393
14.7k
                       configChanged, AOT_NULL_OBJECT)))
394
1.12k
                goto bail;
395
14.7k
            }
396
397
            /* The field p_linfo->m_ascLen could be wrong, so check if */
398
53.3k
            if (0 > (INT)FDKgetValidBits(&tmpBs)) {
399
3.02k
              ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
400
3.02k
              goto bail;
401
3.02k
            }
402
50.3k
            FDKpushFor(bs, ascLen); /* position bitstream after ASC */
403
1.14M
          } else {
404
            /* Read ASC */
405
1.14M
            if (pLatmDemux->applyAsc) {
406
1.02M
              if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse(
407
1.02M
                                          &pAsc[TPDEC_TRACKINDEX(prog, lay)],
408
1.02M
                                          bs, 0, pTpDecCallbacks, configMode,
409
1.02M
                                          configChanged, AOT_NULL_OBJECT)))
410
130k
                goto bail;
411
1.02M
            } else {
412
117k
              if (TRANSPORTDEC_OK !=
413
117k
                  (ErrorStatus = AudioSpecificConfig_Parse(
414
117k
                       pAscDummy, bs, 0, pTpDecCallbacks, configMode,
415
117k
                       configChanged, AOT_NULL_OBJECT)))
416
2.72k
                goto bail;
417
117k
            }
418
1.14M
          }
419
1.05M
          if (!pLatmDemux->applyAsc) {
420
128k
            updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0;
421
930k
          } else {
422
930k
            updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1;
423
930k
          }
424
425
1.05M
          if (!pLatmDemux->applyAsc) {
426
128k
            if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
427
128k
                AOT_USAC) { /* flush in case SMC has changed */
428
42.3k
              const UINT usacConfigLength =
429
42.3k
                  (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3;
430
42.3k
              if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) {
431
0
                ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
432
0
                goto bail;
433
0
              }
434
42.3k
              if (usacConfigLength != usacConfigLengthPrev) {
435
1.28k
                FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
436
1.28k
                                 .m_sc.m_usacConfig.UsacConfig,
437
1.28k
                            TP_USAC_MAX_CONFIG_LEN);
438
1.28k
                FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
439
1.28k
                               .m_sc.m_usacConfig.UsacConfig,
440
1.28k
                          &pAscDummy->m_sc.m_usacConfig.UsacConfig,
441
1.28k
                          usacConfigLength); /* store new USAC config */
442
1.28k
                pAsc[TPDEC_TRACKINDEX(prog, lay)]
443
1.28k
                    .m_sc.m_usacConfig.UsacConfigBits =
444
1.28k
                    pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
445
1.28k
                pLatmDemux->usacExplicitCfgChanged = 1;
446
41.0k
              } else {
447
41.0k
                if (FDKmemcmp(usacConfigPrev,
448
41.0k
                              pAscDummy->m_sc.m_usacConfig.UsacConfig,
449
41.0k
                              usacConfigLengthPrev)) {
450
22.6k
                  FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
451
22.6k
                                   .m_sc.m_usacConfig.UsacConfig,
452
22.6k
                              TP_USAC_MAX_CONFIG_LEN);
453
22.6k
                  FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
454
22.6k
                                 .m_sc.m_usacConfig.UsacConfig,
455
22.6k
                            &pAscDummy->m_sc.m_usacConfig.UsacConfig,
456
22.6k
                            usacConfigLength); /* store new USAC config */
457
22.6k
                  pAsc[TPDEC_TRACKINDEX(prog, lay)]
458
22.6k
                      .m_sc.m_usacConfig.UsacConfigBits =
459
22.6k
                      pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
460
22.6k
                  pLatmDemux->usacExplicitCfgChanged = 1;
461
22.6k
                }
462
41.0k
              }
463
464
42.3k
              if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
465
42.3k
                      .m_sc.m_usacConfig.m_usacNumElements) {
466
42.3k
                if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
467
42.3k
                        .m_sc.m_usacConfig.element[0]
468
42.3k
                        .extElement.usacExtElementHasAudioPreRoll) {
469
768
                  pLatmDemux->newCfgHasAudioPreRoll =
470
768
                      1; /* if dummy parsed cfg has audioPreRoll we first flush
471
                            before applying new cfg */
472
768
                }
473
42.3k
              }
474
42.3k
            }
475
128k
          }
476
1.05M
        }
477
478
1.05M
        p_linfo->m_frameLengthType = FDKreadBits(bs, 3);
479
1.05M
        switch (p_linfo->m_frameLengthType) {
480
1.00M
          case 0:
481
1.00M
            p_linfo->m_bufferFullness = FDKreadBits(bs, 8);
482
483
1.00M
            if (!pLatmDemux->m_allStreamsSameTimeFraming) {
484
227k
              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
227k
            }
496
1.00M
            break;
497
40.2k
          case 1:
498
40.2k
            p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9);
499
40.2k
            break;
500
2.78k
          case 3:
501
4.78k
          case 4:
502
5.73k
          case 5:
503
            /* CELP */
504
6.77k
          case 6:
505
10.3k
          case 7:
506
            /* HVXC */
507
13.9k
          default:
508
13.9k
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
509
13.9k
            goto bail;
510
1.05M
        } /* switch framelengthtype*/
511
512
1.05M
      } /* layer loop */
513
1.20M
    }   /* prog loop */
514
515
1.04M
    pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1);
516
1.04M
    pLatmDemux->m_otherDataLength = 0;
517
518
1.04M
    if (pLatmDemux->m_otherDataPresent) {
519
242k
      if (pLatmDemux->m_AudioMuxVersion == 1) {
520
1.64k
        pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs);
521
240k
      } else {
522
240k
        int otherDataLenEsc = 0;
523
414k
        do {
524
414k
          pLatmDemux->m_otherDataLength <<= 8;  // *= 256
525
414k
          otherDataLenEsc = FDKreadBits(bs, 1);
526
414k
          pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8);
527
414k
        } while (otherDataLenEsc);
528
240k
      }
529
242k
      if (pLatmDemux->m_audioMuxLengthBytes <
530
242k
          (pLatmDemux->m_otherDataLength >> 3)) {
531
9.69k
        ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
532
9.69k
        goto bail;
533
9.69k
      }
534
242k
    }
535
536
1.03M
    pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1);
537
538
1.03M
    if (pLatmDemux->m_crcCheckPresent) {
539
425k
      FDKreadBits(bs, 8);
540
425k
    }
541
542
1.03M
  } else {
543
    /* audioMuxVersionA > 0 is reserved for future extensions */
544
1.16k
    ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
545
1.16k
  }
546
547
  /* Configure source decoder: */
548
1.03M
  if (ErrorStatus == TRANSPORTDEC_OK) {
549
1.03M
    UINT prog;
550
2.05M
    for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
551
1.03M
      UINT lay;
552
2.05M
      for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
553
1.03M
        if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) {
554
914k
          int cbError;
555
914k
          cbError = pTpDecCallbacks->cbUpdateConfig(
556
914k
              pTpDecCallbacks->cbUpdateConfigData,
557
914k
              &pAsc[TPDEC_TRACKINDEX(prog, lay)],
558
914k
              pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode,
559
914k
              &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged);
560
914k
          if (cbError == TRANSPORTDEC_NEED_TO_RESTART) {
561
0
            *pfConfigFound = 0;
562
0
            ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART;
563
0
            goto bail;
564
0
          }
565
914k
          if (cbError != 0) {
566
16.1k
            *pfConfigFound = 0;
567
16.1k
            if (lay == 0) {
568
16.1k
              ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
569
16.1k
              goto bail;
570
16.1k
            }
571
898k
          } else {
572
898k
            *pfConfigFound = 1;
573
898k
          }
574
914k
        } else {
575
121k
          *pfConfigFound = 1;
576
121k
        }
577
1.03M
      }
578
1.03M
    }
579
1.03M
  }
580
581
1.36M
bail:
582
1.36M
  if (ErrorStatus != TRANSPORTDEC_OK) {
583
344k
    UCHAR applyAsc = pLatmDemux->applyAsc;
584
344k
    FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */
585
344k
    pLatmDemux->applyAsc = applyAsc;
586
1.01M
  } else {
587
    /* no error and config parsing is finished */
588
1.01M
    if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0;
589
1.01M
  }
590
591
1.36M
  return (ErrorStatus);
592
1.03M
}
593
594
634k
static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
595
634k
  int len = 0, tmp = 255;
596
634k
  int validBytes = (int)FDKgetValidBits(bs) >> 3;
597
598
1.33M
  while (tmp == 255 && validBytes-- > 0) {
599
698k
    tmp = (int)FDKreadBits(bs, 8);
600
698k
    len += tmp;
601
698k
  }
602
603
634k
  return ((tmp == 255) ? -1 : (len << 3));
604
634k
}
605
606
TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
607
753k
                                                    CLatmDemux *pLatmDemux) {
608
753k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
609
753k
  int totalPayloadBits = 0;
610
611
753k
  if (pLatmDemux->m_allStreamsSameTimeFraming == 1) {
612
648k
    FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG);
613
1.28M
    for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
614
648k
      FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER);
615
1.28M
      for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
616
648k
        LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
617
648k
        int auChunkLengthInfo = 0;
618
619
648k
        switch (p_linfo->m_frameLengthType) {
620
634k
          case 0:
621
634k
            auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs);
622
634k
            if (auChunkLengthInfo >= 0) {
623
632k
              p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo;
624
632k
              totalPayloadBits += p_linfo->m_frameLengthInBits;
625
632k
            } else {
626
2.73k
              return TRANSPORTDEC_PARSE_ERROR;
627
2.73k
            }
628
632k
            break;
629
632k
          case 3:
630
0
          case 5:
631
0
          case 7:
632
13.6k
          default:
633
13.6k
            return TRANSPORTDEC_PARSE_ERROR;  // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE;
634
648k
        }
635
648k
      }
636
648k
    }
637
648k
  } else {
638
104k
    ErrorStatus = TRANSPORTDEC_PARSE_ERROR;  // AAC_DEC_LATM_TIMEFRAMING;
639
104k
  }
640
736k
  if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 &&
641
582k
      totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) {
642
69.2k
    return TRANSPORTDEC_PARSE_ERROR;
643
69.2k
  }
644
645
667k
  return (ErrorStatus);
646
736k
}
647
648
UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
649
403k
                                     const UINT layer) {
650
403k
  UINT nFrameLenBits = 0;
651
403k
  if (prog < pLatmDemux->m_numProgram) {
652
403k
    if (layer < pLatmDemux->m_numLayer[prog]) {
653
403k
      nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits;
654
403k
    }
655
403k
  }
656
403k
  return nFrameLenBits;
657
403k
}
658
659
12.0k
UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) {
660
12.0k
  return pLatmDemux->m_otherDataPresent ? 1 : 0;
661
12.0k
}
662
663
5.40k
UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) {
664
5.40k
  return pLatmDemux->m_otherDataLength;
665
5.40k
}
666
667
265k
UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) {
668
265k
  return pLatmDemux->m_noSubFrames;
669
265k
}
670
671
806k
UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) {
672
806k
  UINT numLayer = 0;
673
806k
  if (prog < pLatmDemux->m_numProgram) {
674
806k
    numLayer = pLatmDemux->m_numLayer[prog];
675
806k
  }
676
806k
  return numLayer;
677
806k
}