Coverage Report

Created: 2025-10-13 06:42

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