Coverage Report

Created: 2025-07-18 06:04

/src/aac/libMpegTPDec/src/tpdec_asc.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 - 2020 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_lib.h"
104
#include "tp_data.h"
105
106
#include "FDK_crc.h"
107
108
#include "common_fix.h"
109
110
/**
111
 * The following arrays provide the IDs of the consecutive elements for each
112
 * channel configuration. Every channel_configuration has to be finalized with
113
 * ID_NONE.
114
 */
115
static const MP4_ELEMENT_ID channel_configuration_0[] = {ID_NONE};
116
static const MP4_ELEMENT_ID channel_configuration_1[] = {ID_SCE, ID_NONE};
117
static const MP4_ELEMENT_ID channel_configuration_2[] = {ID_CPE, ID_NONE};
118
static const MP4_ELEMENT_ID channel_configuration_3[] = {ID_SCE, ID_CPE,
119
                                                         ID_NONE};
120
static const MP4_ELEMENT_ID channel_configuration_4[] = {ID_SCE, ID_CPE, ID_SCE,
121
                                                         ID_NONE};
122
static const MP4_ELEMENT_ID channel_configuration_5[] = {ID_SCE, ID_CPE, ID_CPE,
123
                                                         ID_NONE};
124
static const MP4_ELEMENT_ID channel_configuration_6[] = {ID_SCE, ID_CPE, ID_CPE,
125
                                                         ID_LFE, ID_NONE};
126
static const MP4_ELEMENT_ID channel_configuration_7[] = {
127
    ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
128
static const MP4_ELEMENT_ID channel_configuration_8[] = {
129
    ID_NONE}; /* reserved */
130
static const MP4_ELEMENT_ID channel_configuration_9[] = {
131
    ID_NONE}; /* reserved */
132
static const MP4_ELEMENT_ID channel_configuration_10[] = {
133
    ID_NONE}; /* reserved */
134
static const MP4_ELEMENT_ID channel_configuration_11[] = {
135
    ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_NONE};
136
static const MP4_ELEMENT_ID channel_configuration_12[] = {
137
    ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
138
static const MP4_ELEMENT_ID channel_configuration_13[] = {
139
    ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_LFE, ID_SCE,
140
    ID_CPE, ID_CPE, ID_SCE, ID_CPE, ID_SCE, ID_SCE, ID_CPE, ID_NONE};
141
static const MP4_ELEMENT_ID channel_configuration_14[] = {
142
    ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_NONE};
143
144
static const MP4_ELEMENT_ID *channel_configuration_array[] = {
145
    channel_configuration_0,  channel_configuration_1,
146
    channel_configuration_2,  channel_configuration_3,
147
    channel_configuration_4,  channel_configuration_5,
148
    channel_configuration_6,  channel_configuration_7,
149
    channel_configuration_8,  channel_configuration_9,
150
    channel_configuration_10, channel_configuration_11,
151
    channel_configuration_12, channel_configuration_13,
152
    channel_configuration_14};
153
154
#define TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX (13)
155
#define SC_CHANNEL_CONFIG_TAB_SIZE (TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX + 1)
156
157
/* channel config structure used for sanity check */
158
typedef struct {
159
  SCHAR nCh;  /* number of channels */
160
  SCHAR nSCE; /* number of SCE's */
161
  SCHAR nCPE; /* number of CPE's */
162
  SCHAR nLFE; /* number of LFE's */
163
} SC_CHANNEL_CONFIG;
164
165
static const SC_CHANNEL_CONFIG sc_chan_config_tab[SC_CHANNEL_CONFIG_TAB_SIZE] =
166
    {
167
        /* nCh, nSCE, nCPE, nLFE,     cci */
168
        {0, 0, 0, 0}, /*  0 */
169
        {1, 1, 0, 0}, /*  1 */
170
        {2, 0, 1, 0}, /*  2 */
171
        {3, 1, 1, 0}, /*  3 */
172
        {4, 2, 1, 0}, /*  4 */
173
        {5, 1, 2, 0}, /*  5 */
174
        {6, 1, 2, 1}, /*  6 */
175
        {8, 1, 3, 1}, /*  7 */
176
        {2, 2, 0, 0}, /*  8 */
177
        {3, 1, 1, 0}, /*  9 */
178
        {4, 0, 2, 0}, /* 10 */
179
        {7, 2, 2, 1}, /* 11 */
180
        {8, 1, 3, 1}, /* 12 */
181
        {24, 6, 8, 2} /* 13 */
182
};
183
184
0
void CProgramConfig_Reset(CProgramConfig *pPce) { pPce->elCounter = 0; }
185
186
24.2k
void CProgramConfig_Init(CProgramConfig *pPce) {
187
24.2k
  FDKmemclear(pPce, sizeof(CProgramConfig));
188
24.2k
  pPce->SamplingFrequencyIndex = 0xf;
189
24.2k
}
190
191
6.95k
int CProgramConfig_IsValid(const CProgramConfig *pPce) {
192
6.95k
  return ((pPce->isValid) ? 1 : 0);
193
6.95k
}
194
195
114
#define PCE_HEIGHT_EXT_SYNC (0xAC)
196
197
/*
198
 * Read the extension for height info.
199
 * return 0 if successfull,
200
 *       -1 if the CRC failed,
201
 *       -2 if invalid HeightInfo.
202
 */
203
static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce,
204
                                        HANDLE_FDK_BITSTREAM bs,
205
                                        int *const bytesAvailable,
206
531
                                        const UINT alignmentAnchor) {
207
531
  int err = 0;
208
531
  FDK_CRCINFO crcInfo; /* CRC state info */
209
531
  INT crcReg;
210
531
  FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
211
531
  crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
212
531
  UINT startAnchor = FDKgetValidBits(bs);
213
214
531
  FDK_ASSERT(pPce != NULL);
215
531
  FDK_ASSERT(bs != NULL);
216
531
  FDK_ASSERT(bytesAvailable != NULL);
217
218
531
  if ((startAnchor >= 24) && (*bytesAvailable >= 3) &&
219
531
      (FDKreadBits(bs, 8) == PCE_HEIGHT_EXT_SYNC)) {
220
101
    int i;
221
222
291
    for (i = 0; i < pPce->NumFrontChannelElements; i++) {
223
190
      if ((pPce->FrontElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
224
190
          PC_NUM_HEIGHT_LAYER) {
225
51
        err = -2; /* height information is out of the valid range */
226
51
      }
227
190
    }
228
228
    for (i = 0; i < pPce->NumSideChannelElements; i++) {
229
127
      if ((pPce->SideElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
230
127
          PC_NUM_HEIGHT_LAYER) {
231
22
        err = -2; /* height information is out of the valid range */
232
22
      }
233
127
    }
234
251
    for (i = 0; i < pPce->NumBackChannelElements; i++) {
235
150
      if ((pPce->BackElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
236
150
          PC_NUM_HEIGHT_LAYER) {
237
24
        err = -2; /* height information is out of the valid range */
238
24
      }
239
150
    }
240
101
    FDKbyteAlign(bs, alignmentAnchor);
241
242
101
    FDKcrcEndReg(&crcInfo, bs, crcReg);
243
101
    if ((USHORT)FDKreadBits(bs, 8) != FDKcrcGetCRC(&crcInfo)) {
244
      /* CRC failed */
245
38
      err = -1;
246
38
    }
247
101
    if (err != 0) {
248
      /* Reset whole height information in case an error occured during parsing.
249
         The return value ensures that pPce->isValid is set to 0 and implicit
250
         channel mapping is used. */
251
39
      FDKmemclear(pPce->FrontElementHeightInfo,
252
39
                  sizeof(pPce->FrontElementHeightInfo));
253
39
      FDKmemclear(pPce->SideElementHeightInfo,
254
39
                  sizeof(pPce->SideElementHeightInfo));
255
39
      FDKmemclear(pPce->BackElementHeightInfo,
256
39
                  sizeof(pPce->BackElementHeightInfo));
257
39
    }
258
430
  } else {
259
    /* No valid extension data found -> restore the initial bitbuffer state */
260
430
    FDKpushBack(bs, (INT)startAnchor - (INT)FDKgetValidBits(bs));
261
430
  }
262
263
  /* Always report the bytes read. */
264
531
  *bytesAvailable -= ((INT)startAnchor - (INT)FDKgetValidBits(bs)) >> 3;
265
266
531
  return (err);
267
531
}
268
269
/**
270
 * \brief Sanity checks for program config element.
271
 *        Check order of elements according to ISO/IEC 13818-7:2003(E),
272
 * chapter 8.5.1
273
 *
274
 * \param pPce  pointer to program config element.
275
 *
276
 * \return  0 if successful, otherwise 1.
277
 */
278
531
static int CProgramConfig_Check(CProgramConfig *pPce) {
279
531
  INT i;
280
531
  INT err = 0;
281
531
  INT numBackChannels[3] = {0};
282
531
  INT numSideChannels[3] = {0};
283
531
  INT numFrontChannels[3] = {0};
284
531
  UCHAR *pCpeFront = pPce->FrontElementIsCpe;
285
531
  UCHAR *pCpeSide = pPce->SideElementIsCpe;
286
531
  UCHAR *pCpeBack = pPce->BackElementIsCpe;
287
531
  UCHAR *pHeight;
288
289
531
  pHeight = pPce->BackElementHeightInfo;
290
1.48k
  for (i = 0; i < pPce->NumBackChannelElements; i++) {
291
958
    numBackChannels[*pHeight] += pPce->BackElementIsCpe[i] ? 2 : 1;
292
958
    pHeight++;
293
958
  }
294
531
  pHeight = pPce->SideElementHeightInfo;
295
1.34k
  for (i = 0; i < pPce->NumSideChannelElements; i++) {
296
810
    numSideChannels[*pHeight] += pPce->SideElementIsCpe[i] ? 2 : 1;
297
810
    pHeight++;
298
810
  }
299
531
  pHeight = pPce->FrontElementHeightInfo;
300
1.63k
  for (i = 0; i < pPce->NumFrontChannelElements; i++) {
301
1.10k
    numFrontChannels[*pHeight] += pPce->FrontElementIsCpe[i] ? 2 : 1;
302
1.10k
    pHeight++;
303
1.10k
  }
304
305
  /* 0 = normal height channels, 1 = top height channels, 2 = bottom height
306
   * channels */
307
1.99k
  for (i = 0; i < 3; i++) {
308
    /* if number of channels is odd => first element must be a SCE (front center
309
     * channel) */
310
1.50k
    if (numFrontChannels[i] & 1) {
311
175
      if (*pCpeFront++ == ID_CPE) {
312
5
        err = 1;
313
5
        goto bail;
314
5
      }
315
170
      numFrontChannels[i]--;
316
170
    }
317
2.03k
    while (numFrontChannels[i] > 0) {
318
      /* must be CPE or paired SCE */
319
541
      if (*pCpeFront++ == ID_SCE) {
320
328
        if (*pCpeFront++ == ID_CPE) {
321
4
          err = 1;
322
4
          goto bail;
323
4
        }
324
328
      }
325
537
      numFrontChannels[i] -= 2;
326
1.49k
    };
327
328
    /* in case that a top center surround channel (Ts) is transmitted the number
329
     * of channels can be odd */
330
1.49k
    if (i != 1) {
331
      /* number of channels must be even */
332
1.01k
      if (numSideChannels[i] & 1) {
333
32
        err = 1;
334
32
        goto bail;
335
32
      }
336
1.28k
      while (numSideChannels[i] > 0) {
337
        /* must be CPE or paired SCE */
338
307
        if (*pCpeSide++ == ID_SCE) {
339
199
          if (*pCpeSide++ == ID_CPE) {
340
1
            err = 1;
341
1
            goto bail;
342
1
          }
343
199
        }
344
306
        numSideChannels[i] -= 2;
345
977
      };
346
977
    }
347
348
1.79k
    while (numBackChannels[i] > 1) {
349
      /* must be CPE or paired SCE */
350
335
      if (*pCpeBack++ == ID_SCE) {
351
181
        if (*pCpeBack++ == ID_CPE) {
352
2
          err = 1;
353
2
          goto bail;
354
2
        }
355
181
      }
356
333
      numBackChannels[i] -= 2;
357
1.46k
    };
358
    /* if number of channels is odd => last element must be a SCE (back center
359
     * channel) */
360
1.46k
    if (numBackChannels[i]) {
361
122
      if (*pCpeBack++ == ID_CPE) {
362
1
        err = 1;
363
1
        goto bail;
364
1
      }
365
122
    }
366
1.46k
  }
367
368
531
bail:
369
370
531
  return err;
371
531
}
372
373
void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
374
531
                         UINT alignmentAnchor) {
375
531
  int i;
376
531
  int commentBytes;
377
531
  UCHAR tag, isCpe;
378
531
  UCHAR checkElementTagSelect[3][PC_FSB_CHANNELS_MAX] = {{0}};
379
380
531
  pPce->isValid = 1;
381
531
  pPce->NumEffectiveChannels = 0;
382
531
  pPce->NumChannels = 0;
383
531
  pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4);
384
531
  pPce->Profile = (UCHAR)FDKreadBits(bs, 2);
385
531
  pPce->SamplingFrequencyIndex = (UCHAR)FDKreadBits(bs, 4);
386
531
  pPce->NumFrontChannelElements = (UCHAR)FDKreadBits(bs, 4);
387
531
  pPce->NumSideChannelElements = (UCHAR)FDKreadBits(bs, 4);
388
531
  pPce->NumBackChannelElements = (UCHAR)FDKreadBits(bs, 4);
389
531
  pPce->NumLfeChannelElements = (UCHAR)FDKreadBits(bs, 2);
390
531
  pPce->NumAssocDataElements = (UCHAR)FDKreadBits(bs, 3);
391
531
  pPce->NumValidCcElements = (UCHAR)FDKreadBits(bs, 4);
392
393
531
  if ((pPce->MonoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
394
49
    pPce->MonoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
395
49
  }
396
397
531
  if ((pPce->StereoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
398
35
    pPce->StereoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
399
35
  }
400
401
531
  if ((pPce->MatrixMixdownIndexPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
402
66
    pPce->MatrixMixdownIndex = (UCHAR)FDKreadBits(bs, 2);
403
66
    pPce->PseudoSurroundEnable = (UCHAR)FDKreadBits(bs, 1);
404
66
  }
405
406
1.63k
  for (i = 0; i < pPce->NumFrontChannelElements; i++) {
407
1.10k
    pPce->FrontElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1);
408
1.10k
    pPce->FrontElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
409
1.10k
    pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
410
411
    /* Check element instance tag according to ISO/IEC 13818-7:2003(E),
412
     * chapter 8.2.1.1 */
413
1.10k
    if (checkElementTagSelect[isCpe][tag] == 0) {
414
601
      checkElementTagSelect[isCpe][tag] = 1;
415
601
    } else {
416
506
      pPce->isValid = 0;
417
506
    }
418
1.10k
  }
419
420
1.34k
  for (i = 0; i < pPce->NumSideChannelElements; i++) {
421
810
    pPce->SideElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1);
422
810
    pPce->SideElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
423
810
    pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
424
425
    /* Check element instance tag according to ISO/IEC 13818-7:2003(E),
426
     * chapter 8.2.1.1 */
427
810
    if (checkElementTagSelect[isCpe][tag] == 0) {
428
280
      checkElementTagSelect[isCpe][tag] = 1;
429
530
    } else {
430
530
      pPce->isValid = 0;
431
530
    }
432
810
  }
433
434
1.48k
  for (i = 0; i < pPce->NumBackChannelElements; i++) {
435
958
    pPce->BackElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1);
436
958
    pPce->BackElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
437
958
    pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
438
439
    /* Check element instance tag according to ISO/IEC 13818-7:2003(E),
440
     * chapter 8.2.1.1 */
441
958
    if (checkElementTagSelect[isCpe][tag] == 0) {
442
417
      checkElementTagSelect[isCpe][tag] = 1;
443
541
    } else {
444
541
      pPce->isValid = 0;
445
541
    }
446
958
  }
447
448
531
  pPce->NumEffectiveChannels = pPce->NumChannels;
449
450
788
  for (i = 0; i < pPce->NumLfeChannelElements; i++) {
451
257
    pPce->LfeElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
452
257
    pPce->NumChannels += 1;
453
454
    /* Check element instance tag according to ISO/IEC 13818-7:2003(E),
455
     * chapter 8.2.1.1 */
456
257
    if (checkElementTagSelect[2][tag] == 0) {
457
204
      checkElementTagSelect[2][tag] = 1;
458
204
    } else {
459
53
      pPce->isValid = 0;
460
53
    }
461
257
  }
462
463
1.15k
  for (i = 0; i < pPce->NumAssocDataElements; i++) {
464
620
    pPce->AssocDataElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
465
620
  }
466
467
1.98k
  for (i = 0; i < pPce->NumValidCcElements; i++) {
468
1.45k
    pPce->CcElementIsIndSw[i] = (UCHAR)FDKreadBits(bs, 1);
469
1.45k
    pPce->ValidCcElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
470
1.45k
  }
471
472
531
  FDKbyteAlign(bs, alignmentAnchor);
473
474
531
  pPce->CommentFieldBytes = (UCHAR)FDKreadBits(bs, 8);
475
531
  commentBytes = pPce->CommentFieldBytes;
476
477
  /* Search for height info extension and read it if available */
478
531
  if (CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor)) {
479
39
    pPce->isValid = 0;
480
39
  }
481
482
  /* Check order of elements according to ISO / IEC 13818 - 7:2003(E),
483
   * chapter 8.5.1 */
484
531
  if (CProgramConfig_Check(pPce)) {
485
45
    pPce->isValid = 0;
486
45
  }
487
488
16.7k
  for (i = 0; i < commentBytes; i++) {
489
16.2k
    UCHAR text;
490
491
16.2k
    text = (UCHAR)FDKreadBits(bs, 8);
492
493
16.2k
    if (i < PC_COMMENTLENGTH) {
494
16.2k
      pPce->Comment[i] = text;
495
16.2k
    }
496
16.2k
  }
497
531
}
498
499
/*
500
 * Compare two program configurations.
501
 * Returns the result of the comparison:
502
 *  -1 - completely different
503
 *   0 - completely equal
504
 *   1 - different but same channel configuration
505
 *   2 - different channel configuration but same number of channels
506
 */
507
int CProgramConfig_Compare(const CProgramConfig *const pPce1,
508
460
                           const CProgramConfig *const pPce2) {
509
460
  int result = 0; /* Innocent until proven false. */
510
511
460
  if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) !=
512
460
      0) { /* Configurations are not completely equal.
513
              So look into details and analyse the channel configurations: */
514
457
    result = -1;
515
516
457
    if (pPce1->NumChannels ==
517
457
        pPce2->NumChannels) { /* Now the logic changes. We first assume to have
518
                                 the same channel configuration and then prove
519
                                 if this assumption is true. */
520
457
      result = 1;
521
522
      /* Front channels */
523
457
      if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) {
524
345
        result = 2; /* different number of front channel elements */
525
345
      } else {
526
112
        int el, numCh1 = 0, numCh2 = 0;
527
318
        for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) {
528
228
          if (pPce1->FrontElementHeightInfo[el] !=
529
228
              pPce2->FrontElementHeightInfo[el]) {
530
22
            result = 2; /* different height info */
531
22
            break;
532
22
          }
533
206
          numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1;
534
206
          numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1;
535
206
        }
536
112
        if (numCh1 != numCh2) {
537
51
          result = 2; /* different number of front channels */
538
51
        }
539
112
      }
540
      /* Side channels */
541
457
      if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) {
542
178
        result = 2; /* different number of side channel elements */
543
279
      } else {
544
279
        int el, numCh1 = 0, numCh2 = 0;
545
287
        for (el = 0; el < pPce1->NumSideChannelElements; el += 1) {
546
11
          if (pPce1->SideElementHeightInfo[el] !=
547
11
              pPce2->SideElementHeightInfo[el]) {
548
3
            result = 2; /* different height info */
549
3
            break;
550
3
          }
551
8
          numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1;
552
8
          numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1;
553
8
        }
554
279
        if (numCh1 != numCh2) {
555
0
          result = 2; /* different number of side channels */
556
0
        }
557
279
      }
558
      /* Back channels */
559
457
      if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) {
560
337
        result = 2; /* different number of back channel elements */
561
337
      } else {
562
120
        int el, numCh1 = 0, numCh2 = 0;
563
207
        for (el = 0; el < pPce1->NumBackChannelElements; el += 1) {
564
99
          if (pPce1->BackElementHeightInfo[el] !=
565
99
              pPce2->BackElementHeightInfo[el]) {
566
12
            result = 2; /* different height info */
567
12
            break;
568
12
          }
569
87
          numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1;
570
87
          numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1;
571
87
        }
572
120
        if (numCh1 != numCh2) {
573
43
          result = 2; /* different number of back channels */
574
43
        }
575
120
      }
576
      /* LFE channels */
577
457
      if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) {
578
275
        result = 2; /* different number of lfe channels */
579
275
      }
580
      /* LFEs are always SCEs so we don't need to count the channels. */
581
457
    }
582
457
  }
583
584
460
  return result;
585
460
}
586
587
460
void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) {
588
460
  FDK_ASSERT(pPce != NULL);
589
590
  /* Init PCE */
591
460
  CProgramConfig_Init(pPce);
592
460
  pPce->Profile =
593
460
      1; /* Set AAC LC because it is the only supported object type. */
594
595
460
  switch (channelConfig) {
596
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
597
79
    case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
598
79
      pPce->NumFrontChannelElements = 2;
599
79
      pPce->FrontElementIsCpe[0] = 0;
600
79
      pPce->FrontElementIsCpe[1] = 1;
601
79
      pPce->NumSideChannelElements = 1;
602
79
      pPce->SideElementIsCpe[0] = 1;
603
79
      pPce->NumBackChannelElements = 1;
604
79
      pPce->BackElementIsCpe[0] = 1;
605
79
      pPce->NumLfeChannelElements = 1;
606
79
      pPce->NumChannels = 8;
607
79
      pPce->NumEffectiveChannels = 7;
608
79
      pPce->isValid = 1;
609
79
      break;
610
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
611
79
    case 12: /* 3/0/4.1ch surround back */
612
79
      pPce->BackElementIsCpe[1] = 1;
613
79
      pPce->NumChannels += 1;
614
79
      pPce->NumEffectiveChannels += 1;
615
79
      FDK_FALLTHROUGH;
616
92
    case 11: /* 3/0/3.1ch */
617
92
      pPce->NumFrontChannelElements += 2;
618
92
      pPce->FrontElementIsCpe[0] = 0;
619
92
      pPce->FrontElementIsCpe[1] = 1;
620
92
      pPce->NumBackChannelElements += 2;
621
92
      pPce->BackElementIsCpe[0] = 1;
622
92
      pPce->BackElementIsCpe[1] += 0;
623
92
      pPce->NumLfeChannelElements += 1;
624
92
      pPce->NumChannels += 7;
625
92
      pPce->NumEffectiveChannels += 6;
626
92
      pPce->isValid = 1;
627
92
      break;
628
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
629
79
    case 14:                               /* 2/0/0-3/0/2-0.1ch front height */
630
79
      pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */
631
79
      FDK_FALLTHROUGH;
632
158
    case 7: /* 5/0/2.1ch front */
633
158
      pPce->NumFrontChannelElements += 1;
634
158
      pPce->FrontElementIsCpe[2] = 1;
635
158
      pPce->NumChannels += 2;
636
158
      pPce->NumEffectiveChannels += 2;
637
158
      FDK_FALLTHROUGH;
638
177
    case 6: /* 3/0/2.1ch */
639
177
      pPce->NumLfeChannelElements += 1;
640
177
      pPce->NumChannels += 1;
641
177
      FDK_FALLTHROUGH;
642
200
    case 5: /* 3/0/2.0ch */
643
240
    case 4: /* 3/0/1.0ch */
644
240
      pPce->NumBackChannelElements += 1;
645
240
      pPce->BackElementIsCpe[0] = (channelConfig > 4) ? 1 : 0;
646
240
      pPce->NumChannels += (channelConfig > 4) ? 2 : 1;
647
240
      pPce->NumEffectiveChannels += (channelConfig > 4) ? 2 : 1;
648
240
      FDK_FALLTHROUGH;
649
289
    case 3: /* 3/0/0.0ch */
650
289
      pPce->NumFrontChannelElements += 1;
651
289
      pPce->FrontElementIsCpe[1] = 1;
652
289
      pPce->NumChannels += 2;
653
289
      pPce->NumEffectiveChannels += 2;
654
289
      FDK_FALLTHROUGH;
655
289
    case 1: /* 1/0/0.0ch */
656
289
      pPce->NumFrontChannelElements += 1;
657
289
      pPce->FrontElementIsCpe[0] = 0;
658
289
      pPce->NumChannels += 1;
659
289
      pPce->NumEffectiveChannels += 1;
660
289
      pPce->isValid = 1;
661
289
      break;
662
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
663
0
    case 2: /* 2/0/0.ch */
664
0
      pPce->NumFrontChannelElements = 1;
665
0
      pPce->FrontElementIsCpe[0] = 1;
666
0
      pPce->NumChannels += 2;
667
0
      pPce->NumEffectiveChannels += 2;
668
0
      pPce->isValid = 1;
669
0
      break;
670
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
671
0
    default:
672
0
      pPce->isValid = 0; /* To be explicit! */
673
0
      break;
674
460
  }
675
676
460
  if (pPce->isValid) {
677
    /* Create valid element instance tags */
678
460
    int el, elTagSce = 0, elTagCpe = 0;
679
680
1.53k
    for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
681
1.07k
      pPce->FrontElementTagSelect[el] =
682
1.07k
          (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
683
1.07k
    }
684
539
    for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
685
79
      pPce->SideElementTagSelect[el] =
686
79
          (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
687
79
    }
688
963
    for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
689
503
      pPce->BackElementTagSelect[el] =
690
503
          (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
691
503
    }
692
460
    elTagSce = 0;
693
808
    for (el = 0; el < pPce->NumLfeChannelElements; el += 1) {
694
348
      pPce->LfeElementTagSelect[el] = elTagSce++;
695
348
    }
696
460
  }
697
460
}
698
699
/**
700
 * \brief get implicit audio channel type for given channelConfig and MPEG
701
 * ordered channel index
702
 * \param channelConfig MPEG channelConfiguration from 1 upto 14
703
 * \param index MPEG channel order index
704
 * \return audio channel type.
705
 */
706
static void getImplicitAudioChannelTypeAndIndex(AUDIO_CHANNEL_TYPE *chType,
707
                                                UCHAR *chIndex,
708
                                                UINT channelConfig,
709
0
                                                UINT index) {
710
0
  if (index < 3) {
711
0
    *chType = ACT_FRONT;
712
0
    *chIndex = index;
713
0
  } else {
714
0
    switch (channelConfig) {
715
0
      case 4: /* SCE, CPE, SCE */
716
0
      case 5: /* SCE, CPE, CPE */
717
0
      case 6: /* SCE, CPE, CPE, LFE */
718
0
        switch (index) {
719
0
          case 3:
720
0
          case 4:
721
0
            *chType = ACT_BACK;
722
0
            *chIndex = index - 3;
723
0
            break;
724
0
          case 5:
725
0
            *chType = ACT_LFE;
726
0
            *chIndex = 0;
727
0
            break;
728
0
        }
729
0
        break;
730
0
      case 7: /* SCE,CPE,CPE,CPE,LFE */
731
0
        switch (index) {
732
0
          case 3:
733
0
          case 4:
734
0
            *chType = ACT_FRONT;
735
0
            *chIndex = index;
736
0
            break;
737
0
          case 5:
738
0
          case 6:
739
0
            *chType = ACT_BACK;
740
0
            *chIndex = index - 5;
741
0
            break;
742
0
          case 7:
743
0
            *chType = ACT_LFE;
744
0
            *chIndex = 0;
745
0
            break;
746
0
        }
747
0
        break;
748
0
      case 11: /* SCE,CPE,CPE,SCE,LFE */
749
0
        if (index < 6) {
750
0
          *chType = ACT_BACK;
751
0
          *chIndex = index - 3;
752
0
        } else {
753
0
          *chType = ACT_LFE;
754
0
          *chIndex = 0;
755
0
        }
756
0
        break;
757
0
      case 12: /* SCE,CPE,CPE,CPE,LFE */
758
0
        if (index < 7) {
759
0
          *chType = ACT_BACK;
760
0
          *chIndex = index - 3;
761
0
        } else {
762
0
          *chType = ACT_LFE;
763
0
          *chIndex = 0;
764
0
        }
765
0
        break;
766
0
      case 14: /* SCE,CPE,CPE,LFE,CPE */
767
0
        switch (index) {
768
0
          case 3:
769
0
          case 4:
770
0
            *chType = ACT_BACK;
771
0
            *chIndex = index - 3;
772
0
            break;
773
0
          case 5:
774
0
            *chType = ACT_LFE;
775
0
            *chIndex = 0;
776
0
            break;
777
0
          case 6:
778
0
          case 7:
779
0
            *chType = ACT_FRONT_TOP;
780
0
            *chIndex = index - 6; /* handle the top layer independently */
781
0
            break;
782
0
        }
783
0
        break;
784
0
      default:
785
0
        *chType = ACT_NONE;
786
0
        break;
787
0
    }
788
0
  }
789
0
}
790
791
int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT channelConfig,
792
                                 const UINT tag, const UINT channelIdx,
793
                                 UCHAR chMapping[], AUDIO_CHANNEL_TYPE chType[],
794
                                 UCHAR chIndex[], const UINT chDescrLen,
795
                                 UCHAR *elMapping, MP4_ELEMENT_ID elList[],
796
0
                                 MP4_ELEMENT_ID elType) {
797
0
  if (channelConfig > 0) {
798
    /* Constant channel mapping must have
799
       been set during initialization. */
800
0
    if (IS_CHANNEL_ELEMENT(elType)) {
801
0
      *elMapping = pPce->elCounter;
802
0
      if (elList[pPce->elCounter] != elType &&
803
0
          !IS_USAC_CHANNEL_ELEMENT(elType)) {
804
        /* Not in the list */
805
0
        if ((channelConfig == 2) &&
806
0
            (elType == ID_SCE)) { /* This scenario occurs with HE-AAC v2 streams
807
                                     of buggy encoders. In other decoder
808
                                     implementations decoding of this kind of
809
                                     streams is desired. */
810
0
          channelConfig = 1;
811
0
        } else if ((elList[pPce->elCounter] == ID_LFE) &&
812
0
                   (elType ==
813
0
                    ID_SCE)) { /* Decode bitstreams which wrongly use ID_SCE
814
                                  instead of ID_LFE element type. */
815
0
          ;
816
0
        } else {
817
0
          return 0;
818
0
        }
819
0
      }
820
      /* Assume all front channels */
821
0
      getImplicitAudioChannelTypeAndIndex(
822
0
          &chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
823
0
      if (elType == ID_CPE || elType == ID_USAC_CPE) {
824
0
        chType[channelIdx + 1] = chType[channelIdx];
825
0
        chIndex[channelIdx + 1] = chIndex[channelIdx] + 1;
826
0
      }
827
0
      pPce->elCounter++;
828
0
    }
829
    /* Accept all non-channel elements, too. */
830
0
    return 1;
831
0
  } else {
832
0
    if ((!pPce->isValid) || (pPce->NumChannels > chDescrLen)) {
833
      /* Implicit channel mapping. */
834
0
      if (IS_USAC_CHANNEL_ELEMENT(elType)) {
835
0
        *elMapping = pPce->elCounter++;
836
0
      } else if (IS_MP4_CHANNEL_ELEMENT(elType)) {
837
        /* Store all channel element IDs */
838
0
        elList[pPce->elCounter] = elType;
839
0
        *elMapping = pPce->elCounter++;
840
0
      }
841
0
    } else {
842
      /* Accept the additional channel(s), only if the tag is in the lists */
843
0
      int isCpe = 0, i;
844
      /* Element counter */
845
0
      int ec[PC_NUM_HEIGHT_LAYER] = {0};
846
      /* Channel counters */
847
0
      int cc[PC_NUM_HEIGHT_LAYER] = {0};
848
0
      int fc[PC_NUM_HEIGHT_LAYER] = {0}; /* front channel counter */
849
0
      int sc[PC_NUM_HEIGHT_LAYER] = {0}; /* side channel counter */
850
0
      int bc[PC_NUM_HEIGHT_LAYER] = {0}; /* back channel counter */
851
0
      int lc = 0;                        /* lfe channel counter */
852
853
      /* General MPEG (PCE) composition rules:
854
         - Over all:
855
             <normal height channels><top height channels><bottom height
856
         channels>
857
         - Within each height layer:
858
             <front channels><side channels><back channels>
859
         - Exception:
860
             The LFE channels have no height info and thus they are arranged at
861
         the very end of the normal height layer channels.
862
       */
863
864
0
      switch (elType) {
865
0
        case ID_CPE:
866
0
          isCpe = 1;
867
0
          FDK_FALLTHROUGH;
868
0
        case ID_SCE:
869
          /* search in front channels */
870
0
          for (i = 0; i < pPce->NumFrontChannelElements; i++) {
871
0
            int heightLayer = pPce->FrontElementHeightInfo[i];
872
0
            if (isCpe == pPce->FrontElementIsCpe[i] &&
873
0
                pPce->FrontElementTagSelect[i] == tag) {
874
0
              int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
875
0
              AUDIO_CHANNEL_TYPE aChType =
876
0
                  (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_FRONT);
877
0
              for (h = heightLayer - 1; h >= 0; h -= 1) {
878
0
                int el;
879
                /* Count front channels/elements */
880
0
                for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
881
0
                  if (pPce->FrontElementHeightInfo[el] == h) {
882
0
                    elIdx += 1;
883
0
                    chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
884
0
                  }
885
0
                }
886
                /* Count side channels/elements */
887
0
                for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
888
0
                  if (pPce->SideElementHeightInfo[el] == h) {
889
0
                    elIdx += 1;
890
0
                    chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
891
0
                  }
892
0
                }
893
                /* Count back channels/elements */
894
0
                for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
895
0
                  if (pPce->BackElementHeightInfo[el] == h) {
896
0
                    elIdx += 1;
897
0
                    chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
898
0
                  }
899
0
                }
900
0
                if (h == 0) { /* normal height */
901
0
                  elIdx += pPce->NumLfeChannelElements;
902
0
                  chIdx += pPce->NumLfeChannelElements;
903
0
                }
904
0
              }
905
0
              chMapping[chIdx] = channelIdx;
906
0
              chType[chIdx] = aChType;
907
0
              chIndex[chIdx] = fc[heightLayer];
908
0
              if (isCpe) {
909
0
                chMapping[chIdx + 1] = channelIdx + 1;
910
0
                chType[chIdx + 1] = aChType;
911
0
                chIndex[chIdx + 1] = fc[heightLayer] + 1;
912
0
              }
913
0
              *elMapping = elIdx;
914
0
              return 1;
915
0
            }
916
0
            ec[heightLayer] += 1;
917
0
            if (pPce->FrontElementIsCpe[i]) {
918
0
              cc[heightLayer] += 2;
919
0
              fc[heightLayer] += 2;
920
0
            } else {
921
0
              cc[heightLayer] += 1;
922
0
              fc[heightLayer] += 1;
923
0
            }
924
0
          }
925
          /* search in side channels */
926
0
          for (i = 0; i < pPce->NumSideChannelElements; i++) {
927
0
            int heightLayer = pPce->SideElementHeightInfo[i];
928
0
            if (isCpe == pPce->SideElementIsCpe[i] &&
929
0
                pPce->SideElementTagSelect[i] == tag) {
930
0
              int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
931
0
              AUDIO_CHANNEL_TYPE aChType =
932
0
                  (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_SIDE);
933
0
              for (h = heightLayer - 1; h >= 0; h -= 1) {
934
0
                int el;
935
                /* Count front channels/elements */
936
0
                for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
937
0
                  if (pPce->FrontElementHeightInfo[el] == h) {
938
0
                    elIdx += 1;
939
0
                    chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
940
0
                  }
941
0
                }
942
                /* Count side channels/elements */
943
0
                for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
944
0
                  if (pPce->SideElementHeightInfo[el] == h) {
945
0
                    elIdx += 1;
946
0
                    chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
947
0
                  }
948
0
                }
949
                /* Count back channels/elements */
950
0
                for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
951
0
                  if (pPce->BackElementHeightInfo[el] == h) {
952
0
                    elIdx += 1;
953
0
                    chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
954
0
                  }
955
0
                }
956
0
                if (h ==
957
0
                    0) { /* LFE channels belong to the normal height layer */
958
0
                  elIdx += pPce->NumLfeChannelElements;
959
0
                  chIdx += pPce->NumLfeChannelElements;
960
0
                }
961
0
              }
962
0
              chMapping[chIdx] = channelIdx;
963
0
              chType[chIdx] = aChType;
964
0
              chIndex[chIdx] = sc[heightLayer];
965
0
              if (isCpe) {
966
0
                chMapping[chIdx + 1] = channelIdx + 1;
967
0
                chType[chIdx + 1] = aChType;
968
0
                chIndex[chIdx + 1] = sc[heightLayer] + 1;
969
0
              }
970
0
              *elMapping = elIdx;
971
0
              return 1;
972
0
            }
973
0
            ec[heightLayer] += 1;
974
0
            if (pPce->SideElementIsCpe[i]) {
975
0
              cc[heightLayer] += 2;
976
0
              sc[heightLayer] += 2;
977
0
            } else {
978
0
              cc[heightLayer] += 1;
979
0
              sc[heightLayer] += 1;
980
0
            }
981
0
          }
982
          /* search in back channels */
983
0
          for (i = 0; i < pPce->NumBackChannelElements; i++) {
984
0
            int heightLayer = pPce->BackElementHeightInfo[i];
985
0
            if (isCpe == pPce->BackElementIsCpe[i] &&
986
0
                pPce->BackElementTagSelect[i] == tag) {
987
0
              int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
988
0
              AUDIO_CHANNEL_TYPE aChType =
989
0
                  (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_BACK);
990
0
              for (h = heightLayer - 1; h >= 0; h -= 1) {
991
0
                int el;
992
                /* Count front channels/elements */
993
0
                for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
994
0
                  if (pPce->FrontElementHeightInfo[el] == h) {
995
0
                    elIdx += 1;
996
0
                    chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
997
0
                  }
998
0
                }
999
                /* Count side channels/elements */
1000
0
                for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
1001
0
                  if (pPce->SideElementHeightInfo[el] == h) {
1002
0
                    elIdx += 1;
1003
0
                    chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
1004
0
                  }
1005
0
                }
1006
                /* Count back channels/elements */
1007
0
                for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
1008
0
                  if (pPce->BackElementHeightInfo[el] == h) {
1009
0
                    elIdx += 1;
1010
0
                    chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
1011
0
                  }
1012
0
                }
1013
0
                if (h == 0) { /* normal height */
1014
0
                  elIdx += pPce->NumLfeChannelElements;
1015
0
                  chIdx += pPce->NumLfeChannelElements;
1016
0
                }
1017
0
              }
1018
0
              chMapping[chIdx] = channelIdx;
1019
0
              chType[chIdx] = aChType;
1020
0
              chIndex[chIdx] = bc[heightLayer];
1021
0
              if (isCpe) {
1022
0
                chMapping[chIdx + 1] = channelIdx + 1;
1023
0
                chType[chIdx + 1] = aChType;
1024
0
                chIndex[chIdx + 1] = bc[heightLayer] + 1;
1025
0
              }
1026
0
              *elMapping = elIdx;
1027
0
              return 1;
1028
0
            }
1029
0
            ec[heightLayer] += 1;
1030
0
            if (pPce->BackElementIsCpe[i]) {
1031
0
              cc[heightLayer] += 2;
1032
0
              bc[heightLayer] += 2;
1033
0
            } else {
1034
0
              cc[heightLayer] += 1;
1035
0
              bc[heightLayer] += 1;
1036
0
            }
1037
0
          }
1038
0
          break;
1039
1040
0
        case ID_LFE: { /* Unfortunately we have to go through all normal height
1041
                          layer elements to get the position of the LFE
1042
                          channels. Start with counting the front
1043
                          channels/elements at normal height */
1044
0
          for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
1045
0
            int heightLayer = pPce->FrontElementHeightInfo[i];
1046
0
            ec[heightLayer] += 1;
1047
0
            cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
1048
0
          }
1049
          /* Count side channels/elements at normal height */
1050
0
          for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
1051
0
            int heightLayer = pPce->SideElementHeightInfo[i];
1052
0
            ec[heightLayer] += 1;
1053
0
            cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
1054
0
          }
1055
          /* Count back channels/elements at normal height */
1056
0
          for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
1057
0
            int heightLayer = pPce->BackElementHeightInfo[i];
1058
0
            ec[heightLayer] += 1;
1059
0
            cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
1060
0
          }
1061
1062
          /* search in lfe channels */
1063
0
          for (i = 0; i < pPce->NumLfeChannelElements; i++) {
1064
0
            int elIdx =
1065
0
                ec[0]; /* LFE channels belong to the normal height layer */
1066
0
            int chIdx = cc[0];
1067
0
            if (pPce->LfeElementTagSelect[i] == tag) {
1068
0
              chMapping[chIdx] = channelIdx;
1069
0
              *elMapping = elIdx;
1070
0
              chType[chIdx] = ACT_LFE;
1071
0
              chIndex[chIdx] = lc;
1072
0
              return 1;
1073
0
            }
1074
0
            ec[0] += 1;
1075
0
            cc[0] += 1;
1076
0
            lc += 1;
1077
0
          }
1078
0
        } break;
1079
1080
        /* Non audio elements */
1081
0
        case ID_CCE:
1082
          /* search in cce channels */
1083
0
          for (i = 0; i < pPce->NumValidCcElements; i++) {
1084
0
            if (pPce->ValidCcElementTagSelect[i] == tag) {
1085
0
              return 1;
1086
0
            }
1087
0
          }
1088
0
          break;
1089
0
        case ID_DSE:
1090
          /* search associated data elements */
1091
0
          for (i = 0; i < pPce->NumAssocDataElements; i++) {
1092
0
            if (pPce->AssocDataElementTagSelect[i] == tag) {
1093
0
              return 1;
1094
0
            }
1095
0
          }
1096
0
          break;
1097
0
        default:
1098
0
          return 0;
1099
0
      }
1100
0
      return 0; /* not found in any list */
1101
0
    }
1102
0
  }
1103
1104
0
  return 1;
1105
0
}
1106
1107
0
#define SPEAKER_PLANE_NORMAL 0
1108
0
#define SPEAKER_PLANE_TOP 1
1109
0
#define SPEAKER_PLANE_BOTTOM 2
1110
1111
void CProgramConfig_GetChannelDescription(const UINT chConfig,
1112
                                          const CProgramConfig *pPce,
1113
                                          AUDIO_CHANNEL_TYPE chType[],
1114
0
                                          UCHAR chIndex[]) {
1115
0
  FDK_ASSERT(chType != NULL);
1116
0
  FDK_ASSERT(chIndex != NULL);
1117
1118
0
  if ((chConfig == 0) && (pPce != NULL)) {
1119
0
    if (pPce->isValid) {
1120
0
      int spkPlane, chIdx = 0;
1121
0
      for (spkPlane = SPEAKER_PLANE_NORMAL; spkPlane <= SPEAKER_PLANE_BOTTOM;
1122
0
           spkPlane += 1) {
1123
0
        int elIdx, grpChIdx = 0;
1124
0
        for (elIdx = 0; elIdx < pPce->NumFrontChannelElements; elIdx += 1) {
1125
0
          if (pPce->FrontElementHeightInfo[elIdx] == spkPlane) {
1126
0
            chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
1127
0
            chIndex[chIdx++] = grpChIdx++;
1128
0
            if (pPce->FrontElementIsCpe[elIdx]) {
1129
0
              chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
1130
0
              chIndex[chIdx++] = grpChIdx++;
1131
0
            }
1132
0
          }
1133
0
        }
1134
0
        grpChIdx = 0;
1135
0
        for (elIdx = 0; elIdx < pPce->NumSideChannelElements; elIdx += 1) {
1136
0
          if (pPce->SideElementHeightInfo[elIdx] == spkPlane) {
1137
0
            chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
1138
0
            chIndex[chIdx++] = grpChIdx++;
1139
0
            if (pPce->SideElementIsCpe[elIdx]) {
1140
0
              chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
1141
0
              chIndex[chIdx++] = grpChIdx++;
1142
0
            }
1143
0
          }
1144
0
        }
1145
0
        grpChIdx = 0;
1146
0
        for (elIdx = 0; elIdx < pPce->NumBackChannelElements; elIdx += 1) {
1147
0
          if (pPce->BackElementHeightInfo[elIdx] == spkPlane) {
1148
0
            chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
1149
0
            chIndex[chIdx++] = grpChIdx++;
1150
0
            if (pPce->BackElementIsCpe[elIdx]) {
1151
0
              chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
1152
0
              chIndex[chIdx++] = grpChIdx++;
1153
0
            }
1154
0
          }
1155
0
        }
1156
0
        grpChIdx = 0;
1157
0
        if (spkPlane == SPEAKER_PLANE_NORMAL) {
1158
0
          for (elIdx = 0; elIdx < pPce->NumLfeChannelElements; elIdx += 1) {
1159
0
            chType[chIdx] = ACT_LFE;
1160
0
            chIndex[chIdx++] = grpChIdx++;
1161
0
          }
1162
0
        }
1163
0
      }
1164
0
    }
1165
0
  } else {
1166
0
    int chIdx;
1167
0
    for (chIdx = 0; chIdx < getNumberOfTotalChannels(chConfig); chIdx += 1) {
1168
0
      getImplicitAudioChannelTypeAndIndex(&chType[chIdx], &chIndex[chIdx],
1169
0
                                          chConfig, chIdx);
1170
0
    }
1171
0
  }
1172
0
}
1173
1174
int CProgramConfig_GetPceChMap(const CProgramConfig *pPce, UCHAR pceChMap[],
1175
0
                               const UINT pceChMapLen) {
1176
0
  const UCHAR *nElements = &pPce->NumFrontChannelElements;
1177
0
  const UCHAR *elHeight[3], *elIsCpe[3];
1178
0
  unsigned chIdx, plane, grp, offset, totCh[3], numCh[3][4];
1179
1180
0
  FDK_ASSERT(pPce != NULL);
1181
0
  FDK_ASSERT(pceChMap != NULL);
1182
1183
  /* Init counter: */
1184
0
  FDKmemclear(totCh, 3 * sizeof(unsigned));
1185
0
  FDKmemclear(numCh, 3 * 4 * sizeof(unsigned));
1186
1187
  /* Analyse PCE: */
1188
0
  elHeight[0] = pPce->FrontElementHeightInfo;
1189
0
  elIsCpe[0] = pPce->FrontElementIsCpe;
1190
0
  elHeight[1] = pPce->SideElementHeightInfo;
1191
0
  elIsCpe[1] = pPce->SideElementIsCpe;
1192
0
  elHeight[2] = pPce->BackElementHeightInfo;
1193
0
  elIsCpe[2] = pPce->BackElementIsCpe;
1194
1195
0
  for (plane = 0; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
1196
0
    for (grp = 0; grp < 3; grp += 1) { /* front, side, back */
1197
0
      unsigned el;
1198
0
      for (el = 0; el < nElements[grp]; el += 1) {
1199
0
        if (elHeight[grp][el] == plane) {
1200
0
          unsigned elCh = elIsCpe[grp][el] ? 2 : 1;
1201
0
          numCh[plane][grp] += elCh;
1202
0
          totCh[plane] += elCh;
1203
0
        }
1204
0
      }
1205
0
    }
1206
0
    if (plane == SPEAKER_PLANE_NORMAL) {
1207
0
      unsigned elCh = pPce->NumLfeChannelElements;
1208
0
      numCh[plane][grp] += elCh;
1209
0
      totCh[plane] += elCh;
1210
0
    }
1211
0
  }
1212
  /* Sanity checks: */
1213
0
  chIdx = totCh[SPEAKER_PLANE_NORMAL] + totCh[SPEAKER_PLANE_TOP] +
1214
0
          totCh[SPEAKER_PLANE_BOTTOM];
1215
0
  if (chIdx > pceChMapLen) {
1216
0
    return -1;
1217
0
  }
1218
1219
  /* Create map: */
1220
0
  offset = grp = 0;
1221
0
  unsigned grpThresh = numCh[SPEAKER_PLANE_NORMAL][grp];
1222
0
  for (chIdx = 0; chIdx < totCh[SPEAKER_PLANE_NORMAL]; chIdx += 1) {
1223
0
    while ((chIdx >= grpThresh) && (grp < 3)) {
1224
0
      offset += numCh[1][grp] + numCh[2][grp];
1225
0
      grp += 1;
1226
0
      grpThresh += numCh[SPEAKER_PLANE_NORMAL][grp];
1227
0
    }
1228
0
    pceChMap[chIdx] = chIdx + offset;
1229
0
  }
1230
0
  offset = 0;
1231
0
  for (grp = 0; grp < 4; grp += 1) { /* front, side, back and lfe */
1232
0
    offset += numCh[SPEAKER_PLANE_NORMAL][grp];
1233
0
    for (plane = SPEAKER_PLANE_TOP; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
1234
0
      unsigned mapCh;
1235
0
      for (mapCh = 0; mapCh < numCh[plane][grp]; mapCh += 1) {
1236
0
        pceChMap[chIdx++] = offset;
1237
0
        offset += 1;
1238
0
      }
1239
0
    }
1240
0
  }
1241
0
  return 0;
1242
0
}
1243
1244
int CProgramConfig_GetElementTable(const CProgramConfig *pPce,
1245
                                   MP4_ELEMENT_ID elList[],
1246
344
                                   const INT elListSize, UCHAR *pChMapIdx) {
1247
344
  int i, el = 0;
1248
1249
344
  FDK_ASSERT(elList != NULL);
1250
344
  FDK_ASSERT(pChMapIdx != NULL);
1251
344
  FDK_ASSERT(pPce != NULL);
1252
1253
344
  *pChMapIdx = 0;
1254
1255
344
  if ((elListSize <
1256
344
       pPce->NumFrontChannelElements + pPce->NumSideChannelElements +
1257
344
           pPce->NumBackChannelElements + pPce->NumLfeChannelElements) ||
1258
344
      (pPce->NumChannels == 0)) {
1259
3
    return 0;
1260
3
  }
1261
1262
772
  for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
1263
431
    elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE;
1264
431
  }
1265
1266
535
  for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
1267
194
    elList[el++] = (pPce->SideElementIsCpe[i]) ? ID_CPE : ID_SCE;
1268
194
  }
1269
1270
690
  for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
1271
349
    elList[el++] = (pPce->BackElementIsCpe[i]) ? ID_CPE : ID_SCE;
1272
349
  }
1273
1274
484
  for (i = 0; i < pPce->NumLfeChannelElements; i += 1) {
1275
143
    elList[el++] = ID_LFE;
1276
143
  }
1277
1278
  /* Find an corresponding channel configuration if possible */
1279
341
  switch (pPce->NumChannels) {
1280
84
    case 1:
1281
111
    case 2:
1282
      /* One and two channels have no alternatives. */
1283
111
      *pChMapIdx = pPce->NumChannels;
1284
111
      break;
1285
49
    case 3:
1286
89
    case 4:
1287
112
    case 5:
1288
131
    case 6: { /* Test if the number of channels can be used as channel config:
1289
               */
1290
131
      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
1291
      /* Create a PCE for the config to test ... */
1292
131
      CProgramConfig_GetDefault(tmpPce, pPce->NumChannels);
1293
      /* ... and compare it with the given one. */
1294
131
      *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE))
1295
131
                       ? pPce->NumChannels
1296
131
                       : 0;
1297
      /* If compare result is 0 or 1 we can be sure that it is channel
1298
       * config 11. */
1299
131
      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
1300
131
    } break;
1301
13
    case 7: {
1302
13
      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
1303
      /* Create a PCE for the config to test ... */
1304
13
      CProgramConfig_GetDefault(tmpPce, 11);
1305
      /* ... and compare it with the given one. */
1306
13
      *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) ? 11 : 0;
1307
      /* If compare result is 0 or 1 we can be sure that it is channel
1308
       * config 11. */
1309
13
      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
1310
13
    } break;
1311
79
    case 8: { /* Try the four possible 7.1ch configurations. One after the
1312
                 other. */
1313
79
      UCHAR testCfg[4] = {32, 14, 12, 7};
1314
79
      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
1315
395
      for (i = 0; i < 4; i += 1) {
1316
        /* Create a PCE for the config to test ... */
1317
316
        CProgramConfig_GetDefault(tmpPce, testCfg[i]);
1318
        /* ... and compare it with the given one. */
1319
316
        if (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) {
1320
          /* If the compare result is 0 or 1 than the two channel configurations
1321
           * match. */
1322
          /* Explicit mapping of 7.1 side channel configuration to 7.1 rear
1323
           * channel mapping. */
1324
6
          *pChMapIdx = (testCfg[i] == 32) ? 12 : testCfg[i];
1325
6
        }
1326
316
      }
1327
79
      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
1328
79
    } break;
1329
7
    default:
1330
      /* The PCE does not match any predefined channel configuration. */
1331
7
      *pChMapIdx = 0;
1332
7
      break;
1333
341
  }
1334
1335
341
  return el;
1336
341
}
1337
1338
11.9k
static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs) {
1339
11.9k
  int tmp = 0;
1340
1341
11.9k
  tmp = FDKreadBits(bs, 5);
1342
11.9k
  if (tmp == AOT_ESCAPE) {
1343
8.96k
    int tmp2 = FDKreadBits(bs, 6);
1344
8.96k
    tmp = 32 + tmp2;
1345
8.96k
  }
1346
1347
11.9k
  return (AUDIO_OBJECT_TYPE)tmp;
1348
11.9k
}
1349
1350
18.2k
static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits) {
1351
18.2k
  INT sampleRate;
1352
18.2k
  int idx;
1353
1354
18.2k
  idx = FDKreadBits(bs, nBits);
1355
18.2k
  if (idx == (1 << nBits) - 1) {
1356
1.09k
    if (FDKgetValidBits(bs) < 24) {
1357
10
      return 0;
1358
10
    }
1359
1.08k
    sampleRate = FDKreadBits(bs, 24);
1360
17.2k
  } else {
1361
17.2k
    sampleRate = SamplingRateTable[idx];
1362
17.2k
  }
1363
1364
18.2k
  *index = idx;
1365
1366
18.2k
  return sampleRate;
1367
18.2k
}
1368
1369
static TRANSPORTDEC_ERROR GaSpecificConfig_Parse(CSGaSpecificConfig *self,
1370
                                                 CSAudioSpecificConfig *asc,
1371
                                                 HANDLE_FDK_BITSTREAM bs,
1372
1.62k
                                                 UINT ascStartAnchor) {
1373
1.62k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
1374
1375
1.62k
  self->m_frameLengthFlag = FDKreadBits(bs, 1);
1376
1377
1.62k
  self->m_dependsOnCoreCoder = FDKreadBits(bs, 1);
1378
1379
1.62k
  if (self->m_dependsOnCoreCoder) self->m_coreCoderDelay = FDKreadBits(bs, 14);
1380
1381
1.62k
  self->m_extensionFlag = FDKreadBits(bs, 1);
1382
1383
1.62k
  if (asc->m_channelConfiguration == 0) {
1384
531
    CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor);
1385
531
  }
1386
1387
1.62k
  if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
1388
43
    self->m_layer = FDKreadBits(bs, 3);
1389
43
  }
1390
1391
1.62k
  if (self->m_extensionFlag) {
1392
335
    if (asc->m_aot == AOT_ER_BSAC) {
1393
24
      self->m_numOfSubFrame = FDKreadBits(bs, 5);
1394
24
      self->m_layerLength = FDKreadBits(bs, 11);
1395
24
    }
1396
1397
335
    if ((asc->m_aot == AOT_ER_AAC_LC) || (asc->m_aot == AOT_ER_AAC_LTP) ||
1398
335
        (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD)) {
1399
73
      asc->m_vcb11Flag = FDKreadBits(bs, 1); /* aacSectionDataResilienceFlag */
1400
73
      asc->m_rvlcFlag =
1401
73
          FDKreadBits(bs, 1); /* aacScalefactorDataResilienceFlag */
1402
73
      asc->m_hcrFlag = FDKreadBits(bs, 1); /* aacSpectralDataResilienceFlag */
1403
73
    }
1404
1405
335
    self->m_extensionFlag3 = FDKreadBits(bs, 1);
1406
335
  }
1407
1.62k
  return (ErrorStatus);
1408
1.62k
}
1409
1410
1.65k
static INT skipSbrHeader(HANDLE_FDK_BITSTREAM hBs, int isUsac) {
1411
  /* Dummy parse SbrDfltHeader() */
1412
1.65k
  INT dflt_header_extra1, dflt_header_extra2, bitsToSkip = 0;
1413
1414
1.65k
  if (!isUsac) {
1415
1.48k
    bitsToSkip = 6;
1416
1.48k
    FDKpushFor(hBs, 6); /* amp res 1, xover freq 3, reserved 2 */
1417
1.48k
  }
1418
1.65k
  bitsToSkip += 8;
1419
1.65k
  FDKpushFor(hBs, 8); /* start / stop freq */
1420
1.65k
  bitsToSkip += 2;
1421
1.65k
  dflt_header_extra1 = FDKreadBit(hBs);
1422
1.65k
  dflt_header_extra2 = FDKreadBit(hBs);
1423
1.65k
  bitsToSkip += 5 * dflt_header_extra1 + 6 * dflt_header_extra2;
1424
1.65k
  FDKpushFor(hBs, 5 * dflt_header_extra1 + 6 * dflt_header_extra2);
1425
1426
1.65k
  return bitsToSkip;
1427
1.65k
}
1428
1429
static INT ld_sbr_header(CSAudioSpecificConfig *asc, const INT dsFactor,
1430
710
                         HANDLE_FDK_BITSTREAM hBs, CSTpCallBacks *cb) {
1431
710
  const int channelConfiguration = asc->m_channelConfiguration;
1432
710
  int i = 0, j = 0;
1433
710
  INT error = 0;
1434
710
  MP4_ELEMENT_ID element = ID_NONE;
1435
1436
  /* check whether the channelConfiguration is defined in
1437
   * channel_configuration_array */
1438
710
  if (channelConfiguration < 0 ||
1439
710
      channelConfiguration > (INT)(sizeof(channel_configuration_array) /
1440
710
                                       sizeof(MP4_ELEMENT_ID **) -
1441
710
                                   1)) {
1442
0
    return TRANSPORTDEC_PARSE_ERROR;
1443
0
  }
1444
1445
  /* read elements of the passed channel_configuration until there is ID_NONE */
1446
1.97k
  while ((element = channel_configuration_array[channelConfiguration][j]) !=
1447
1.97k
         ID_NONE) {
1448
    /* Setup LFE element for upsampling too. This is essential especially for
1449
     * channel configs where the LFE element is not at the last position for
1450
     * example in channel config 13 or 14. It leads to memory leaks if the setup
1451
     * of the LFE element would be done later in the core. */
1452
1.42k
    if (element == ID_SCE || element == ID_CPE || element == ID_LFE) {
1453
1.42k
      error |= cb->cbSbr(
1454
1.42k
          cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor,
1455
1.42k
          asc->m_extensionSamplingFrequency / dsFactor,
1456
1.42k
          asc->m_samplesPerFrame / dsFactor, AOT_ER_AAC_ELD, element, i++, 0, 0,
1457
1.42k
          asc->configMode, &asc->SbrConfigChanged, dsFactor);
1458
1.42k
      if (error != TRANSPORTDEC_OK) {
1459
168
        goto bail;
1460
168
      }
1461
1.42k
    }
1462
1.26k
    j++;
1463
1.26k
  }
1464
710
bail:
1465
710
  return error;
1466
710
}
1467
1468
static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
1469
                                                  HANDLE_FDK_BITSTREAM hBs,
1470
1.42k
                                                  CSTpCallBacks *cb) {
1471
1.42k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
1472
1.42k
  CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
1473
1.42k
  UINT eldExtType;
1474
1.42k
  int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
1475
1.42k
                           sbrIndex, eldExtCnt = 0;
1476
1477
1.42k
  unsigned char downscale_fill_nibble;
1478
1479
1.42k
  FDKmemclear(esc, sizeof(CSEldSpecificConfig));
1480
1481
1.42k
  esc->m_frameLengthFlag = FDKreadBits(hBs, 1);
1482
1.42k
  if (esc->m_frameLengthFlag) {
1483
686
    asc->m_samplesPerFrame = 480;
1484
742
  } else {
1485
742
    asc->m_samplesPerFrame = 512;
1486
742
  }
1487
1488
1.42k
  asc->m_vcb11Flag = FDKreadBits(hBs, 1);
1489
1.42k
  asc->m_rvlcFlag = FDKreadBits(hBs, 1);
1490
1.42k
  asc->m_hcrFlag = FDKreadBits(hBs, 1);
1491
1492
1.42k
  esc->m_sbrPresentFlag = FDKreadBits(hBs, 1);
1493
1494
1.42k
  if (esc->m_sbrPresentFlag == 1) {
1495
847
    esc->m_sbrSamplingRate =
1496
847
        FDKreadBits(hBs, 1); /* 0: single rate, 1: dual rate */
1497
847
    esc->m_sbrCrcFlag = FDKreadBits(hBs, 1);
1498
1499
847
    asc->m_extensionSamplingFrequency = asc->m_samplingFrequency
1500
847
                                        << esc->m_sbrSamplingRate;
1501
1502
847
    if (cb->cbSbr != NULL) {
1503
      /* ELD reduced delay mode: LD-SBR initialization has to know the downscale
1504
         information. Postpone LD-SBR initialization and read ELD extension
1505
         information first. */
1506
847
      switch (asc->m_channelConfiguration) {
1507
312
        case 1:
1508
432
        case 2:
1509
432
          numSbrHeader = 1;
1510
432
          break;
1511
134
        case 3:
1512
134
          numSbrHeader = 2;
1513
134
          break;
1514
32
        case 4:
1515
72
        case 5:
1516
107
        case 6:
1517
107
          numSbrHeader = 3;
1518
107
          break;
1519
63
        case 7:
1520
77
        case 11:
1521
100
        case 12:
1522
115
        case 14:
1523
115
          numSbrHeader = 4;
1524
115
          break;
1525
59
        default:
1526
59
          numSbrHeader = 0;
1527
59
          break;
1528
847
      }
1529
2.32k
      for (sbrIndex = 0; sbrIndex < numSbrHeader; sbrIndex++) {
1530
1.48k
        ldSbrLen += skipSbrHeader(hBs, 0);
1531
1.48k
      }
1532
847
    } else {
1533
0
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
1534
0
    }
1535
847
  }
1536
1.42k
  esc->m_useLdQmfTimeAlign = 0;
1537
1538
  /* new ELD syntax */
1539
1.42k
  eldExtLenSum = FDKgetValidBits(hBs);
1540
1.42k
  esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
1541
  /* parse ExtTypeConfigData */
1542
2.69k
  while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
1543
2.69k
         ((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) {
1544
1.55k
    eldExtLen = len = FDKreadBits(hBs, 4);
1545
1.55k
    if (len == 0xf) {
1546
168
      len = FDKreadBits(hBs, 8);
1547
168
      eldExtLen += len;
1548
1549
168
      if (len == 0xff) {
1550
98
        len = FDKreadBits(hBs, 16);
1551
98
        eldExtLen += len;
1552
98
      }
1553
168
    }
1554
1555
1.55k
    switch (eldExtType) {
1556
899
      case ELDEXT_LDSAC:
1557
899
        esc->m_useLdQmfTimeAlign = 1;
1558
899
        if (cb->cbSsc != NULL) {
1559
899
          ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
1560
899
              cb->cbSscData, hBs, asc->m_aot,
1561
899
              asc->m_samplingFrequency << esc->m_sbrSamplingRate,
1562
899
              asc->m_samplesPerFrame << esc->m_sbrSamplingRate,
1563
899
              asc->m_channelConfiguration, 1, /* stereoConfigIndex */
1564
899
              -1, /* nTimeSlots: read from bitstream */
1565
899
              eldExtLen, asc->configMode, &asc->SacConfigChanged);
1566
899
          if (ErrorStatus != TRANSPORTDEC_OK) {
1567
221
            return TRANSPORTDEC_PARSE_ERROR;
1568
221
          }
1569
678
          if (esc->m_downscaledSamplingFrequency != asc->m_samplingFrequency) {
1570
21
            return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled
1571
                                                       mode not allowed */
1572
21
          }
1573
657
          break;
1574
678
        }
1575
1576
0
        FDK_FALLTHROUGH;
1577
266
      default:
1578
1.55M
        for (cnt = 0; cnt < eldExtLen; cnt++) {
1579
1.55M
          FDKreadBits(hBs, 8);
1580
1.55M
        }
1581
266
        break;
1582
1583
385
      case ELDEXT_DOWNSCALEINFO:
1584
385
        UCHAR tmpDownscaleFreqIdx;
1585
385
        esc->m_downscaledSamplingFrequency =
1586
385
            getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
1587
385
        if (esc->m_downscaledSamplingFrequency == 0 ||
1588
385
            esc->m_downscaledSamplingFrequency > 96000) {
1589
22
          return TRANSPORTDEC_PARSE_ERROR;
1590
22
        }
1591
363
        downscale_fill_nibble = FDKreadBits(hBs, 4);
1592
363
        if (downscale_fill_nibble != 0x0) {
1593
16
          return TRANSPORTDEC_PARSE_ERROR;
1594
16
        }
1595
347
        if (esc->m_useLdQmfTimeAlign == 1) {
1596
4
          return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled
1597
                                                     mode not allowed */
1598
4
        }
1599
343
        break;
1600
1.55k
    }
1601
1.55k
  }
1602
1.14k
  if (eldExtType != ELDEXT_TERM) {
1603
18
    return TRANSPORTDEC_PARSE_ERROR;
1604
18
  }
1605
1606
1.12k
  if ((INT)FDKgetValidBits(hBs) < 0) {
1607
135
    return TRANSPORTDEC_PARSE_ERROR;
1608
135
  }
1609
1610
991
  if (esc->m_sbrPresentFlag == 1 && numSbrHeader != 0) {
1611
725
    INT dsFactor = 1; /* Downscale factor must be 1 or even for SBR */
1612
725
    if (esc->m_downscaledSamplingFrequency != 0) {
1613
725
      if (asc->m_samplingFrequency % esc->m_downscaledSamplingFrequency != 0) {
1614
11
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
1615
11
      }
1616
714
      dsFactor = asc->m_samplingFrequency / esc->m_downscaledSamplingFrequency;
1617
714
      if (dsFactor != 1 && (dsFactor)&1) {
1618
4
        return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* SBR needs an even downscale
1619
                                                   factor */
1620
4
      }
1621
710
      if (dsFactor != 1 && dsFactor != 2 && dsFactor != 4) {
1622
47
        dsFactor = 1; /* don't apply dsf for not yet supported even dsfs */
1623
47
      }
1624
710
      if ((INT)asc->m_samplesPerFrame % dsFactor != 0) {
1625
0
        return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* frameSize/dsf must be an
1626
                                                   integer number */
1627
0
      }
1628
710
    }
1629
710
    eldExtLenSum = eldExtLenSum - FDKgetValidBits(hBs);
1630
710
    FDKpushBack(hBs, eldExtLenSum + ldSbrLen);
1631
710
    if (0 != ld_sbr_header(asc, dsFactor, hBs, cb)) {
1632
168
      return TRANSPORTDEC_PARSE_ERROR;
1633
168
    }
1634
542
    FDKpushFor(hBs, eldExtLenSum);
1635
542
  }
1636
808
  return (ErrorStatus);
1637
991
}
1638
1639
/*
1640
Subroutine to store config in UCHAR buffer. Bit stream position does not change.
1641
*/
1642
static UINT StoreConfigAsBitstream(
1643
    HANDLE_FDK_BITSTREAM hBs, const INT configSize_bits, /* If < 0 (> 0) config
1644
                                                            to read is before
1645
                                                            (after) current bit
1646
                                                            stream position. */
1647
7.63k
    UCHAR *configTargetBuffer, const USHORT configTargetBufferSize_bytes) {
1648
7.63k
  FDK_BITSTREAM usacConf;
1649
7.63k
  UINT const nBits = fAbs(configSize_bits);
1650
7.63k
  UINT j, tmp;
1651
1652
7.63k
  if (nBits > 8 * (UINT)configTargetBufferSize_bytes) {
1653
15
    return 1;
1654
15
  }
1655
7.61k
  FDKmemclear(configTargetBuffer, configTargetBufferSize_bytes);
1656
1657
7.61k
  FDKinitBitStream(&usacConf, configTargetBuffer, configTargetBufferSize_bytes,
1658
7.61k
                   nBits, BS_WRITER);
1659
7.61k
  if (configSize_bits < 0) {
1660
7.61k
    FDKpushBack(hBs, nBits);
1661
7.61k
  }
1662
121k
  for (j = nBits; j > 31; j -= 32) {
1663
113k
    tmp = FDKreadBits(hBs, 32);
1664
113k
    FDKwriteBits(&usacConf, tmp, 32);
1665
113k
  }
1666
7.61k
  if (j > 0) {
1667
7.33k
    tmp = FDKreadBits(hBs, j);
1668
7.33k
    FDKwriteBits(&usacConf, tmp, j);
1669
7.33k
  }
1670
7.61k
  FDKsyncCache(&usacConf);
1671
7.61k
  if (configSize_bits > 0) {
1672
0
    FDKpushBack(hBs, nBits);
1673
0
  }
1674
1675
7.61k
  return 0;
1676
7.63k
}
1677
1678
/* maps coreSbrFrameLengthIndex to coreCoderFrameLength */
1679
static const USHORT usacFrameLength[8] = {768, 1024, 2048, 2048, 4096, 0, 0, 0};
1680
/* maps coreSbrFrameLengthIndex to sbrRatioIndex */
1681
static const UCHAR sbrRatioIndex[8] = {0, 0, 2, 3, 1, 0, 0, 0};
1682
1683
/*
1684
  subroutine for parsing extension element configuration:
1685
  UsacExtElementConfig() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 14
1686
  rsv603daExtElementConfig() q.v. ISO/IEC DIS 23008-3 Table 13
1687
*/
1688
static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
1689
                                           HANDLE_FDK_BITSTREAM hBs,
1690
                                           const CSTpCallBacks *cb,
1691
                                           const UCHAR numSignalsInGroup,
1692
                                           const UINT coreFrameLength,
1693
                                           const int subStreamIndex,
1694
47.7k
                                           const AUDIO_OBJECT_TYPE aot) {
1695
47.7k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
1696
1697
47.7k
  UINT usacExtElementType = escapedValue(hBs, 4, 8, 16);
1698
1699
  /* recurve extension elements which are invalid for USAC */
1700
47.7k
  if (aot == AOT_USAC) {
1701
47.7k
    switch (usacExtElementType) {
1702
1.31k
      case ID_EXT_ELE_FILL:
1703
3.77k
      case ID_EXT_ELE_MPEGS:
1704
4.06k
      case ID_EXT_ELE_SAOC:
1705
7.52k
      case ID_EXT_ELE_AUDIOPREROLL:
1706
38.2k
      case ID_EXT_ELE_UNI_DRC:
1707
38.2k
        break;
1708
9.45k
      default:
1709
9.45k
        usacExtElementType = ID_EXT_ELE_UNKNOWN;
1710
9.45k
        break;
1711
47.7k
    }
1712
47.7k
  }
1713
1714
47.7k
  int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16);
1715
47.7k
  extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength;
1716
47.7k
  INT bsAnchor;
1717
1718
47.7k
  if (FDKreadBit(hBs)) /* usacExtElementDefaultLengthPresent */
1719
10.9k
    extElement->usacExtElementDefaultLength = escapedValue(hBs, 8, 16, 0) + 1;
1720
36.7k
  else
1721
36.7k
    extElement->usacExtElementDefaultLength = 0;
1722
1723
47.7k
  extElement->usacExtElementPayloadFrag = FDKreadBit(hBs);
1724
1725
47.7k
  bsAnchor = (INT)FDKgetValidBits(hBs);
1726
1727
47.7k
  switch (usacExtElementType) {
1728
9.45k
    case ID_EXT_ELE_UNKNOWN:
1729
10.7k
    case ID_EXT_ELE_FILL:
1730
10.7k
      break;
1731
3.45k
    case ID_EXT_ELE_AUDIOPREROLL:
1732
      /* No configuration element */
1733
3.45k
      extElement->usacExtElementHasAudioPreRoll = 1;
1734
3.45k
      break;
1735
30.7k
    case ID_EXT_ELE_UNI_DRC: {
1736
30.7k
      if (cb->cbUniDrc != NULL) {
1737
30.7k
        ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
1738
30.7k
            cb->cbUniDrcData, hBs, usacExtElementConfigLength,
1739
30.7k
            0, /* uniDrcConfig */
1740
30.7k
            subStreamIndex, 0, aot);
1741
30.7k
        if (ErrorStatus != TRANSPORTDEC_OK) {
1742
0
          return ErrorStatus;
1743
0
        }
1744
30.7k
      }
1745
30.7k
    } break;
1746
30.7k
    default:
1747
2.75k
      usacExtElementType = ID_EXT_ELE_UNKNOWN;
1748
2.75k
      break;
1749
47.7k
  }
1750
47.7k
  extElement->usacExtElementType = (USAC_EXT_ELEMENT_TYPE)usacExtElementType;
1751
1752
  /* Adjust bit stream position. This is required because of byte alignment and
1753
   * unhandled extensions. */
1754
47.7k
  {
1755
47.7k
    INT left_bits = (usacExtElementConfigLength << 3) -
1756
47.7k
                    (bsAnchor - (INT)FDKgetValidBits(hBs));
1757
47.7k
    if (left_bits >= 0) {
1758
46.6k
      FDKpushFor(hBs, left_bits);
1759
46.6k
    } else {
1760
      /* parsed too many bits */
1761
1.03k
      ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
1762
1.03k
    }
1763
47.7k
  }
1764
1765
47.7k
  return ErrorStatus;
1766
47.7k
}
1767
1768
/*
1769
  subroutine for parsing the USAC / RSVD60 configuration extension:
1770
  UsacConfigExtension() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 15
1771
  rsv603daConfigExtension() q.v. ISO/IEC DIS 23008-3 Table 14
1772
*/
1773
static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
1774
                                          HANDLE_FDK_BITSTREAM hBs,
1775
2.43k
                                          const CSTpCallBacks *cb) {
1776
2.43k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
1777
1778
2.43k
  int numConfigExtensions;
1779
2.43k
  UINT usacConfigExtType;
1780
2.43k
  int usacConfigExtLength;
1781
2.43k
  int loudnessInfoSetIndex =
1782
2.43k
      -1; /* index of loudnessInfoSet config extension. -1 if not contained. */
1783
2.43k
  int tmp_subStreamIndex = 0;
1784
2.43k
  AUDIO_OBJECT_TYPE tmp_aot = AOT_USAC;
1785
1786
2.43k
  numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1;
1787
7.72k
  for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
1788
5.73k
    INT nbits;
1789
5.73k
    int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs);
1790
5.73k
    usacConfigExtType = escapedValue(hBs, 4, 8, 16);
1791
5.73k
    usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16);
1792
1793
    /* Start bit position of config extension */
1794
5.73k
    nbits = (INT)FDKgetValidBits(hBs);
1795
1796
    /* Return an error in case the bitbuffer fill level is too low. */
1797
5.73k
    if (nbits < usacConfigExtLength * 8) {
1798
53
      return TRANSPORTDEC_PARSE_ERROR;
1799
53
    }
1800
1801
5.67k
    switch (usacConfigExtType) {
1802
1.46k
      case ID_CONFIG_EXT_FILL:
1803
2.42k
        for (int i = 0; i < usacConfigExtLength; i++) {
1804
970
          if (FDKreadBits(hBs, 8) != 0xa5) {
1805
12
            return TRANSPORTDEC_PARSE_ERROR;
1806
12
          }
1807
970
        }
1808
1.45k
        break;
1809
3.43k
      case ID_CONFIG_EXT_LOUDNESS_INFO: {
1810
3.43k
        if (cb->cbUniDrc != NULL) {
1811
3.43k
          ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
1812
3.43k
              cb->cbUniDrcData, hBs, usacConfigExtLength,
1813
3.43k
              1, /* loudnessInfoSet */
1814
3.43k
              tmp_subStreamIndex, loudnessInfoSetConfigExtensionPosition,
1815
3.43k
              tmp_aot);
1816
3.43k
          if (ErrorStatus != TRANSPORTDEC_OK) {
1817
0
            return ErrorStatus;
1818
0
          }
1819
3.43k
          loudnessInfoSetIndex = confExtIdx;
1820
3.43k
        }
1821
3.43k
      } break;
1822
3.43k
      default:
1823
783
        break;
1824
5.67k
    }
1825
1826
    /* Skip remaining bits. If too many bits were parsed, assume error. */
1827
5.66k
    usacConfigExtLength =
1828
5.66k
        8 * usacConfigExtLength - (nbits - (INT)FDKgetValidBits(hBs));
1829
5.66k
    if (usacConfigExtLength < 0) {
1830
373
      return TRANSPORTDEC_PARSE_ERROR;
1831
373
    }
1832
5.29k
    FDKpushFor(hBs, usacConfigExtLength);
1833
5.29k
  }
1834
1835
1.99k
  if (loudnessInfoSetIndex == -1 && cb->cbUniDrc != NULL) {
1836
    /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding
1837
     * an empty config extension */
1838
75
    ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
1839
75
        cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, tmp_subStreamIndex,
1840
75
        0, tmp_aot);
1841
75
    if (ErrorStatus != TRANSPORTDEC_OK) {
1842
0
      return ErrorStatus;
1843
0
    }
1844
75
  }
1845
1846
1.99k
  return ErrorStatus;
1847
1.99k
}
1848
1849
/* This function unifies decoder config parsing of USAC and RSV60:
1850
   rsv603daDecoderConfig() ISO/IEC DIS 23008-3   Table 8
1851
   UsacDecoderConfig()     ISO/IEC FDIS 23003-3  Table 6
1852
  */
1853
static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
1854
    CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs,
1855
7.07k
    const CSTpCallBacks *cb) {
1856
7.07k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
1857
7.07k
  CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
1858
7.07k
  int i, numberOfElements;
1859
7.07k
  int channelElementIdx =
1860
7.07k
      0; /* index for elements which contain audio channels (sce, cpe, lfe) */
1861
7.07k
  SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0};
1862
7.07k
  int uniDrcElement =
1863
7.07k
      -1; /* index of uniDrc extension element. -1 if not contained. */
1864
1865
7.07k
  numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1;
1866
7.07k
  usc->m_usacNumElements = numberOfElements;
1867
7.07k
  if (numberOfElements > TP_USAC_MAX_ELEMENTS) {
1868
16
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
1869
16
  }
1870
7.05k
  usc->m_nUsacChannels = 0;
1871
7.05k
  usc->m_channelConfigurationIndex = asc->m_channelConfiguration;
1872
1873
7.05k
  if (asc->m_aot == AOT_USAC) {
1874
7.05k
    sc_chan_config = sc_chan_config_tab[usc->m_channelConfigurationIndex];
1875
1876
7.05k
    if (sc_chan_config.nCh > (SCHAR)TP_USAC_MAX_SPEAKERS) {
1877
0
      return TRANSPORTDEC_PARSE_ERROR;
1878
0
    }
1879
7.05k
  }
1880
1881
58.1k
  for (i = 0; i < numberOfElements; i++) {
1882
52.3k
    MP4_ELEMENT_ID usacElementType = (MP4_ELEMENT_ID)(
1883
52.3k
        FDKreadBits(hBs, 2) | USAC_ID_BIT); /* set USAC_ID_BIT to map
1884
                                               usacElementType to
1885
                                               MP4_ELEMENT_ID enum */
1886
52.3k
    usc->element[i].usacElementType = usacElementType;
1887
1888
    /* sanity check: update element counter */
1889
52.3k
    if (asc->m_aot == AOT_USAC) {
1890
52.3k
      switch (usacElementType) {
1891
4.38k
        case ID_USAC_SCE:
1892
4.38k
          sc_chan_config.nSCE--;
1893
4.38k
          break;
1894
255
        case ID_USAC_CPE:
1895
255
          sc_chan_config.nCPE--;
1896
255
          break;
1897
2
        case ID_USAC_LFE:
1898
2
          sc_chan_config.nLFE--;
1899
2
          break;
1900
47.7k
        default:
1901
47.7k
          break;
1902
52.3k
      }
1903
52.3k
      if (usc->m_channelConfigurationIndex) {
1904
        /* sanity check: no element counter may be smaller zero */
1905
52.3k
        if (sc_chan_config.nCPE < 0 || sc_chan_config.nSCE < 0 ||
1906
52.3k
            sc_chan_config.nLFE < 0) {
1907
157
          return TRANSPORTDEC_PARSE_ERROR;
1908
157
        }
1909
52.3k
      }
1910
52.3k
    }
1911
1912
52.2k
    switch (usacElementType) {
1913
4.23k
      case ID_USAC_SCE:
1914
        /* UsacCoreConfig() ISO/IEC FDIS 23003-3  Table 10 */
1915
4.23k
        if (FDKreadBit(hBs)) { /* tw_mdct */
1916
2
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
1917
2
        }
1918
4.23k
        usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
1919
        /* end of UsacCoreConfig() */
1920
4.23k
        if (usc->m_sbrRatioIndex > 0) {
1921
1.02k
          if (cb->cbSbr == NULL) {
1922
0
            return TRANSPORTDEC_UNKOWN_ERROR;
1923
0
          }
1924
          /* SbrConfig() ISO/IEC FDIS 23003-3  Table 11 */
1925
1.02k
          usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
1926
1.02k
          usc->element[i].m_interTes = FDKreadBit(hBs);
1927
1.02k
          usc->element[i].m_pvc = FDKreadBit(hBs);
1928
1.02k
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
1929
1.02k
                        asc->m_extensionSamplingFrequency,
1930
1.02k
                        asc->m_samplesPerFrame, asc->m_aot, ID_SCE,
1931
1.02k
                        channelElementIdx, usc->element[i].m_harmonicSBR,
1932
1.02k
                        usc->element[i].m_stereoConfigIndex, asc->configMode,
1933
1.02k
                        &asc->SbrConfigChanged, 1)) {
1934
35
            return TRANSPORTDEC_PARSE_ERROR;
1935
35
          }
1936
          /* end of SbrConfig() */
1937
1.02k
        }
1938
4.20k
        usc->m_nUsacChannels += 1;
1939
4.20k
        channelElementIdx++;
1940
4.20k
        break;
1941
1942
244
      case ID_USAC_CPE:
1943
        /* UsacCoreConfig() ISO/IEC FDIS 23003-3  Table 10 */
1944
244
        if (FDKreadBit(hBs)) { /* tw_mdct */
1945
3
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
1946
3
        }
1947
241
        usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
1948
        /* end of UsacCoreConfig() */
1949
241
        if (usc->m_sbrRatioIndex > 0) {
1950
170
          if (cb->cbSbr == NULL) return TRANSPORTDEC_UNKOWN_ERROR;
1951
          /* SbrConfig() ISO/IEC FDIS 23003-3 */
1952
170
          usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
1953
170
          usc->element[i].m_interTes = FDKreadBit(hBs);
1954
170
          usc->element[i].m_pvc = FDKreadBit(hBs);
1955
170
          {
1956
170
            INT bitsToSkip = skipSbrHeader(hBs, 1);
1957
            /* read stereoConfigIndex */
1958
170
            usc->element[i].m_stereoConfigIndex = FDKreadBits(hBs, 2);
1959
            /* rewind */
1960
170
            FDKpushBack(hBs, bitsToSkip + 2);
1961
170
          }
1962
170
          {
1963
170
            MP4_ELEMENT_ID el_type =
1964
170
                (usc->element[i].m_stereoConfigIndex == 1 ||
1965
170
                 usc->element[i].m_stereoConfigIndex == 2)
1966
170
                    ? ID_SCE
1967
170
                    : ID_CPE;
1968
170
            if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
1969
170
                          asc->m_extensionSamplingFrequency,
1970
170
                          asc->m_samplesPerFrame, asc->m_aot, el_type,
1971
170
                          channelElementIdx, usc->element[i].m_harmonicSBR,
1972
170
                          usc->element[i].m_stereoConfigIndex, asc->configMode,
1973
170
                          &asc->SbrConfigChanged, 1)) {
1974
6
              return TRANSPORTDEC_PARSE_ERROR;
1975
6
            }
1976
170
          }
1977
          /* end of SbrConfig() */
1978
1979
164
          usc->element[i].m_stereoConfigIndex =
1980
164
              FDKreadBits(hBs, 2); /* Needed in RM5 syntax */
1981
1982
164
          if (usc->element[i].m_stereoConfigIndex > 0) {
1983
132
            if (cb->cbSsc != NULL) {
1984
132
              int samplesPerFrame = asc->m_samplesPerFrame;
1985
1986
132
              if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
1987
132
              if (usc->m_sbrRatioIndex == 2)
1988
42
                samplesPerFrame = (samplesPerFrame * 8) / 3;
1989
132
              if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
1990
1991
              /* Mps212Config() ISO/IEC FDIS 23003-3 */
1992
132
              if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
1993
132
                            asc->m_extensionSamplingFrequency, samplesPerFrame,
1994
132
                            1, /* only downmix channels (residual channels are
1995
                                  not counted) */
1996
132
                            usc->element[i].m_stereoConfigIndex,
1997
132
                            usc->m_coreSbrFrameLengthIndex,
1998
132
                            0, /* don't know the length */
1999
132
                            asc->configMode, &asc->SacConfigChanged)) {
2000
42
                return TRANSPORTDEC_PARSE_ERROR;
2001
42
              }
2002
              /* end of Mps212Config() */
2003
132
            } else {
2004
0
              return TRANSPORTDEC_UNKOWN_ERROR;
2005
0
            }
2006
132
          }
2007
164
        } else {
2008
71
          usc->element[i].m_stereoConfigIndex = 0;
2009
71
        }
2010
193
        usc->m_nUsacChannels += 2;
2011
2012
193
        channelElementIdx++;
2013
193
        break;
2014
2015
0
      case ID_USAC_LFE:
2016
0
        usc->element[i].m_noiseFilling = 0;
2017
0
        usc->m_nUsacChannels += 1;
2018
0
        if (usc->m_sbrRatioIndex > 0) {
2019
          /* Use SBR for upsampling */
2020
0
          if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
2021
0
          usc->element[i].m_harmonicSBR = (UCHAR)0;
2022
0
          usc->element[i].m_interTes = (UCHAR)0;
2023
0
          usc->element[i].m_pvc = (UCHAR)0;
2024
0
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
2025
0
                        asc->m_extensionSamplingFrequency,
2026
0
                        asc->m_samplesPerFrame, asc->m_aot, ID_LFE,
2027
0
                        channelElementIdx, usc->element[i].m_harmonicSBR,
2028
0
                        usc->element[i].m_stereoConfigIndex, asc->configMode,
2029
0
                        &asc->SbrConfigChanged, 1)) {
2030
0
            return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2031
0
          }
2032
0
        }
2033
0
        channelElementIdx++;
2034
0
        break;
2035
2036
47.7k
      case ID_USAC_EXT:
2037
47.7k
        ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0,
2038
47.7k
                                       asc->m_samplesPerFrame, 0, asc->m_aot);
2039
47.7k
        if (usc->element[i].extElement.usacExtElementType ==
2040
47.7k
            ID_EXT_ELE_UNI_DRC) {
2041
30.7k
          uniDrcElement = i;
2042
30.7k
        }
2043
2044
47.7k
        if (ErrorStatus) {
2045
1.03k
          return ErrorStatus;
2046
1.03k
        }
2047
46.6k
        break;
2048
2049
46.6k
      default:
2050
        /* non USAC-element encountered */
2051
0
        return TRANSPORTDEC_PARSE_ERROR;
2052
52.2k
    }
2053
52.2k
  }
2054
2055
5.78k
  if (asc->m_aot == AOT_USAC) {
2056
5.78k
    if (usc->m_channelConfigurationIndex) {
2057
      /* sanity check: all element counter must be zero */
2058
5.78k
      if (sc_chan_config.nCPE | sc_chan_config.nSCE | sc_chan_config.nLFE) {
2059
1.52k
        return TRANSPORTDEC_PARSE_ERROR;
2060
1.52k
      }
2061
5.78k
    } else {
2062
      /* sanity check: number of audio channels shall be equal to or smaller
2063
       * than the accumulated sum of all channels */
2064
0
      if ((INT)(-2 * sc_chan_config.nCPE - sc_chan_config.nSCE -
2065
0
                sc_chan_config.nLFE) < (INT)usc->numAudioChannels) {
2066
0
        return TRANSPORTDEC_PARSE_ERROR;
2067
0
      }
2068
0
    }
2069
5.78k
  }
2070
2071
4.26k
  if (uniDrcElement == -1 && cb->cbUniDrc != NULL) {
2072
    /* no uniDrcConfig contained. Clear the uniDrcConfig struct by feeding an
2073
     * empty extension element */
2074
2.06k
    int subStreamIndex = 0;
2075
2.06k
    ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
2076
2.06k
        cb->cbUniDrcData, NULL, 0, 0 /* uniDrcConfig */, subStreamIndex, 0,
2077
2.06k
        asc->m_aot);
2078
2.06k
    if (ErrorStatus != TRANSPORTDEC_OK) {
2079
0
      return ErrorStatus;
2080
0
    }
2081
2.06k
  }
2082
2083
4.26k
  return ErrorStatus;
2084
4.26k
}
2085
2086
/* Mapping of coreSbrFrameLengthIndex defined by Table 70 in ISO/IEC 23003-3 */
2087
static TRANSPORTDEC_ERROR UsacConfig_SetCoreSbrFrameLengthIndex(
2088
7.10k
    CSAudioSpecificConfig *asc, int coreSbrFrameLengthIndex) {
2089
7.10k
  int sbrRatioIndex_val;
2090
2091
7.10k
  if (coreSbrFrameLengthIndex > 4) {
2092
1
    return TRANSPORTDEC_PARSE_ERROR; /* reserved values */
2093
1
  }
2094
7.10k
  asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex = coreSbrFrameLengthIndex;
2095
7.10k
  asc->m_samplesPerFrame = usacFrameLength[coreSbrFrameLengthIndex];
2096
7.10k
  sbrRatioIndex_val = sbrRatioIndex[coreSbrFrameLengthIndex];
2097
7.10k
  asc->m_sc.m_usacConfig.m_sbrRatioIndex = sbrRatioIndex_val;
2098
2099
7.10k
  if (sbrRatioIndex_val > 0) {
2100
2.47k
    asc->m_sbrPresentFlag = 1;
2101
2.47k
    asc->m_extensionSamplingFrequency = asc->m_samplingFrequency;
2102
2.47k
    asc->m_extensionSamplingFrequencyIndex = asc->m_samplingFrequencyIndex;
2103
2.47k
    switch (sbrRatioIndex_val) {
2104
1.02k
      case 1: /* sbrRatio = 4:1 */
2105
1.02k
        asc->m_samplingFrequency >>= 2;
2106
1.02k
        asc->m_samplesPerFrame >>= 2;
2107
1.02k
        break;
2108
858
      case 2: /* sbrRatio = 8:3 */
2109
858
        asc->m_samplingFrequency = (asc->m_samplingFrequency * 3) / 8;
2110
858
        asc->m_samplesPerFrame = (asc->m_samplesPerFrame * 3) / 8;
2111
858
        break;
2112
592
      case 3: /* sbrRatio = 2:1 */
2113
592
        asc->m_samplingFrequency >>= 1;
2114
592
        asc->m_samplesPerFrame >>= 1;
2115
592
        break;
2116
0
      default:
2117
0
        return TRANSPORTDEC_PARSE_ERROR;
2118
2.47k
    }
2119
2.47k
    asc->m_samplingFrequencyIndex =
2120
2.47k
        getSamplingRateIndex(asc->m_samplingFrequency, 4);
2121
2.47k
  }
2122
2123
7.10k
  return TRANSPORTDEC_OK;
2124
7.10k
}
2125
2126
static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
2127
                                           HANDLE_FDK_BITSTREAM hBs,
2128
7.12k
                                           CSTpCallBacks *cb) {
2129
7.12k
  int usacSamplingFrequency, channelConfigurationIndex, coreSbrFrameLengthIndex;
2130
7.12k
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
2131
2132
  /* Start bit position of usacConfig */
2133
7.12k
  INT nbits = (INT)FDKgetValidBits(hBs);
2134
2135
7.12k
  usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
2136
7.12k
  if (usacSamplingFrequency == 0 || usacSamplingFrequency > 96000) {
2137
22
    return TRANSPORTDEC_PARSE_ERROR;
2138
22
  }
2139
7.10k
  asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
2140
2141
7.10k
  coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
2142
7.10k
  if (UsacConfig_SetCoreSbrFrameLengthIndex(asc, coreSbrFrameLengthIndex) !=
2143
7.10k
      TRANSPORTDEC_OK) {
2144
1
    return TRANSPORTDEC_PARSE_ERROR;
2145
1
  }
2146
2147
7.10k
  channelConfigurationIndex = FDKreadBits(hBs, 5);
2148
7.10k
  if (channelConfigurationIndex > 2) {
2149
5
    return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
2150
                                        are supported */
2151
5
  }
2152
2153
7.09k
  if (channelConfigurationIndex == 0) {
2154
22
    return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
2155
                                        are supported */
2156
22
  }
2157
7.07k
  asc->m_channelConfiguration = channelConfigurationIndex;
2158
2159
7.07k
  err = UsacRsv60DecoderConfig_Parse(asc, hBs, cb);
2160
7.07k
  if (err != TRANSPORTDEC_OK) {
2161
2.81k
    return err;
2162
2.81k
  }
2163
2164
4.26k
  if (FDKreadBits(hBs, 1)) { /* usacConfigExtensionPresent */
2165
2.43k
    err = configExtension(&asc->m_sc.m_usacConfig, hBs, cb);
2166
2.43k
    if (err != TRANSPORTDEC_OK) {
2167
438
      return err;
2168
438
    }
2169
2.43k
  } else if (cb->cbUniDrc != NULL) {
2170
    /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding
2171
     * an empty config extension */
2172
1.82k
    err = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
2173
1.82k
        cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, 0, 0, asc->m_aot);
2174
1.82k
    if (err != TRANSPORTDEC_OK) {
2175
0
      return err;
2176
0
    }
2177
1.82k
  }
2178
2179
  /* sanity check whether number of channels signaled in UsacDecoderConfig()
2180
     matches the number of channels required by channelConfigurationIndex */
2181
3.82k
  if ((channelConfigurationIndex > 0) &&
2182
3.82k
      (sc_chan_config_tab[channelConfigurationIndex].nCh !=
2183
3.82k
       asc->m_sc.m_usacConfig.m_nUsacChannels)) {
2184
0
    return TRANSPORTDEC_PARSE_ERROR;
2185
0
  }
2186
2187
  /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */
2188
3.82k
  INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits;
2189
3.82k
  if (StoreConfigAsBitstream(hBs, configSize_bits,
2190
3.82k
                             asc->m_sc.m_usacConfig.UsacConfig,
2191
3.82k
                             TP_USAC_MAX_CONFIG_LEN)) {
2192
12
    return TRANSPORTDEC_PARSE_ERROR;
2193
12
  }
2194
3.81k
  asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits);
2195
2196
3.81k
  return err;
2197
3.82k
}
2198
2199
static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
2200
1.55k
    CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb) {
2201
1.55k
  TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN;
2202
1.55k
  INT bitsAvailable = (INT)FDKgetValidBits(bs);
2203
2204
8.61k
  while (bitsAvailable >= 11) {
2205
7.25k
    lastAscExt = ascExtId;
2206
7.25k
    ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
2207
7.25k
    bitsAvailable -= 11;
2208
2209
7.25k
    switch (ascExtId) {
2210
1.62k
      case ASCEXT_SBR: /* 0x2b7 */
2211
1.62k
        if ((self->m_extensionAudioObjectType != AOT_SBR) &&
2212
1.62k
            (bitsAvailable >= 5)) {
2213
1.45k
          self->m_extensionAudioObjectType = getAOT(bs);
2214
2215
1.45k
          if ((self->m_extensionAudioObjectType == AOT_SBR) ||
2216
1.45k
              (self->m_extensionAudioObjectType ==
2217
1.40k
               AOT_ER_BSAC)) { /* Get SBR extension configuration */
2218
492
            self->m_sbrPresentFlag = FDKreadBits(bs, 1);
2219
492
            if (self->m_aot == AOT_USAC && self->m_sbrPresentFlag > 0 &&
2220
492
                self->m_sc.m_usacConfig.m_sbrRatioIndex == 0) {
2221
0
              return TRANSPORTDEC_PARSE_ERROR;
2222
0
            }
2223
2224
492
            if (self->m_sbrPresentFlag == 1) {
2225
239
              self->m_extensionSamplingFrequency = getSampleRate(
2226
239
                  bs, &self->m_extensionSamplingFrequencyIndex, 4);
2227
2228
239
              if (self->m_extensionSamplingFrequency == 0 ||
2229
239
                  self->m_extensionSamplingFrequency > 96000) {
2230
22
                return TRANSPORTDEC_PARSE_ERROR;
2231
22
              }
2232
239
            }
2233
470
            if (self->m_extensionAudioObjectType == AOT_ER_BSAC) {
2234
422
              self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
2235
422
            }
2236
470
          }
2237
          /* Update counter because of variable length fields (AOT and sampling
2238
           * rate) */
2239
1.43k
          bitsAvailable = (INT)FDKgetValidBits(bs);
2240
1.43k
        }
2241
1.59k
        break;
2242
1.59k
      case ASCEXT_PS: /* 0x548 */
2243
800
        if ((lastAscExt == ASCEXT_SBR) &&
2244
800
            (self->m_extensionAudioObjectType == AOT_SBR) &&
2245
800
            (bitsAvailable > 0)) { /* Get PS extension configuration */
2246
118
          self->m_psPresentFlag = FDKreadBits(bs, 1);
2247
118
          bitsAvailable -= 1;
2248
118
        }
2249
800
        break;
2250
410
      case ASCEXT_MPS: /* 0x76a */
2251
410
        if (self->m_extensionAudioObjectType == AOT_MPEGS) break;
2252
340
        FDK_FALLTHROUGH;
2253
2.54k
      case ASCEXT_LDMPS: /* 0x7cc */
2254
2.54k
        if ((ascExtId == ASCEXT_LDMPS) &&
2255
2.54k
            (self->m_extensionAudioObjectType == AOT_LD_MPEGS))
2256
198
          break;
2257
2.34k
        if (bitsAvailable >= 1) {
2258
2.32k
          bitsAvailable -= 1;
2259
2.32k
          if (FDKreadBits(bs, 1)) { /* self->m_mpsPresentFlag */
2260
1.07k
            int sscLen = FDKreadBits(bs, 8);
2261
1.07k
            bitsAvailable -= 8;
2262
1.07k
            if (sscLen == 0xFF) {
2263
38
              sscLen += FDKreadBits(bs, 16);
2264
38
              bitsAvailable -= 16;
2265
38
            }
2266
1.07k
            FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next
2267
                                       extension if there is one. */
2268
2269
1.07k
            bitsAvailable -= sscLen * 8;
2270
1.07k
          }
2271
2.32k
        }
2272
2.34k
        break;
2273
2.05k
      case ASCEXT_SAOC:
2274
2.05k
        if ((ascExtId == ASCEXT_SAOC) &&
2275
2.05k
            (self->m_extensionAudioObjectType == AOT_SAOC))
2276
194
          break;
2277
1.86k
        if (FDKreadBits(bs, 1)) { /* saocPresent */
2278
1.09k
          int saocscLen = FDKreadBits(bs, 8);
2279
1.09k
          bitsAvailable -= 8;
2280
1.09k
          if (saocscLen == 0xFF) {
2281
31
            saocscLen += FDKreadBits(bs, 16);
2282
31
            bitsAvailable -= 16;
2283
31
          }
2284
1.09k
          FDKpushFor(bs, saocscLen);
2285
1.09k
          bitsAvailable -= saocscLen * 8;
2286
1.09k
        }
2287
1.86k
        break;
2288
166
      default:
2289
        /* Just ignore anything. */
2290
166
        return TRANSPORTDEC_OK;
2291
7.25k
    }
2292
7.25k
  }
2293
2294
1.36k
  return TRANSPORTDEC_OK;
2295
1.55k
}
2296
2297
/*
2298
 * API Functions
2299
 */
2300
2301
10.3k
void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc) {
2302
10.3k
  FDKmemclear(asc, sizeof(CSAudioSpecificConfig));
2303
2304
  /* Init all values that should not be zero. */
2305
10.3k
  asc->m_aot = AOT_NONE;
2306
10.3k
  asc->m_samplingFrequencyIndex = 0xf;
2307
10.3k
  asc->m_epConfig = -1;
2308
10.3k
  asc->m_extensionAudioObjectType = AOT_NULL_OBJECT;
2309
10.3k
  CProgramConfig_Init(&asc->m_progrConfigElement);
2310
10.3k
}
2311
2312
TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
2313
    CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
2314
    int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode,
2315
10.3k
    UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot) {
2316
10.3k
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
2317
10.3k
  UINT ascStartAnchor = FDKgetValidBits(bs);
2318
10.3k
  int frameLengthFlag = -1;
2319
2320
10.3k
  AudioSpecificConfig_Init(self);
2321
2322
10.3k
  self->configMode = configMode;
2323
10.3k
  self->AacConfigChanged = configChanged;
2324
10.3k
  self->SbrConfigChanged = configChanged;
2325
10.3k
  self->SacConfigChanged = configChanged;
2326
2327
10.3k
  if (m_aot != AOT_NULL_OBJECT) {
2328
0
    self->m_aot = m_aot;
2329
10.3k
  } else {
2330
10.3k
    self->m_aot = getAOT(bs);
2331
10.3k
    self->m_samplingFrequency =
2332
10.3k
        getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
2333
10.3k
    if (self->m_samplingFrequency <= 0 ||
2334
10.3k
        (self->m_samplingFrequency > 96000 && self->m_aot != 39) ||
2335
10.3k
        self->m_samplingFrequency > 4 * 96000) {
2336
37
      return TRANSPORTDEC_PARSE_ERROR;
2337
37
    }
2338
2339
10.2k
    self->m_channelConfiguration = FDKreadBits(bs, 4);
2340
2341
    /* MPEG-04 standard ISO/IEC 14496-3: channelConfiguration == 0 is reserved
2342
       in er_raw_data_block (table 4.19) and er_raw_data_block_eld (table 4.75)
2343
       MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration == 0 is not
2344
       permitted for AOT_ER_AAC_LC, AOT_ER_AAC_LTP, AOT_ER_AAC_LD,
2345
       AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */
2346
10.2k
    if ((self->m_channelConfiguration == 0) &&
2347
10.2k
        ((self->m_aot == AOT_ER_AAC_LC) || (self->m_aot == AOT_ER_AAC_LTP) ||
2348
981
         (self->m_aot == AOT_ER_AAC_LD) || (self->m_aot == AOT_ER_AAC_SCAL) ||
2349
981
         (self->m_aot == AOT_ER_AAC_ELD))) {
2350
17
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
2351
17
    }
2352
    /* MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration > 2 is not
2353
     * permitted for AOT_AAC_SCAL and AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */
2354
10.2k
    if ((self->m_channelConfiguration > 2) &&
2355
10.2k
        ((self->m_aot == AOT_AAC_SCAL) || (self->m_aot == AOT_ER_AAC_SCAL))) {
2356
4
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
2357
4
    }
2358
2359
    /* SBR extension ( explicit non-backwards compatible mode ) */
2360
10.2k
    self->m_sbrPresentFlag = 0;
2361
10.2k
    self->m_psPresentFlag = 0;
2362
2363
10.2k
    if (self->m_aot == AOT_SBR || self->m_aot == AOT_PS) {
2364
237
      self->m_extensionAudioObjectType = AOT_SBR;
2365
2366
237
      self->m_sbrPresentFlag = 1;
2367
237
      if (self->m_aot == AOT_PS) {
2368
70
        self->m_psPresentFlag = 1;
2369
70
      }
2370
2371
237
      self->m_extensionSamplingFrequency =
2372
237
          getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
2373
237
      if (self->m_extensionSamplingFrequency == 0 ||
2374
237
          self->m_extensionSamplingFrequency > 96000) {
2375
18
        return TRANSPORTDEC_PARSE_ERROR;
2376
18
      }
2377
219
      self->m_aot = getAOT(bs);
2378
2379
219
      switch (self->m_aot) {
2380
182
        case AOT_AAC_LC:
2381
182
          break;
2382
15
        case AOT_ER_BSAC:
2383
15
          break;
2384
22
        default:
2385
22
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
2386
219
      }
2387
2388
197
      if (self->m_aot == AOT_ER_BSAC) {
2389
15
        self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
2390
15
      }
2391
10.0k
    } else {
2392
10.0k
      self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
2393
10.0k
    }
2394
10.2k
  }
2395
2396
  /* Parse whatever specific configs */
2397
10.2k
  switch (self->m_aot) {
2398
1.36k
    case AOT_AAC_LC:
2399
1.38k
    case AOT_AAC_SCAL:
2400
1.40k
    case AOT_ER_AAC_LC:
2401
1.56k
    case AOT_ER_AAC_LD:
2402
1.57k
    case AOT_ER_AAC_SCAL:
2403
1.62k
    case AOT_ER_BSAC:
2404
1.62k
      if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig,
2405
1.62k
                                                self, bs, ascStartAnchor)) !=
2406
1.62k
          TRANSPORTDEC_OK) {
2407
0
        return (ErrorStatus);
2408
0
      }
2409
1.62k
      frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
2410
1.62k
      break;
2411
1
    case AOT_MPEGS:
2412
1
      if (cb->cbSsc != NULL) {
2413
1
        if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
2414
1
                      self->m_samplesPerFrame, self->m_channelConfiguration, 1,
2415
1
                      -1, /* nTimeSlots: read from bitstream */
2416
1
                      0,  /* don't know the length */
2417
1
                      self->configMode, &self->SacConfigChanged)) {
2418
1
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
2419
1
        }
2420
1
      } else {
2421
0
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
2422
0
      }
2423
0
      break;
2424
1.42k
    case AOT_ER_AAC_ELD:
2425
1.42k
      if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) !=
2426
1.42k
          TRANSPORTDEC_OK) {
2427
620
        return (ErrorStatus);
2428
620
      }
2429
808
      frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
2430
808
      self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
2431
808
      self->m_extensionSamplingFrequency =
2432
808
          (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate + 1) *
2433
808
          self->m_samplingFrequency;
2434
808
      break;
2435
7.12k
    case AOT_USAC:
2436
7.12k
      if ((ErrorStatus = UsacConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK) {
2437
3.31k
        return (ErrorStatus);
2438
3.31k
      }
2439
3.81k
      break;
2440
2441
3.81k
    default:
2442
42
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
2443
10.2k
  }
2444
2445
  /* Frame length */
2446
6.23k
  switch (self->m_aot) {
2447
1.36k
    case AOT_AAC_LC:
2448
1.38k
    case AOT_AAC_SCAL:
2449
1.40k
    case AOT_ER_AAC_LC:
2450
1.42k
    case AOT_ER_AAC_SCAL:
2451
1.46k
    case AOT_ER_BSAC:
2452
      /*case AOT_USAC:*/
2453
1.46k
      if (!frameLengthFlag)
2454
924
        self->m_samplesPerFrame = 1024;
2455
544
      else
2456
544
        self->m_samplesPerFrame = 960;
2457
1.46k
      break;
2458
153
    case AOT_ER_AAC_LD:
2459
153
      if (!frameLengthFlag)
2460
85
        self->m_samplesPerFrame = 512;
2461
68
      else
2462
68
        self->m_samplesPerFrame = 480;
2463
153
      break;
2464
4.61k
    default:
2465
4.61k
      break;
2466
6.23k
  }
2467
2468
6.23k
  switch (self->m_aot) {
2469
21
    case AOT_ER_AAC_LC:
2470
174
    case AOT_ER_AAC_LD:
2471
982
    case AOT_ER_AAC_ELD:
2472
1.00k
    case AOT_ER_AAC_SCAL:
2473
1.00k
    case AOT_ER_CELP:
2474
1.00k
    case AOT_ER_HVXC:
2475
1.04k
    case AOT_ER_BSAC:
2476
1.04k
      self->m_epConfig = FDKreadBits(bs, 2);
2477
2478
1.04k
      if (self->m_epConfig > 1) {
2479
11
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;  // EPCONFIG;
2480
11
      }
2481
1.03k
      break;
2482
5.19k
    default:
2483
5.19k
      break;
2484
6.23k
  }
2485
2486
6.22k
  if (fExplicitBackwardCompatible &&
2487
6.22k
      (self->m_aot == AOT_AAC_LC || self->m_aot == AOT_ER_AAC_LD ||
2488
6.22k
       self->m_aot == AOT_ER_BSAC)) {
2489
1.55k
    ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
2490
1.55k
  }
2491
2492
  /* Copy config() to asc->config[] buffer. */
2493
6.22k
  if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) {
2494
3.81k
    INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor;
2495
3.81k
    if (StoreConfigAsBitstream(bs, configSize_bits, self->config,
2496
3.81k
                               TP_USAC_MAX_CONFIG_LEN)) {
2497
3
      return TRANSPORTDEC_PARSE_ERROR;
2498
3
    }
2499
3.80k
    self->configBits = fAbs(configSize_bits);
2500
3.80k
  }
2501
2502
6.22k
  return (ErrorStatus);
2503
6.22k
}
2504
2505
static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
2506
    CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs, int audioMode,
2507
    CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
2508
0
) {
2509
0
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
2510
0
  CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
2511
0
  int elemIdx = 0;
2512
2513
0
  usc->element[elemIdx].m_stereoConfigIndex = 0;
2514
2515
0
  usc->m_usacNumElements = 1; /* Currently all extension elements are skipped
2516
                                 -> only one SCE or CPE. */
2517
2518
0
  switch (audioMode) {
2519
0
    case 0: /* mono: ID_USAC_SCE */
2520
0
      usc->element[elemIdx].usacElementType = ID_USAC_SCE;
2521
0
      usc->m_nUsacChannels = 1;
2522
0
      usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
2523
0
      if (usc->m_sbrRatioIndex > 0) {
2524
0
        if (cb == NULL) {
2525
0
          return ErrorStatus;
2526
0
        }
2527
0
        if (cb->cbSbr != NULL) {
2528
0
          usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
2529
0
          usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
2530
0
          usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
2531
0
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
2532
0
                        asc->m_extensionSamplingFrequency,
2533
0
                        asc->m_samplesPerFrame, asc->m_aot, ID_SCE, elemIdx,
2534
0
                        usc->element[elemIdx].m_harmonicSBR,
2535
0
                        usc->element[elemIdx].m_stereoConfigIndex,
2536
0
                        asc->configMode, &asc->SbrConfigChanged, 1)) {
2537
0
            return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2538
0
          }
2539
0
        }
2540
0
      }
2541
0
      break;
2542
0
    case 2: /* stereo: ID_USAC_CPE */
2543
0
      usc->element[elemIdx].usacElementType = ID_USAC_CPE;
2544
0
      usc->m_nUsacChannels = 2;
2545
0
      usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
2546
0
      if (usc->m_sbrRatioIndex > 0) {
2547
0
        usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
2548
0
        usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
2549
0
        usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
2550
0
        {
2551
0
          INT bitsToSkip = skipSbrHeader(hBs, 1);
2552
          /* read stereoConfigIndex */
2553
0
          usc->element[elemIdx].m_stereoConfigIndex = FDKreadBits(hBs, 2);
2554
          /* rewind */
2555
0
          FDKpushBack(hBs, bitsToSkip + 2);
2556
0
        }
2557
        /*
2558
        The application of the following tools is mutually exclusive per audio
2559
        stream configuration (see clause 5.3.2, xHE-AAC codec configuration):
2560
        - MPS212 parametric stereo tool with residual coding
2561
        (stereoConfigIndex>1); and
2562
        - QMF based Harmonic Transposer (harmonicSBR==1).
2563
        */
2564
0
        if ((usc->element[elemIdx].m_stereoConfigIndex > 1) &&
2565
0
            usc->element[elemIdx].m_harmonicSBR) {
2566
0
          return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2567
0
        }
2568
        /*
2569
        The 4:1 sbrRatio (sbrRatioIndex==1 in [11]) may only be employed:
2570
        - in mono operation; or
2571
        - in stereo operation if parametric stereo (MPS212) without residual
2572
        coding is applied, i.e. if stereoConfigIndex==1 (see clause 5.3.2,
2573
        xHE-AAC codec configuration).
2574
        */
2575
0
        if ((usc->m_sbrRatioIndex == 1) &&
2576
0
            (usc->element[elemIdx].m_stereoConfigIndex != 1)) {
2577
0
          return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2578
0
        }
2579
0
        if (cb == NULL) {
2580
0
          return ErrorStatus;
2581
0
        }
2582
0
        {
2583
0
          MP4_ELEMENT_ID el_type =
2584
0
              (usc->element[elemIdx].m_stereoConfigIndex == 1 ||
2585
0
               usc->element[elemIdx].m_stereoConfigIndex == 2)
2586
0
                  ? ID_SCE
2587
0
                  : ID_CPE;
2588
0
          if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
2589
0
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
2590
0
                        asc->m_extensionSamplingFrequency,
2591
0
                        asc->m_samplesPerFrame, asc->m_aot, el_type, elemIdx,
2592
0
                        usc->element[elemIdx].m_harmonicSBR,
2593
0
                        usc->element[elemIdx].m_stereoConfigIndex,
2594
0
                        asc->configMode, &asc->SbrConfigChanged, 1)) {
2595
0
            return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2596
0
          }
2597
0
        }
2598
0
        /*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
2599
0
        if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
2600
0
          if (cb->cbSsc != NULL) {
2601
0
            int samplesPerFrame = asc->m_samplesPerFrame;
2602
2603
0
            if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
2604
0
            if (usc->m_sbrRatioIndex == 2)
2605
0
              samplesPerFrame = (samplesPerFrame * 8) / 3;
2606
0
            if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
2607
2608
0
            ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
2609
0
                cb->cbSscData, hBs,
2610
0
                AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
2611
0
                asc->m_extensionSamplingFrequency, samplesPerFrame,
2612
0
                1, /* only downmix channels (residual channels are not
2613
                      counted) */
2614
0
                usc->element[elemIdx].m_stereoConfigIndex,
2615
0
                usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
2616
0
                asc->configMode, &asc->SacConfigChanged);
2617
0
          } else {
2618
            /* ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; */
2619
0
          }
2620
0
        }
2621
0
      }
2622
0
      break;
2623
0
    default:
2624
0
      return TRANSPORTDEC_PARSE_ERROR;
2625
0
  }
2626
2627
0
  return ErrorStatus;
2628
0
}
2629
2630
TRANSPORTDEC_ERROR Drm_xHEAACStaticConfig(
2631
    CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM bs, int audioMode,
2632
    CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
2633
0
) {
2634
0
  int coreSbrFrameLengthIndexDrm = FDKreadBits(bs, 2);
2635
0
  if (UsacConfig_SetCoreSbrFrameLengthIndex(
2636
0
          asc, coreSbrFrameLengthIndexDrm + 1) != TRANSPORTDEC_OK) {
2637
0
    return TRANSPORTDEC_PARSE_ERROR;
2638
0
  }
2639
2640
0
  asc->m_channelConfiguration = (audioMode) ? 2 : 1;
2641
2642
0
  if (Drm_xHEAACDecoderConfig(asc, bs, audioMode, cb) != TRANSPORTDEC_OK) {
2643
0
    return TRANSPORTDEC_PARSE_ERROR;
2644
0
  }
2645
2646
0
  return TRANSPORTDEC_OK;
2647
0
}
2648
2649
/* Mapping of DRM audio sampling rate field to MPEG usacSamplingFrequencyIndex
2650
 */
2651
const UCHAR mapSr2MPEGIdx[8] = {
2652
    0x1b, /*  9.6 kHz */
2653
    0x09, /* 12.0 kHz */
2654
    0x08, /* 16.0 kHz */
2655
    0x17, /* 19.2 kHz */
2656
    0x06, /* 24.0 kHz */
2657
    0x05, /* 32.0 kHz */
2658
    0x12, /* 38.4 kHz */
2659
    0x03  /* 48.0 kHz */
2660
};
2661
2662
TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
2663
    CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
2664
    CSTpCallBacks *cb, /* use cb == NULL to signal config check only mode */
2665
0
    UCHAR configMode, UCHAR configChanged) {
2666
0
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
2667
2668
0
  AudioSpecificConfig_Init(self);
2669
2670
0
  if ((INT)FDKgetValidBits(bs) < 16) {
2671
0
    ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2672
0
    goto bail;
2673
0
  } else {
2674
    /* DRM - Audio information data entity - type 9
2675
       - Short Id            2 bits (not part of the config buffer)
2676
       - Stream Id           2 bits (not part of the config buffer)
2677
       - audio coding        2 bits
2678
       - SBR flag            1 bit
2679
       - audio mode          2 bits
2680
       - audio sampling rate 3 bits
2681
       - text flag           1 bit
2682
       - enhancement flag    1 bit
2683
       - coder field         5 bits
2684
       - rfa                 1 bit  */
2685
2686
0
    int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;
2687
2688
0
    self->configMode = configMode;
2689
0
    self->AacConfigChanged = configChanged;
2690
0
    self->SbrConfigChanged = configChanged;
2691
0
    self->SacConfigChanged = configChanged;
2692
2693
    /* Read the SDC field */
2694
0
    audioCoding = FDKreadBits(bs, 2);
2695
0
    sbrFlag = FDKreadBits(bs, 1);
2696
0
    audioMode = FDKreadBits(bs, 2);
2697
0
    cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */
2698
2699
0
    FDKreadBits(bs, 2); /* Text and enhancement flag */
2700
0
    coderField = FDKreadBits(bs, 5);
2701
0
    FDKreadBits(bs, 1); /* rfa */
2702
2703
    /* Evaluate configuration and fill the ASC */
2704
0
    if (audioCoding == 3) {
2705
0
      sfIdx = (int)mapSr2MPEGIdx[cSamplingFreq];
2706
0
      sbrFlag = 0; /* rfa */
2707
0
    } else {
2708
0
      switch (cSamplingFreq) {
2709
0
        case 0: /*  8 kHz */
2710
0
          sfIdx = 11;
2711
0
          break;
2712
0
        case 1: /* 12 kHz */
2713
0
          sfIdx = 9;
2714
0
          break;
2715
0
        case 2: /* 16 kHz */
2716
0
          sfIdx = 8;
2717
0
          break;
2718
0
        case 3: /* 24 kHz */
2719
0
          sfIdx = 6;
2720
0
          break;
2721
0
        case 5: /* 48 kHz */
2722
0
          sfIdx = 3;
2723
0
          break;
2724
0
        case 4: /* reserved */
2725
0
        case 6: /* reserved */
2726
0
        case 7: /* reserved */
2727
0
        default:
2728
0
          ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2729
0
          goto bail;
2730
0
      }
2731
0
    }
2732
2733
0
    self->m_samplingFrequencyIndex = sfIdx;
2734
0
    self->m_samplingFrequency = SamplingRateTable[sfIdx];
2735
2736
0
    if (sbrFlag) {
2737
0
      UINT i;
2738
0
      int tmp = -1;
2739
0
      self->m_sbrPresentFlag = 1;
2740
0
      self->m_extensionAudioObjectType = AOT_SBR;
2741
0
      self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
2742
0
      for (i = 0;
2743
0
           i < (sizeof(SamplingRateTable) / sizeof(SamplingRateTable[0]));
2744
0
           i++) {
2745
0
        if (SamplingRateTable[i] == self->m_extensionSamplingFrequency) {
2746
0
          tmp = i;
2747
0
          break;
2748
0
        }
2749
0
      }
2750
0
      self->m_extensionSamplingFrequencyIndex = tmp;
2751
0
    }
2752
2753
0
    switch (audioCoding) {
2754
0
      case 0: /* AAC */
2755
0
        if ((coderField >> 2) && (audioMode != 1)) {
2756
0
          self->m_aot = AOT_DRM_SURROUND; /* Set pseudo AOT for Drm Surround */
2757
0
        } else {
2758
0
          self->m_aot = AOT_DRM_AAC; /* Set pseudo AOT for Drm AAC */
2759
0
        }
2760
0
        switch (audioMode) {
2761
0
          case 1: /* parametric stereo */
2762
0
            self->m_psPresentFlag = 1;
2763
0
            FDK_FALLTHROUGH;
2764
0
          case 0: /* mono */
2765
0
            self->m_channelConfiguration = 1;
2766
0
            break;
2767
0
          case 2: /* stereo */
2768
0
            self->m_channelConfiguration = 2;
2769
0
            break;
2770
0
          default:
2771
0
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2772
0
            goto bail;
2773
0
        }
2774
0
        self->m_vcb11Flag = 1;
2775
0
        self->m_hcrFlag = 1;
2776
0
        self->m_samplesPerFrame = 960;
2777
0
        self->m_epConfig = 1;
2778
0
        break;
2779
0
      case 1: /* CELP */
2780
0
        self->m_aot = AOT_ER_CELP;
2781
0
        self->m_channelConfiguration = 1;
2782
0
        break;
2783
0
      case 2: /* HVXC */
2784
0
        self->m_aot = AOT_ER_HVXC;
2785
0
        self->m_channelConfiguration = 1;
2786
0
        break;
2787
0
      case 3: /* xHE-AAC */
2788
0
      {
2789
        /* payload is MPEG conform -> no pseudo DRM AOT needed */
2790
0
        self->m_aot = AOT_USAC;
2791
0
      }
2792
0
        switch (audioMode) {
2793
0
          case 0: /* mono */
2794
0
          case 2: /* stereo */
2795
            /* codec specific config 8n bits */
2796
0
            ErrorStatus = Drm_xHEAACStaticConfig(self, bs, audioMode, cb);
2797
0
            break;
2798
0
          default:
2799
0
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2800
0
            goto bail;
2801
0
        }
2802
0
        break;
2803
0
      default:
2804
0
        ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2805
0
        self->m_aot = AOT_NONE;
2806
0
        break;
2807
0
    }
2808
2809
0
    if (self->m_psPresentFlag && !self->m_sbrPresentFlag) {
2810
0
      ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
2811
0
      goto bail;
2812
0
    }
2813
0
  }
2814
2815
0
bail:
2816
0
  return (ErrorStatus);
2817
0
}