Coverage Report

Created: 2026-02-14 06:49

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