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