Coverage Report

Created: 2025-07-01 06:21

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