Coverage Report

Created: 2025-10-10 07:00

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