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