/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 | 342k | void CProgramConfig_Reset(CProgramConfig *pPce) { pPce->elCounter = 0; } |
185 | | |
186 | 1.20M | void CProgramConfig_Init(CProgramConfig *pPce) { |
187 | 1.20M | FDKmemclear(pPce, sizeof(CProgramConfig)); |
188 | 1.20M | pPce->SamplingFrequencyIndex = 0xf; |
189 | 1.20M | } |
190 | | |
191 | 404k | int CProgramConfig_IsValid(const CProgramConfig *pPce) { |
192 | 404k | return ((pPce->isValid) ? 1 : 0); |
193 | 404k | } |
194 | | |
195 | 14.3k | #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 | 31.5k | const UINT alignmentAnchor) { |
207 | 31.5k | int err = 0; |
208 | 31.5k | FDK_CRCINFO crcInfo; /* CRC state info */ |
209 | 31.5k | INT crcReg; |
210 | 31.5k | FDKcrcInit(&crcInfo, 0x07, 0xFF, 8); |
211 | 31.5k | crcReg = FDKcrcStartReg(&crcInfo, bs, 0); |
212 | 31.5k | UINT startAnchor = FDKgetValidBits(bs); |
213 | | |
214 | 31.5k | FDK_ASSERT(pPce != NULL); |
215 | 31.5k | FDK_ASSERT(bs != NULL); |
216 | 31.5k | FDK_ASSERT(bytesAvailable != NULL); |
217 | | |
218 | 31.5k | if ((startAnchor >= 24) && (*bytesAvailable >= 3) && |
219 | 31.5k | (FDKreadBits(bs, 8) == PCE_HEIGHT_EXT_SYNC)) { |
220 | 2.40k | int i; |
221 | | |
222 | 13.0k | for (i = 0; i < pPce->NumFrontChannelElements; i++) { |
223 | 10.6k | if ((pPce->FrontElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >= |
224 | 10.6k | PC_NUM_HEIGHT_LAYER) { |
225 | 5.66k | err = -2; /* height information is out of the valid range */ |
226 | 5.66k | } |
227 | 10.6k | } |
228 | 11.8k | for (i = 0; i < pPce->NumSideChannelElements; i++) { |
229 | 9.41k | if ((pPce->SideElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >= |
230 | 9.41k | PC_NUM_HEIGHT_LAYER) { |
231 | 4.48k | err = -2; /* height information is out of the valid range */ |
232 | 4.48k | } |
233 | 9.41k | } |
234 | 19.4k | for (i = 0; i < pPce->NumBackChannelElements; i++) { |
235 | 17.0k | if ((pPce->BackElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >= |
236 | 17.0k | PC_NUM_HEIGHT_LAYER) { |
237 | 8.15k | err = -2; /* height information is out of the valid range */ |
238 | 8.15k | } |
239 | 17.0k | } |
240 | 2.40k | FDKbyteAlign(bs, alignmentAnchor); |
241 | | |
242 | 2.40k | FDKcrcEndReg(&crcInfo, bs, crcReg); |
243 | 2.40k | if ((USHORT)FDKreadBits(bs, 8) != FDKcrcGetCRC(&crcInfo)) { |
244 | | /* CRC failed */ |
245 | 1.61k | err = -1; |
246 | 1.61k | } |
247 | 2.40k | 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 | 1.61k | FDKmemclear(pPce->FrontElementHeightInfo, |
252 | 1.61k | sizeof(pPce->FrontElementHeightInfo)); |
253 | 1.61k | FDKmemclear(pPce->SideElementHeightInfo, |
254 | 1.61k | sizeof(pPce->SideElementHeightInfo)); |
255 | 1.61k | FDKmemclear(pPce->BackElementHeightInfo, |
256 | 1.61k | sizeof(pPce->BackElementHeightInfo)); |
257 | 1.61k | } |
258 | 29.1k | } else { |
259 | | /* No valid extension data found -> restore the initial bitbuffer state */ |
260 | 29.1k | FDKpushBack(bs, (INT)startAnchor - (INT)FDKgetValidBits(bs)); |
261 | 29.1k | } |
262 | | |
263 | | /* Always report the bytes read. */ |
264 | 31.5k | *bytesAvailable -= ((INT)startAnchor - (INT)FDKgetValidBits(bs)) >> 3; |
265 | | |
266 | 31.5k | return (err); |
267 | 31.5k | } |
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 | 31.5k | static int CProgramConfig_Check(CProgramConfig *pPce) { |
279 | 31.5k | INT i; |
280 | 31.5k | INT err = 0; |
281 | 31.5k | INT numBackChannels[3] = {0}; |
282 | 31.5k | INT numSideChannels[3] = {0}; |
283 | 31.5k | INT numFrontChannels[3] = {0}; |
284 | 31.5k | UCHAR *pCpeFront = pPce->FrontElementIsCpe; |
285 | 31.5k | UCHAR *pCpeSide = pPce->SideElementIsCpe; |
286 | 31.5k | UCHAR *pCpeBack = pPce->BackElementIsCpe; |
287 | 31.5k | UCHAR *pHeight; |
288 | | |
289 | 31.5k | pHeight = pPce->BackElementHeightInfo; |
290 | 97.1k | for (i = 0; i < pPce->NumBackChannelElements; i++) { |
291 | 65.5k | numBackChannels[*pHeight] += pPce->BackElementIsCpe[i] ? 2 : 1; |
292 | 65.5k | pHeight++; |
293 | 65.5k | } |
294 | 31.5k | pHeight = pPce->SideElementHeightInfo; |
295 | 104k | for (i = 0; i < pPce->NumSideChannelElements; i++) { |
296 | 72.8k | numSideChannels[*pHeight] += pPce->SideElementIsCpe[i] ? 2 : 1; |
297 | 72.8k | pHeight++; |
298 | 72.8k | } |
299 | 31.5k | pHeight = pPce->FrontElementHeightInfo; |
300 | 121k | for (i = 0; i < pPce->NumFrontChannelElements; i++) { |
301 | 89.7k | numFrontChannels[*pHeight] += pPce->FrontElementIsCpe[i] ? 2 : 1; |
302 | 89.7k | pHeight++; |
303 | 89.7k | } |
304 | | |
305 | | /* 0 = normal height channels, 1 = top height channels, 2 = bottom height |
306 | | * channels */ |
307 | 101k | for (i = 0; i < 3; i++) { |
308 | | /* if number of channels is odd => first element must be a SCE (front center |
309 | | * channel) */ |
310 | 78.4k | if (numFrontChannels[i] & 1) { |
311 | 8.38k | if (*pCpeFront++ == ID_CPE) { |
312 | 1.23k | err = 1; |
313 | 1.23k | goto bail; |
314 | 1.23k | } |
315 | 7.15k | numFrontChannels[i]--; |
316 | 7.15k | } |
317 | 112k | while (numFrontChannels[i] > 0) { |
318 | | /* must be CPE or paired SCE */ |
319 | 38.1k | if (*pCpeFront++ == ID_SCE) { |
320 | 17.7k | if (*pCpeFront++ == ID_CPE) { |
321 | 2.33k | err = 1; |
322 | 2.33k | goto bail; |
323 | 2.33k | } |
324 | 17.7k | } |
325 | 35.8k | numFrontChannels[i] -= 2; |
326 | 74.8k | }; |
327 | | |
328 | | /* in case that a top center surround channel (Ts) is transmitted the number |
329 | | * of channels can be odd */ |
330 | 74.8k | if (i != 1) { |
331 | | /* number of channels must be even */ |
332 | 51.3k | if (numSideChannels[i] & 1) { |
333 | 2.22k | err = 1; |
334 | 2.22k | goto bail; |
335 | 2.22k | } |
336 | 72.7k | while (numSideChannels[i] > 0) { |
337 | | /* must be CPE or paired SCE */ |
338 | 24.9k | if (*pCpeSide++ == ID_SCE) { |
339 | 5.64k | if (*pCpeSide++ == ID_CPE) { |
340 | 1.36k | err = 1; |
341 | 1.36k | goto bail; |
342 | 1.36k | } |
343 | 5.64k | } |
344 | 23.6k | numSideChannels[i] -= 2; |
345 | 47.7k | }; |
346 | 47.7k | } |
347 | | |
348 | 83.1k | while (numBackChannels[i] > 1) { |
349 | | /* must be CPE or paired SCE */ |
350 | 12.8k | if (*pCpeBack++ == ID_SCE) { |
351 | 3.06k | if (*pCpeBack++ == ID_CPE) { |
352 | 892 | err = 1; |
353 | 892 | goto bail; |
354 | 892 | } |
355 | 3.06k | } |
356 | 11.9k | numBackChannels[i] -= 2; |
357 | 70.3k | }; |
358 | | /* if number of channels is odd => last element must be a SCE (back center |
359 | | * channel) */ |
360 | 70.3k | if (numBackChannels[i]) { |
361 | 8.29k | if (*pCpeBack++ == ID_CPE) { |
362 | 207 | err = 1; |
363 | 207 | goto bail; |
364 | 207 | } |
365 | 8.29k | } |
366 | 70.3k | } |
367 | | |
368 | 31.5k | bail: |
369 | | |
370 | 31.5k | return err; |
371 | 31.5k | } |
372 | | |
373 | | void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, |
374 | 31.5k | UINT alignmentAnchor) { |
375 | 31.5k | int i; |
376 | 31.5k | int commentBytes; |
377 | 31.5k | UCHAR tag, isCpe; |
378 | 31.5k | UCHAR checkElementTagSelect[3][PC_FSB_CHANNELS_MAX] = {{0}}; |
379 | | |
380 | 31.5k | pPce->isValid = 1; |
381 | 31.5k | pPce->NumEffectiveChannels = 0; |
382 | 31.5k | pPce->NumChannels = 0; |
383 | 31.5k | pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4); |
384 | 31.5k | pPce->Profile = (UCHAR)FDKreadBits(bs, 2); |
385 | 31.5k | pPce->SamplingFrequencyIndex = (UCHAR)FDKreadBits(bs, 4); |
386 | 31.5k | pPce->NumFrontChannelElements = (UCHAR)FDKreadBits(bs, 4); |
387 | 31.5k | pPce->NumSideChannelElements = (UCHAR)FDKreadBits(bs, 4); |
388 | 31.5k | pPce->NumBackChannelElements = (UCHAR)FDKreadBits(bs, 4); |
389 | 31.5k | pPce->NumLfeChannelElements = (UCHAR)FDKreadBits(bs, 2); |
390 | 31.5k | pPce->NumAssocDataElements = (UCHAR)FDKreadBits(bs, 3); |
391 | 31.5k | pPce->NumValidCcElements = (UCHAR)FDKreadBits(bs, 4); |
392 | | |
393 | 31.5k | if ((pPce->MonoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) { |
394 | 8.70k | pPce->MonoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4); |
395 | 8.70k | } |
396 | | |
397 | 31.5k | if ((pPce->StereoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) { |
398 | 7.04k | pPce->StereoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4); |
399 | 7.04k | } |
400 | | |
401 | 31.5k | if ((pPce->MatrixMixdownIndexPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) { |
402 | 16.1k | pPce->MatrixMixdownIndex = (UCHAR)FDKreadBits(bs, 2); |
403 | 16.1k | pPce->PseudoSurroundEnable = (UCHAR)FDKreadBits(bs, 1); |
404 | 16.1k | } |
405 | | |
406 | 121k | for (i = 0; i < pPce->NumFrontChannelElements; i++) { |
407 | 89.7k | pPce->FrontElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); |
408 | 89.7k | pPce->FrontElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); |
409 | 89.7k | 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 | 89.7k | if (checkElementTagSelect[isCpe][tag] == 0) { |
414 | 74.4k | checkElementTagSelect[isCpe][tag] = 1; |
415 | 74.4k | } else { |
416 | 15.3k | pPce->isValid = 0; |
417 | 15.3k | } |
418 | 89.7k | } |
419 | | |
420 | 104k | for (i = 0; i < pPce->NumSideChannelElements; i++) { |
421 | 72.8k | pPce->SideElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); |
422 | 72.8k | pPce->SideElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); |
423 | 72.8k | 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 | 72.8k | if (checkElementTagSelect[isCpe][tag] == 0) { |
428 | 51.2k | checkElementTagSelect[isCpe][tag] = 1; |
429 | 51.2k | } else { |
430 | 21.6k | pPce->isValid = 0; |
431 | 21.6k | } |
432 | 72.8k | } |
433 | | |
434 | 97.1k | for (i = 0; i < pPce->NumBackChannelElements; i++) { |
435 | 65.5k | pPce->BackElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); |
436 | 65.5k | pPce->BackElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); |
437 | 65.5k | 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 | 65.5k | if (checkElementTagSelect[isCpe][tag] == 0) { |
442 | 41.6k | checkElementTagSelect[isCpe][tag] = 1; |
443 | 41.6k | } else { |
444 | 23.9k | pPce->isValid = 0; |
445 | 23.9k | } |
446 | 65.5k | } |
447 | | |
448 | 31.5k | pPce->NumEffectiveChannels = pPce->NumChannels; |
449 | | |
450 | 51.7k | for (i = 0; i < pPce->NumLfeChannelElements; i++) { |
451 | 20.1k | pPce->LfeElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); |
452 | 20.1k | pPce->NumChannels += 1; |
453 | | |
454 | | /* Check element instance tag according to ISO/IEC 13818-7:2003(E), |
455 | | * chapter 8.2.1.1 */ |
456 | 20.1k | if (checkElementTagSelect[2][tag] == 0) { |
457 | 19.0k | checkElementTagSelect[2][tag] = 1; |
458 | 19.0k | } else { |
459 | 1.07k | pPce->isValid = 0; |
460 | 1.07k | } |
461 | 20.1k | } |
462 | | |
463 | 82.9k | for (i = 0; i < pPce->NumAssocDataElements; i++) { |
464 | 51.4k | pPce->AssocDataElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); |
465 | 51.4k | } |
466 | | |
467 | 159k | for (i = 0; i < pPce->NumValidCcElements; i++) { |
468 | 128k | pPce->CcElementIsIndSw[i] = (UCHAR)FDKreadBits(bs, 1); |
469 | 128k | pPce->ValidCcElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); |
470 | 128k | } |
471 | | |
472 | 31.5k | FDKbyteAlign(bs, alignmentAnchor); |
473 | | |
474 | 31.5k | pPce->CommentFieldBytes = (UCHAR)FDKreadBits(bs, 8); |
475 | 31.5k | commentBytes = pPce->CommentFieldBytes; |
476 | | |
477 | | /* Search for height info extension and read it if available */ |
478 | 31.5k | if (CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor)) { |
479 | 1.61k | pPce->isValid = 0; |
480 | 1.61k | } |
481 | | |
482 | | /* Check order of elements according to ISO / IEC 13818 - 7:2003(E), |
483 | | * chapter 8.5.1 */ |
484 | 31.5k | if (CProgramConfig_Check(pPce)) { |
485 | 8.25k | pPce->isValid = 0; |
486 | 8.25k | } |
487 | | |
488 | 842k | for (i = 0; i < commentBytes; i++) { |
489 | 810k | UCHAR text; |
490 | | |
491 | 810k | text = (UCHAR)FDKreadBits(bs, 8); |
492 | | |
493 | 810k | if (i < PC_COMMENTLENGTH) { |
494 | 810k | pPce->Comment[i] = text; |
495 | 810k | } |
496 | 810k | } |
497 | 31.5k | } |
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 | 30.9k | const CProgramConfig *const pPce2) { |
509 | 30.9k | int result = 0; /* Innocent until proven false. */ |
510 | | |
511 | 30.9k | if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) != |
512 | 30.9k | 0) { /* Configurations are not completely equal. |
513 | | So look into details and analyse the channel configurations: */ |
514 | 30.2k | result = -1; |
515 | | |
516 | 30.2k | if (pPce1->NumChannels == |
517 | 30.2k | 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 | 29.7k | result = 1; |
521 | | |
522 | | /* Front channels */ |
523 | 29.7k | if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) { |
524 | 15.1k | result = 2; /* different number of front channel elements */ |
525 | 15.1k | } else { |
526 | 14.5k | int el, numCh1 = 0, numCh2 = 0; |
527 | 43.2k | for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) { |
528 | 30.3k | if (pPce1->FrontElementHeightInfo[el] != |
529 | 30.3k | pPce2->FrontElementHeightInfo[el]) { |
530 | 1.60k | result = 2; /* different height info */ |
531 | 1.60k | break; |
532 | 1.60k | } |
533 | 28.7k | numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1; |
534 | 28.7k | numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1; |
535 | 28.7k | } |
536 | 14.5k | if (numCh1 != numCh2) { |
537 | 8.94k | result = 2; /* different number of front channels */ |
538 | 8.94k | } |
539 | 14.5k | } |
540 | | /* Side channels */ |
541 | 29.7k | if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) { |
542 | 13.6k | result = 2; /* different number of side channel elements */ |
543 | 16.1k | } else { |
544 | 16.1k | int el, numCh1 = 0, numCh2 = 0; |
545 | 16.7k | for (el = 0; el < pPce1->NumSideChannelElements; el += 1) { |
546 | 748 | if (pPce1->SideElementHeightInfo[el] != |
547 | 748 | pPce2->SideElementHeightInfo[el]) { |
548 | 129 | result = 2; /* different height info */ |
549 | 129 | break; |
550 | 129 | } |
551 | 619 | numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1; |
552 | 619 | numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1; |
553 | 619 | } |
554 | 16.1k | if (numCh1 != numCh2) { |
555 | 1 | result = 2; /* different number of side channels */ |
556 | 1 | } |
557 | 16.1k | } |
558 | | /* Back channels */ |
559 | 29.7k | if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) { |
560 | 17.2k | result = 2; /* different number of back channel elements */ |
561 | 17.2k | } else { |
562 | 12.5k | int el, numCh1 = 0, numCh2 = 0; |
563 | 23.9k | for (el = 0; el < pPce1->NumBackChannelElements; el += 1) { |
564 | 12.3k | if (pPce1->BackElementHeightInfo[el] != |
565 | 12.3k | pPce2->BackElementHeightInfo[el]) { |
566 | 923 | result = 2; /* different height info */ |
567 | 923 | break; |
568 | 923 | } |
569 | 11.4k | numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1; |
570 | 11.4k | numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1; |
571 | 11.4k | } |
572 | 12.5k | if (numCh1 != numCh2) { |
573 | 5.12k | result = 2; /* different number of back channels */ |
574 | 5.12k | } |
575 | 12.5k | } |
576 | | /* LFE channels */ |
577 | 29.7k | if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) { |
578 | 10.0k | result = 2; /* different number of lfe channels */ |
579 | 10.0k | } |
580 | | /* LFEs are always SCEs so we don't need to count the channels. */ |
581 | 29.7k | } |
582 | 30.2k | } |
583 | | |
584 | 30.9k | return result; |
585 | 30.9k | } |
586 | | |
587 | 29.7k | void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) { |
588 | 29.7k | FDK_ASSERT(pPce != NULL); |
589 | | |
590 | | /* Init PCE */ |
591 | 29.7k | CProgramConfig_Init(pPce); |
592 | 29.7k | pPce->Profile = |
593 | 29.7k | 1; /* Set AAC LC because it is the only supported object type. */ |
594 | | |
595 | 29.7k | switch (channelConfig) { |
596 | | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
597 | 4.26k | case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */ |
598 | 4.26k | pPce->NumFrontChannelElements = 2; |
599 | 4.26k | pPce->FrontElementIsCpe[0] = 0; |
600 | 4.26k | pPce->FrontElementIsCpe[1] = 1; |
601 | 4.26k | pPce->NumSideChannelElements = 1; |
602 | 4.26k | pPce->SideElementIsCpe[0] = 1; |
603 | 4.26k | pPce->NumBackChannelElements = 1; |
604 | 4.26k | pPce->BackElementIsCpe[0] = 1; |
605 | 4.26k | pPce->NumLfeChannelElements = 1; |
606 | 4.26k | pPce->NumChannels = 8; |
607 | 4.26k | pPce->NumEffectiveChannels = 7; |
608 | 4.26k | pPce->isValid = 1; |
609 | 4.26k | break; |
610 | | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
611 | 4.27k | case 12: /* 3/0/4.1ch surround back */ |
612 | 4.27k | pPce->BackElementIsCpe[1] = 1; |
613 | 4.27k | pPce->NumChannels += 1; |
614 | 4.27k | pPce->NumEffectiveChannels += 1; |
615 | 4.27k | FDK_FALLTHROUGH; |
616 | 5.81k | case 11: /* 3/0/3.1ch */ |
617 | 5.81k | pPce->NumFrontChannelElements += 2; |
618 | 5.81k | pPce->FrontElementIsCpe[0] = 0; |
619 | 5.81k | pPce->FrontElementIsCpe[1] = 1; |
620 | 5.81k | pPce->NumBackChannelElements += 2; |
621 | 5.81k | pPce->BackElementIsCpe[0] = 1; |
622 | 5.81k | pPce->BackElementIsCpe[1] += 0; |
623 | 5.81k | pPce->NumLfeChannelElements += 1; |
624 | 5.81k | pPce->NumChannels += 7; |
625 | 5.81k | pPce->NumEffectiveChannels += 6; |
626 | 5.81k | pPce->isValid = 1; |
627 | 5.81k | break; |
628 | | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
629 | 4.27k | case 14: /* 2/0/0-3/0/2-0.1ch front height */ |
630 | 4.27k | pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */ |
631 | 4.27k | FDK_FALLTHROUGH; |
632 | 8.82k | case 7: /* 5/0/2.1ch front */ |
633 | 8.82k | pPce->NumFrontChannelElements += 1; |
634 | 8.82k | pPce->FrontElementIsCpe[2] = 1; |
635 | 8.82k | pPce->NumChannels += 2; |
636 | 8.82k | pPce->NumEffectiveChannels += 2; |
637 | 8.82k | FDK_FALLTHROUGH; |
638 | 14.6k | case 6: /* 3/0/2.1ch */ |
639 | 14.6k | pPce->NumLfeChannelElements += 1; |
640 | 14.6k | pPce->NumChannels += 1; |
641 | 14.6k | FDK_FALLTHROUGH; |
642 | 16.0k | case 5: /* 3/0/2.0ch */ |
643 | 17.4k | case 4: /* 3/0/1.0ch */ |
644 | 17.4k | pPce->NumBackChannelElements += 1; |
645 | 17.4k | pPce->BackElementIsCpe[0] = (channelConfig > 4) ? 1 : 0; |
646 | 17.4k | pPce->NumChannels += (channelConfig > 4) ? 2 : 1; |
647 | 17.4k | pPce->NumEffectiveChannels += (channelConfig > 4) ? 2 : 1; |
648 | 17.4k | FDK_FALLTHROUGH; |
649 | 18.5k | case 3: /* 3/0/0.0ch */ |
650 | 18.5k | pPce->NumFrontChannelElements += 1; |
651 | 18.5k | pPce->FrontElementIsCpe[1] = 1; |
652 | 18.5k | pPce->NumChannels += 2; |
653 | 18.5k | pPce->NumEffectiveChannels += 2; |
654 | 18.5k | FDK_FALLTHROUGH; |
655 | 18.9k | case 1: /* 1/0/0.0ch */ |
656 | 18.9k | pPce->NumFrontChannelElements += 1; |
657 | 18.9k | pPce->FrontElementIsCpe[0] = 0; |
658 | 18.9k | pPce->NumChannels += 1; |
659 | 18.9k | pPce->NumEffectiveChannels += 1; |
660 | 18.9k | pPce->isValid = 1; |
661 | 18.9k | break; |
662 | | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
663 | 346 | case 2: /* 2/0/0.ch */ |
664 | 346 | pPce->NumFrontChannelElements = 1; |
665 | 346 | pPce->FrontElementIsCpe[0] = 1; |
666 | 346 | pPce->NumChannels += 2; |
667 | 346 | pPce->NumEffectiveChannels += 2; |
668 | 346 | pPce->isValid = 1; |
669 | 346 | break; |
670 | | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
671 | 358 | default: |
672 | 358 | pPce->isValid = 0; /* To be explicit! */ |
673 | 358 | break; |
674 | 29.7k | } |
675 | | |
676 | 29.7k | if (pPce->isValid) { |
677 | | /* Create valid element instance tags */ |
678 | 29.3k | int el, elTagSce = 0, elTagCpe = 0; |
679 | | |
680 | 96.1k | for (el = 0; el < pPce->NumFrontChannelElements; el += 1) { |
681 | 66.8k | pPce->FrontElementTagSelect[el] = |
682 | 66.8k | (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++; |
683 | 66.8k | } |
684 | 33.6k | for (el = 0; el < pPce->NumSideChannelElements; el += 1) { |
685 | 4.26k | pPce->SideElementTagSelect[el] = |
686 | 4.26k | (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++; |
687 | 4.26k | } |
688 | 62.7k | for (el = 0; el < pPce->NumBackChannelElements; el += 1) { |
689 | 33.3k | pPce->BackElementTagSelect[el] = |
690 | 33.3k | (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++; |
691 | 33.3k | } |
692 | 29.3k | elTagSce = 0; |
693 | 54.0k | for (el = 0; el < pPce->NumLfeChannelElements; el += 1) { |
694 | 24.7k | pPce->LfeElementTagSelect[el] = elTagSce++; |
695 | 24.7k | } |
696 | 29.3k | } |
697 | 29.7k | } |
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 | 420k | UINT index) { |
710 | 420k | if (index < 3) { |
711 | 359k | *chType = ACT_FRONT; |
712 | 359k | *chIndex = index; |
713 | 359k | } else { |
714 | 61.1k | switch (channelConfig) { |
715 | 38 | case 4: /* SCE, CPE, SCE */ |
716 | 231 | case 5: /* SCE, CPE, CPE */ |
717 | 500 | case 6: /* SCE, CPE, CPE, LFE */ |
718 | 500 | switch (index) { |
719 | 368 | case 3: |
720 | 368 | case 4: |
721 | 368 | *chType = ACT_BACK; |
722 | 368 | *chIndex = index - 3; |
723 | 368 | break; |
724 | 132 | case 5: |
725 | 132 | *chType = ACT_LFE; |
726 | 132 | *chIndex = 0; |
727 | 132 | break; |
728 | 500 | } |
729 | 500 | break; |
730 | 10.1k | case 7: /* SCE,CPE,CPE,CPE,LFE */ |
731 | 10.1k | switch (index) { |
732 | 3.39k | case 3: |
733 | 3.39k | case 4: |
734 | 3.39k | *chType = ACT_FRONT; |
735 | 3.39k | *chIndex = index; |
736 | 3.39k | break; |
737 | 3.37k | case 5: |
738 | 3.37k | case 6: |
739 | 3.37k | *chType = ACT_BACK; |
740 | 3.37k | *chIndex = index - 5; |
741 | 3.37k | break; |
742 | 3.34k | case 7: |
743 | 3.34k | *chType = ACT_LFE; |
744 | 3.34k | *chIndex = 0; |
745 | 3.34k | break; |
746 | 10.1k | } |
747 | 10.1k | break; |
748 | 10.1k | case 11: /* SCE,CPE,CPE,SCE,LFE */ |
749 | 8.26k | if (index < 6) { |
750 | 5.63k | *chType = ACT_BACK; |
751 | 5.63k | *chIndex = index - 3; |
752 | 5.63k | } else { |
753 | 2.62k | *chType = ACT_LFE; |
754 | 2.62k | *chIndex = 0; |
755 | 2.62k | } |
756 | 8.26k | break; |
757 | 7.05k | case 12: /* SCE,CPE,CPE,CPE,LFE */ |
758 | 7.05k | if (index < 7) { |
759 | 4.71k | *chType = ACT_BACK; |
760 | 4.71k | *chIndex = index - 3; |
761 | 4.71k | } else { |
762 | 2.34k | *chType = ACT_LFE; |
763 | 2.34k | *chIndex = 0; |
764 | 2.34k | } |
765 | 7.05k | break; |
766 | 35.2k | case 14: /* SCE,CPE,CPE,LFE,CPE */ |
767 | 35.2k | switch (index) { |
768 | 11.7k | case 3: |
769 | 11.7k | case 4: |
770 | 11.7k | *chType = ACT_BACK; |
771 | 11.7k | *chIndex = index - 3; |
772 | 11.7k | break; |
773 | 11.7k | case 5: |
774 | 11.7k | *chType = ACT_LFE; |
775 | 11.7k | *chIndex = 0; |
776 | 11.7k | break; |
777 | 11.7k | case 6: |
778 | 11.7k | case 7: |
779 | 11.7k | *chType = ACT_FRONT_TOP; |
780 | 11.7k | *chIndex = index - 6; /* handle the top layer independently */ |
781 | 11.7k | break; |
782 | 35.2k | } |
783 | 35.2k | break; |
784 | 35.2k | default: |
785 | 0 | *chType = ACT_NONE; |
786 | 0 | break; |
787 | 61.1k | } |
788 | 61.1k | } |
789 | 420k | } |
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 | 440k | MP4_ELEMENT_ID elType) { |
797 | 440k | if (channelConfig > 0) { |
798 | | /* Constant channel mapping must have |
799 | | been set during initialization. */ |
800 | 434k | if (IS_CHANNEL_ELEMENT(elType)) { |
801 | 420k | *elMapping = pPce->elCounter; |
802 | 420k | if (elList[pPce->elCounter] != elType && |
803 | 420k | !IS_USAC_CHANNEL_ELEMENT(elType)) { |
804 | | /* Not in the list */ |
805 | 3.11k | if ((channelConfig == 2) && |
806 | 3.11k | (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 | 2.70k | channelConfig = 1; |
811 | 2.70k | } else if ((elList[pPce->elCounter] == ID_LFE) && |
812 | 407 | (elType == |
813 | 352 | ID_SCE)) { /* Decode bitstreams which wrongly use ID_SCE |
814 | | instead of ID_LFE element type. */ |
815 | 352 | ; |
816 | 352 | } else { |
817 | 55 | return 0; |
818 | 55 | } |
819 | 3.11k | } |
820 | | /* Assume all front channels */ |
821 | 420k | getImplicitAudioChannelTypeAndIndex( |
822 | 420k | &chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx); |
823 | 420k | if (elType == ID_CPE || elType == ID_USAC_CPE) { |
824 | 276k | chType[channelIdx + 1] = chType[channelIdx]; |
825 | 276k | chIndex[channelIdx + 1] = chIndex[channelIdx] + 1; |
826 | 276k | } |
827 | 420k | pPce->elCounter++; |
828 | 420k | } |
829 | | /* Accept all non-channel elements, too. */ |
830 | 434k | return 1; |
831 | 434k | } else { |
832 | 6.57k | 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 | 6.57k | } else { |
842 | | /* Accept the additional channel(s), only if the tag is in the lists */ |
843 | 6.57k | int isCpe = 0, i; |
844 | | /* Element counter */ |
845 | 6.57k | int ec[PC_NUM_HEIGHT_LAYER] = {0}; |
846 | | /* Channel counters */ |
847 | 6.57k | int cc[PC_NUM_HEIGHT_LAYER] = {0}; |
848 | 6.57k | int fc[PC_NUM_HEIGHT_LAYER] = {0}; /* front channel counter */ |
849 | 6.57k | int sc[PC_NUM_HEIGHT_LAYER] = {0}; /* side channel counter */ |
850 | 6.57k | int bc[PC_NUM_HEIGHT_LAYER] = {0}; /* back channel counter */ |
851 | 6.57k | 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 | 6.57k | switch (elType) { |
865 | 431 | case ID_CPE: |
866 | 431 | isCpe = 1; |
867 | 431 | FDK_FALLTHROUGH; |
868 | 2.19k | case ID_SCE: |
869 | | /* search in front channels */ |
870 | 4.21k | for (i = 0; i < pPce->NumFrontChannelElements; i++) { |
871 | 3.06k | int heightLayer = pPce->FrontElementHeightInfo[i]; |
872 | 3.06k | if (isCpe == pPce->FrontElementIsCpe[i] && |
873 | 3.06k | pPce->FrontElementTagSelect[i] == tag) { |
874 | 1.05k | int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer]; |
875 | 1.05k | AUDIO_CHANNEL_TYPE aChType = |
876 | 1.05k | (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_FRONT); |
877 | 1.17k | for (h = heightLayer - 1; h >= 0; h -= 1) { |
878 | 123 | int el; |
879 | | /* Count front channels/elements */ |
880 | 600 | for (el = 0; el < pPce->NumFrontChannelElements; el += 1) { |
881 | 477 | if (pPce->FrontElementHeightInfo[el] == h) { |
882 | 126 | elIdx += 1; |
883 | 126 | chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1; |
884 | 126 | } |
885 | 477 | } |
886 | | /* Count side channels/elements */ |
887 | 241 | for (el = 0; el < pPce->NumSideChannelElements; el += 1) { |
888 | 118 | if (pPce->SideElementHeightInfo[el] == h) { |
889 | 51 | elIdx += 1; |
890 | 51 | chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1; |
891 | 51 | } |
892 | 118 | } |
893 | | /* Count back channels/elements */ |
894 | 262 | for (el = 0; el < pPce->NumBackChannelElements; el += 1) { |
895 | 139 | if (pPce->BackElementHeightInfo[el] == h) { |
896 | 45 | elIdx += 1; |
897 | 45 | chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1; |
898 | 45 | } |
899 | 139 | } |
900 | 123 | if (h == 0) { /* normal height */ |
901 | 77 | elIdx += pPce->NumLfeChannelElements; |
902 | 77 | chIdx += pPce->NumLfeChannelElements; |
903 | 77 | } |
904 | 123 | } |
905 | 1.05k | chMapping[chIdx] = channelIdx; |
906 | 1.05k | chType[chIdx] = aChType; |
907 | 1.05k | chIndex[chIdx] = fc[heightLayer]; |
908 | 1.05k | if (isCpe) { |
909 | 79 | chMapping[chIdx + 1] = channelIdx + 1; |
910 | 79 | chType[chIdx + 1] = aChType; |
911 | 79 | chIndex[chIdx + 1] = fc[heightLayer] + 1; |
912 | 79 | } |
913 | 1.05k | *elMapping = elIdx; |
914 | 1.05k | return 1; |
915 | 1.05k | } |
916 | 2.01k | ec[heightLayer] += 1; |
917 | 2.01k | if (pPce->FrontElementIsCpe[i]) { |
918 | 246 | cc[heightLayer] += 2; |
919 | 246 | fc[heightLayer] += 2; |
920 | 1.77k | } else { |
921 | 1.77k | cc[heightLayer] += 1; |
922 | 1.77k | fc[heightLayer] += 1; |
923 | 1.77k | } |
924 | 2.01k | } |
925 | | /* search in side channels */ |
926 | 1.94k | for (i = 0; i < pPce->NumSideChannelElements; i++) { |
927 | 1.22k | int heightLayer = pPce->SideElementHeightInfo[i]; |
928 | 1.22k | if (isCpe == pPce->SideElementIsCpe[i] && |
929 | 1.22k | pPce->SideElementTagSelect[i] == tag) { |
930 | 421 | int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer]; |
931 | 421 | AUDIO_CHANNEL_TYPE aChType = |
932 | 421 | (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_SIDE); |
933 | 620 | for (h = heightLayer - 1; h >= 0; h -= 1) { |
934 | 199 | int el; |
935 | | /* Count front channels/elements */ |
936 | 415 | for (el = 0; el < pPce->NumFrontChannelElements; el += 1) { |
937 | 216 | if (pPce->FrontElementHeightInfo[el] == h) { |
938 | 79 | elIdx += 1; |
939 | 79 | chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1; |
940 | 79 | } |
941 | 216 | } |
942 | | /* Count side channels/elements */ |
943 | 947 | for (el = 0; el < pPce->NumSideChannelElements; el += 1) { |
944 | 748 | if (pPce->SideElementHeightInfo[el] == h) { |
945 | 191 | elIdx += 1; |
946 | 191 | chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1; |
947 | 191 | } |
948 | 748 | } |
949 | | /* Count back channels/elements */ |
950 | 406 | for (el = 0; el < pPce->NumBackChannelElements; el += 1) { |
951 | 207 | if (pPce->BackElementHeightInfo[el] == h) { |
952 | 65 | elIdx += 1; |
953 | 65 | chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1; |
954 | 65 | } |
955 | 207 | } |
956 | 199 | if (h == |
957 | 199 | 0) { /* LFE channels belong to the normal height layer */ |
958 | 121 | elIdx += pPce->NumLfeChannelElements; |
959 | 121 | chIdx += pPce->NumLfeChannelElements; |
960 | 121 | } |
961 | 199 | } |
962 | 421 | chMapping[chIdx] = channelIdx; |
963 | 421 | chType[chIdx] = aChType; |
964 | 421 | chIndex[chIdx] = sc[heightLayer]; |
965 | 421 | if (isCpe) { |
966 | 122 | chMapping[chIdx + 1] = channelIdx + 1; |
967 | 122 | chType[chIdx + 1] = aChType; |
968 | 122 | chIndex[chIdx + 1] = sc[heightLayer] + 1; |
969 | 122 | } |
970 | 421 | *elMapping = elIdx; |
971 | 421 | return 1; |
972 | 421 | } |
973 | 805 | ec[heightLayer] += 1; |
974 | 805 | if (pPce->SideElementIsCpe[i]) { |
975 | 363 | cc[heightLayer] += 2; |
976 | 363 | sc[heightLayer] += 2; |
977 | 442 | } else { |
978 | 442 | cc[heightLayer] += 1; |
979 | 442 | sc[heightLayer] += 1; |
980 | 442 | } |
981 | 805 | } |
982 | | /* search in back channels */ |
983 | 1.35k | for (i = 0; i < pPce->NumBackChannelElements; i++) { |
984 | 1.33k | int heightLayer = pPce->BackElementHeightInfo[i]; |
985 | 1.33k | if (isCpe == pPce->BackElementIsCpe[i] && |
986 | 1.33k | pPce->BackElementTagSelect[i] == tag) { |
987 | 703 | int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer]; |
988 | 703 | AUDIO_CHANNEL_TYPE aChType = |
989 | 703 | (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_BACK); |
990 | 829 | for (h = heightLayer - 1; h >= 0; h -= 1) { |
991 | 126 | int el; |
992 | | /* Count front channels/elements */ |
993 | 399 | for (el = 0; el < pPce->NumFrontChannelElements; el += 1) { |
994 | 273 | if (pPce->FrontElementHeightInfo[el] == h) { |
995 | 90 | elIdx += 1; |
996 | 90 | chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1; |
997 | 90 | } |
998 | 273 | } |
999 | | /* Count side channels/elements */ |
1000 | 244 | for (el = 0; el < pPce->NumSideChannelElements; el += 1) { |
1001 | 118 | if (pPce->SideElementHeightInfo[el] == h) { |
1002 | 36 | elIdx += 1; |
1003 | 36 | chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1; |
1004 | 36 | } |
1005 | 118 | } |
1006 | | /* Count back channels/elements */ |
1007 | 454 | for (el = 0; el < pPce->NumBackChannelElements; el += 1) { |
1008 | 328 | if (pPce->BackElementHeightInfo[el] == h) { |
1009 | 79 | elIdx += 1; |
1010 | 79 | chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1; |
1011 | 79 | } |
1012 | 328 | } |
1013 | 126 | if (h == 0) { /* normal height */ |
1014 | 86 | elIdx += pPce->NumLfeChannelElements; |
1015 | 86 | chIdx += pPce->NumLfeChannelElements; |
1016 | 86 | } |
1017 | 126 | } |
1018 | 703 | chMapping[chIdx] = channelIdx; |
1019 | 703 | chType[chIdx] = aChType; |
1020 | 703 | chIndex[chIdx] = bc[heightLayer]; |
1021 | 703 | if (isCpe) { |
1022 | 227 | chMapping[chIdx + 1] = channelIdx + 1; |
1023 | 227 | chType[chIdx + 1] = aChType; |
1024 | 227 | chIndex[chIdx + 1] = bc[heightLayer] + 1; |
1025 | 227 | } |
1026 | 703 | *elMapping = elIdx; |
1027 | 703 | return 1; |
1028 | 703 | } |
1029 | 630 | ec[heightLayer] += 1; |
1030 | 630 | if (pPce->BackElementIsCpe[i]) { |
1031 | 215 | cc[heightLayer] += 2; |
1032 | 215 | bc[heightLayer] += 2; |
1033 | 415 | } else { |
1034 | 415 | cc[heightLayer] += 1; |
1035 | 415 | bc[heightLayer] += 1; |
1036 | 415 | } |
1037 | 630 | } |
1038 | 19 | break; |
1039 | | |
1040 | 334 | 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 | 1.24k | for (i = 0; i < pPce->NumFrontChannelElements; i += 1) { |
1045 | 914 | int heightLayer = pPce->FrontElementHeightInfo[i]; |
1046 | 914 | ec[heightLayer] += 1; |
1047 | 914 | cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1; |
1048 | 914 | } |
1049 | | /* Count side channels/elements at normal height */ |
1050 | 515 | for (i = 0; i < pPce->NumSideChannelElements; i += 1) { |
1051 | 181 | int heightLayer = pPce->SideElementHeightInfo[i]; |
1052 | 181 | ec[heightLayer] += 1; |
1053 | 181 | cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1; |
1054 | 181 | } |
1055 | | /* Count back channels/elements at normal height */ |
1056 | 576 | for (i = 0; i < pPce->NumBackChannelElements; i += 1) { |
1057 | 242 | int heightLayer = pPce->BackElementHeightInfo[i]; |
1058 | 242 | ec[heightLayer] += 1; |
1059 | 242 | cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1; |
1060 | 242 | } |
1061 | | |
1062 | | /* search in lfe channels */ |
1063 | 343 | for (i = 0; i < pPce->NumLfeChannelElements; i++) { |
1064 | 329 | int elIdx = |
1065 | 329 | ec[0]; /* LFE channels belong to the normal height layer */ |
1066 | 329 | int chIdx = cc[0]; |
1067 | 329 | if (pPce->LfeElementTagSelect[i] == tag) { |
1068 | 320 | chMapping[chIdx] = channelIdx; |
1069 | 320 | *elMapping = elIdx; |
1070 | 320 | chType[chIdx] = ACT_LFE; |
1071 | 320 | chIndex[chIdx] = lc; |
1072 | 320 | return 1; |
1073 | 320 | } |
1074 | 9 | ec[0] += 1; |
1075 | 9 | cc[0] += 1; |
1076 | 9 | lc += 1; |
1077 | 9 | } |
1078 | 334 | } break; |
1079 | | |
1080 | | /* Non audio elements */ |
1081 | 26 | case ID_CCE: |
1082 | | /* search in cce channels */ |
1083 | 91 | for (i = 0; i < pPce->NumValidCcElements; i++) { |
1084 | 81 | if (pPce->ValidCcElementTagSelect[i] == tag) { |
1085 | 16 | return 1; |
1086 | 16 | } |
1087 | 81 | } |
1088 | 10 | break; |
1089 | 4.02k | case ID_DSE: |
1090 | | /* search associated data elements */ |
1091 | 6.54k | for (i = 0; i < pPce->NumAssocDataElements; i++) { |
1092 | 2.73k | if (pPce->AssocDataElementTagSelect[i] == tag) { |
1093 | 221 | return 1; |
1094 | 221 | } |
1095 | 2.73k | } |
1096 | 3.80k | break; |
1097 | 3.80k | default: |
1098 | 0 | return 0; |
1099 | 6.57k | } |
1100 | 3.84k | return 0; /* not found in any list */ |
1101 | 6.57k | } |
1102 | 6.57k | } |
1103 | | |
1104 | 0 | return 1; |
1105 | 440k | } |
1106 | | |
1107 | 10.0k | #define SPEAKER_PLANE_NORMAL 0 |
1108 | 2.96k | #define SPEAKER_PLANE_TOP 1 |
1109 | 10.0k | #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 | 592 | const UINT pceChMapLen) { |
1176 | 592 | const UCHAR *nElements = &pPce->NumFrontChannelElements; |
1177 | 592 | const UCHAR *elHeight[3], *elIsCpe[3]; |
1178 | 592 | unsigned chIdx, plane, grp, offset, totCh[3], numCh[3][4]; |
1179 | | |
1180 | 592 | FDK_ASSERT(pPce != NULL); |
1181 | 592 | FDK_ASSERT(pceChMap != NULL); |
1182 | | |
1183 | | /* Init counter: */ |
1184 | 592 | FDKmemclear(totCh, 3 * sizeof(unsigned)); |
1185 | 592 | FDKmemclear(numCh, 3 * 4 * sizeof(unsigned)); |
1186 | | |
1187 | | /* Analyse PCE: */ |
1188 | 592 | elHeight[0] = pPce->FrontElementHeightInfo; |
1189 | 592 | elIsCpe[0] = pPce->FrontElementIsCpe; |
1190 | 592 | elHeight[1] = pPce->SideElementHeightInfo; |
1191 | 592 | elIsCpe[1] = pPce->SideElementIsCpe; |
1192 | 592 | elHeight[2] = pPce->BackElementHeightInfo; |
1193 | 592 | elIsCpe[2] = pPce->BackElementIsCpe; |
1194 | | |
1195 | 2.36k | for (plane = 0; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) { |
1196 | 7.10k | for (grp = 0; grp < 3; grp += 1) { /* front, side, back */ |
1197 | 5.32k | unsigned el; |
1198 | 11.0k | for (el = 0; el < nElements[grp]; el += 1) { |
1199 | 5.70k | if (elHeight[grp][el] == plane) { |
1200 | 1.90k | unsigned elCh = elIsCpe[grp][el] ? 2 : 1; |
1201 | 1.90k | numCh[plane][grp] += elCh; |
1202 | 1.90k | totCh[plane] += elCh; |
1203 | 1.90k | } |
1204 | 5.70k | } |
1205 | 5.32k | } |
1206 | 1.77k | if (plane == SPEAKER_PLANE_NORMAL) { |
1207 | 592 | unsigned elCh = pPce->NumLfeChannelElements; |
1208 | 592 | numCh[plane][grp] += elCh; |
1209 | 592 | totCh[plane] += elCh; |
1210 | 592 | } |
1211 | 1.77k | } |
1212 | | /* Sanity checks: */ |
1213 | 592 | chIdx = totCh[SPEAKER_PLANE_NORMAL] + totCh[SPEAKER_PLANE_TOP] + |
1214 | 592 | totCh[SPEAKER_PLANE_BOTTOM]; |
1215 | 592 | if (chIdx > pceChMapLen) { |
1216 | 0 | return -1; |
1217 | 0 | } |
1218 | | |
1219 | | /* Create map: */ |
1220 | 592 | offset = grp = 0; |
1221 | 592 | unsigned grpThresh = numCh[SPEAKER_PLANE_NORMAL][grp]; |
1222 | 3.29k | for (chIdx = 0; chIdx < totCh[SPEAKER_PLANE_NORMAL]; chIdx += 1) { |
1223 | 4.15k | while ((chIdx >= grpThresh) && (grp < 3)) { |
1224 | 1.44k | offset += numCh[1][grp] + numCh[2][grp]; |
1225 | 1.44k | grp += 1; |
1226 | 1.44k | grpThresh += numCh[SPEAKER_PLANE_NORMAL][grp]; |
1227 | 1.44k | } |
1228 | 2.70k | pceChMap[chIdx] = chIdx + offset; |
1229 | 2.70k | } |
1230 | 592 | offset = 0; |
1231 | 2.96k | for (grp = 0; grp < 4; grp += 1) { /* front, side, back and lfe */ |
1232 | 2.36k | offset += numCh[SPEAKER_PLANE_NORMAL][grp]; |
1233 | 7.10k | for (plane = SPEAKER_PLANE_TOP; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) { |
1234 | 4.73k | unsigned mapCh; |
1235 | 4.73k | for (mapCh = 0; mapCh < numCh[plane][grp]; mapCh += 1) { |
1236 | 0 | pceChMap[chIdx++] = offset; |
1237 | 0 | offset += 1; |
1238 | 0 | } |
1239 | 4.73k | } |
1240 | 2.36k | } |
1241 | 592 | return 0; |
1242 | 592 | } |
1243 | | |
1244 | | int CProgramConfig_GetElementTable(const CProgramConfig *pPce, |
1245 | | MP4_ELEMENT_ID elList[], |
1246 | 17.6k | const INT elListSize, UCHAR *pChMapIdx) { |
1247 | 17.6k | int i, el = 0; |
1248 | | |
1249 | 17.6k | FDK_ASSERT(elList != NULL); |
1250 | 17.6k | FDK_ASSERT(pChMapIdx != NULL); |
1251 | 17.6k | FDK_ASSERT(pPce != NULL); |
1252 | | |
1253 | 17.6k | *pChMapIdx = 0; |
1254 | | |
1255 | 17.6k | if ((elListSize < |
1256 | 17.6k | pPce->NumFrontChannelElements + pPce->NumSideChannelElements + |
1257 | 17.6k | pPce->NumBackChannelElements + pPce->NumLfeChannelElements) || |
1258 | 17.6k | (pPce->NumChannels == 0)) { |
1259 | 201 | return 0; |
1260 | 201 | } |
1261 | | |
1262 | 45.7k | for (i = 0; i < pPce->NumFrontChannelElements; i += 1) { |
1263 | 28.2k | elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE; |
1264 | 28.2k | } |
1265 | | |
1266 | 35.0k | for (i = 0; i < pPce->NumSideChannelElements; i += 1) { |
1267 | 17.5k | elList[el++] = (pPce->SideElementIsCpe[i]) ? ID_CPE : ID_SCE; |
1268 | 17.5k | } |
1269 | | |
1270 | 31.6k | for (i = 0; i < pPce->NumBackChannelElements; i += 1) { |
1271 | 14.1k | elList[el++] = (pPce->BackElementIsCpe[i]) ? ID_CPE : ID_SCE; |
1272 | 14.1k | } |
1273 | | |
1274 | 27.6k | for (i = 0; i < pPce->NumLfeChannelElements; i += 1) { |
1275 | 10.1k | elList[el++] = ID_LFE; |
1276 | 10.1k | } |
1277 | | |
1278 | | /* Find an corresponding channel configuration if possible */ |
1279 | 17.4k | switch (pPce->NumChannels) { |
1280 | 861 | case 1: |
1281 | 1.54k | case 2: |
1282 | | /* One and two channels have no alternatives. */ |
1283 | 1.54k | *pChMapIdx = pPce->NumChannels; |
1284 | 1.54k | break; |
1285 | 1.07k | case 3: |
1286 | 2.52k | case 4: |
1287 | 3.89k | case 5: |
1288 | 9.70k | case 6: { /* Test if the number of channels can be used as channel config: |
1289 | | */ |
1290 | 9.70k | C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1); |
1291 | | /* Create a PCE for the config to test ... */ |
1292 | 9.70k | CProgramConfig_GetDefault(tmpPce, pPce->NumChannels); |
1293 | | /* ... and compare it with the given one. */ |
1294 | 9.70k | *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) |
1295 | 9.70k | ? pPce->NumChannels |
1296 | 9.70k | : 0; |
1297 | | /* If compare result is 0 or 1 we can be sure that it is channel |
1298 | | * config 11. */ |
1299 | 9.70k | C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1); |
1300 | 9.70k | } break; |
1301 | 1.48k | case 7: { |
1302 | 1.48k | C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1); |
1303 | | /* Create a PCE for the config to test ... */ |
1304 | 1.48k | CProgramConfig_GetDefault(tmpPce, 11); |
1305 | | /* ... and compare it with the given one. */ |
1306 | 1.48k | *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 | 1.48k | C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1); |
1310 | 1.48k | } break; |
1311 | 4.26k | case 8: { /* Try the four possible 7.1ch configurations. One after the |
1312 | | other. */ |
1313 | 4.26k | UCHAR testCfg[4] = {32, 14, 12, 7}; |
1314 | 4.26k | C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1); |
1315 | 21.3k | for (i = 0; i < 4; i += 1) { |
1316 | | /* Create a PCE for the config to test ... */ |
1317 | 17.0k | CProgramConfig_GetDefault(tmpPce, testCfg[i]); |
1318 | | /* ... and compare it with the given one. */ |
1319 | 17.0k | 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 | 1.43k | *pChMapIdx = (testCfg[i] == 32) ? 12 : testCfg[i]; |
1325 | 1.43k | } |
1326 | 17.0k | } |
1327 | 4.26k | C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1); |
1328 | 4.26k | } break; |
1329 | 490 | default: |
1330 | | /* The PCE does not match any predefined channel configuration. */ |
1331 | 490 | *pChMapIdx = 0; |
1332 | 490 | break; |
1333 | 17.4k | } |
1334 | | |
1335 | 17.4k | return el; |
1336 | 17.4k | } |
1337 | | |
1338 | 818k | static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs) { |
1339 | 818k | int tmp = 0; |
1340 | | |
1341 | 818k | tmp = FDKreadBits(bs, 5); |
1342 | 818k | if (tmp == AOT_ESCAPE) { |
1343 | 497k | int tmp2 = FDKreadBits(bs, 6); |
1344 | 497k | tmp = 32 + tmp2; |
1345 | 497k | } |
1346 | | |
1347 | 818k | return (AUDIO_OBJECT_TYPE)tmp; |
1348 | 818k | } |
1349 | | |
1350 | 1.13M | static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits) { |
1351 | 1.13M | INT sampleRate; |
1352 | 1.13M | int idx; |
1353 | | |
1354 | 1.13M | idx = FDKreadBits(bs, nBits); |
1355 | 1.13M | if (idx == (1 << nBits) - 1) { |
1356 | 37.8k | if (FDKgetValidBits(bs) < 24) { |
1357 | 271 | return 0; |
1358 | 271 | } |
1359 | 37.5k | sampleRate = FDKreadBits(bs, 24); |
1360 | 1.09M | } else { |
1361 | 1.09M | sampleRate = SamplingRateTable[idx]; |
1362 | 1.09M | } |
1363 | | |
1364 | 1.13M | *index = idx; |
1365 | | |
1366 | 1.13M | return sampleRate; |
1367 | 1.13M | } |
1368 | | |
1369 | | static TRANSPORTDEC_ERROR GaSpecificConfig_Parse(CSGaSpecificConfig *self, |
1370 | | CSAudioSpecificConfig *asc, |
1371 | | HANDLE_FDK_BITSTREAM bs, |
1372 | 134k | UINT ascStartAnchor) { |
1373 | 134k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
1374 | | |
1375 | 134k | self->m_frameLengthFlag = FDKreadBits(bs, 1); |
1376 | | |
1377 | 134k | self->m_dependsOnCoreCoder = FDKreadBits(bs, 1); |
1378 | | |
1379 | 134k | if (self->m_dependsOnCoreCoder) self->m_coreCoderDelay = FDKreadBits(bs, 14); |
1380 | | |
1381 | 134k | self->m_extensionFlag = FDKreadBits(bs, 1); |
1382 | | |
1383 | 134k | if (asc->m_channelConfiguration == 0) { |
1384 | 29.6k | CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor); |
1385 | 29.6k | } |
1386 | | |
1387 | 134k | if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) { |
1388 | 49.8k | self->m_layer = FDKreadBits(bs, 3); |
1389 | 49.8k | } |
1390 | | |
1391 | 134k | if (self->m_extensionFlag) { |
1392 | 66.3k | if (asc->m_aot == AOT_ER_BSAC) { |
1393 | 1.56k | self->m_numOfSubFrame = FDKreadBits(bs, 5); |
1394 | 1.56k | self->m_layerLength = FDKreadBits(bs, 11); |
1395 | 1.56k | } |
1396 | | |
1397 | 66.3k | if ((asc->m_aot == AOT_ER_AAC_LC) || (asc->m_aot == AOT_ER_AAC_LTP) || |
1398 | 66.3k | (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD)) { |
1399 | 43.2k | asc->m_vcb11Flag = FDKreadBits(bs, 1); /* aacSectionDataResilienceFlag */ |
1400 | 43.2k | asc->m_rvlcFlag = |
1401 | 43.2k | FDKreadBits(bs, 1); /* aacScalefactorDataResilienceFlag */ |
1402 | 43.2k | asc->m_hcrFlag = FDKreadBits(bs, 1); /* aacSpectralDataResilienceFlag */ |
1403 | 43.2k | } |
1404 | | |
1405 | 66.3k | self->m_extensionFlag3 = FDKreadBits(bs, 1); |
1406 | 66.3k | } |
1407 | 134k | return (ErrorStatus); |
1408 | 134k | } |
1409 | | |
1410 | 537k | static INT skipSbrHeader(HANDLE_FDK_BITSTREAM hBs, int isUsac) { |
1411 | | /* Dummy parse SbrDfltHeader() */ |
1412 | 537k | INT dflt_header_extra1, dflt_header_extra2, bitsToSkip = 0; |
1413 | | |
1414 | 537k | if (!isUsac) { |
1415 | 386k | bitsToSkip = 6; |
1416 | 386k | FDKpushFor(hBs, 6); /* amp res 1, xover freq 3, reserved 2 */ |
1417 | 386k | } |
1418 | 537k | bitsToSkip += 8; |
1419 | 537k | FDKpushFor(hBs, 8); /* start / stop freq */ |
1420 | 537k | bitsToSkip += 2; |
1421 | 537k | dflt_header_extra1 = FDKreadBit(hBs); |
1422 | 537k | dflt_header_extra2 = FDKreadBit(hBs); |
1423 | 537k | bitsToSkip += 5 * dflt_header_extra1 + 6 * dflt_header_extra2; |
1424 | 537k | FDKpushFor(hBs, 5 * dflt_header_extra1 + 6 * dflt_header_extra2); |
1425 | | |
1426 | 537k | return bitsToSkip; |
1427 | 537k | } |
1428 | | |
1429 | | static INT ld_sbr_header(CSAudioSpecificConfig *asc, const INT dsFactor, |
1430 | 103k | HANDLE_FDK_BITSTREAM hBs, CSTpCallBacks *cb) { |
1431 | 103k | const int channelConfiguration = asc->m_channelConfiguration; |
1432 | 103k | int i = 0, j = 0; |
1433 | 103k | INT error = 0; |
1434 | 103k | MP4_ELEMENT_ID element = ID_NONE; |
1435 | | |
1436 | | /* check whether the channelConfiguration is defined in |
1437 | | * channel_configuration_array */ |
1438 | 103k | if (channelConfiguration < 0 || |
1439 | 103k | channelConfiguration > (INT)(sizeof(channel_configuration_array) / |
1440 | 103k | sizeof(MP4_ELEMENT_ID **) - |
1441 | 103k | 1)) { |
1442 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
1443 | 0 | } |
1444 | | |
1445 | | /* read elements of the passed channel_configuration until there is ID_NONE */ |
1446 | 512k | while ((element = channel_configuration_array[channelConfiguration][j]) != |
1447 | 512k | 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 | 420k | if (element == ID_SCE || element == ID_CPE || element == ID_LFE) { |
1453 | 420k | error |= cb->cbSbr( |
1454 | 420k | cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor, |
1455 | 420k | asc->m_extensionSamplingFrequency / dsFactor, |
1456 | 420k | asc->m_samplesPerFrame / dsFactor, AOT_ER_AAC_ELD, element, i++, 0, 0, |
1457 | 420k | asc->configMode, &asc->SbrConfigChanged, dsFactor); |
1458 | 420k | if (error != TRANSPORTDEC_OK) { |
1459 | 10.7k | goto bail; |
1460 | 10.7k | } |
1461 | 420k | } |
1462 | 409k | j++; |
1463 | 409k | } |
1464 | 103k | bail: |
1465 | 103k | return error; |
1466 | 103k | } |
1467 | | |
1468 | | static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, |
1469 | | HANDLE_FDK_BITSTREAM hBs, |
1470 | 176k | CSTpCallBacks *cb) { |
1471 | 176k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
1472 | 176k | CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig; |
1473 | 176k | UINT eldExtType; |
1474 | 176k | int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0, |
1475 | 176k | sbrIndex, eldExtCnt = 0; |
1476 | | |
1477 | 176k | unsigned char downscale_fill_nibble; |
1478 | | |
1479 | 176k | FDKmemclear(esc, sizeof(CSEldSpecificConfig)); |
1480 | | |
1481 | 176k | esc->m_frameLengthFlag = FDKreadBits(hBs, 1); |
1482 | 176k | if (esc->m_frameLengthFlag) { |
1483 | 97.3k | asc->m_samplesPerFrame = 480; |
1484 | 97.3k | } else { |
1485 | 78.6k | asc->m_samplesPerFrame = 512; |
1486 | 78.6k | } |
1487 | | |
1488 | 176k | asc->m_vcb11Flag = FDKreadBits(hBs, 1); |
1489 | 176k | asc->m_rvlcFlag = FDKreadBits(hBs, 1); |
1490 | 176k | asc->m_hcrFlag = FDKreadBits(hBs, 1); |
1491 | | |
1492 | 176k | esc->m_sbrPresentFlag = FDKreadBits(hBs, 1); |
1493 | | |
1494 | 176k | if (esc->m_sbrPresentFlag == 1) { |
1495 | 118k | esc->m_sbrSamplingRate = |
1496 | 118k | FDKreadBits(hBs, 1); /* 0: single rate, 1: dual rate */ |
1497 | 118k | esc->m_sbrCrcFlag = FDKreadBits(hBs, 1); |
1498 | | |
1499 | 118k | asc->m_extensionSamplingFrequency = asc->m_samplingFrequency |
1500 | 118k | << esc->m_sbrSamplingRate; |
1501 | | |
1502 | 118k | 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 | 118k | switch (asc->m_channelConfiguration) { |
1507 | 11.5k | case 1: |
1508 | 25.9k | case 2: |
1509 | 25.9k | numSbrHeader = 1; |
1510 | 25.9k | break; |
1511 | 1.07k | case 3: |
1512 | 1.07k | numSbrHeader = 2; |
1513 | 1.07k | break; |
1514 | 1.13k | case 4: |
1515 | 3.20k | case 5: |
1516 | 3.93k | case 6: |
1517 | 3.93k | numSbrHeader = 3; |
1518 | 3.93k | break; |
1519 | 23.8k | case 7: |
1520 | 32.3k | case 11: |
1521 | 39.9k | case 12: |
1522 | 86.7k | case 14: |
1523 | 86.7k | numSbrHeader = 4; |
1524 | 86.7k | break; |
1525 | 564 | default: |
1526 | 564 | numSbrHeader = 0; |
1527 | 564 | break; |
1528 | 118k | } |
1529 | 505k | for (sbrIndex = 0; sbrIndex < numSbrHeader; sbrIndex++) { |
1530 | 386k | ldSbrLen += skipSbrHeader(hBs, 0); |
1531 | 386k | } |
1532 | 118k | } else { |
1533 | 0 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
1534 | 0 | } |
1535 | 118k | } |
1536 | 176k | esc->m_useLdQmfTimeAlign = 0; |
1537 | | |
1538 | | /* new ELD syntax */ |
1539 | 176k | eldExtLenSum = FDKgetValidBits(hBs); |
1540 | 176k | esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency; |
1541 | | /* parse ExtTypeConfigData */ |
1542 | 517k | while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) && |
1543 | 517k | ((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) { |
1544 | 358k | eldExtLen = len = FDKreadBits(hBs, 4); |
1545 | 358k | if (len == 0xf) { |
1546 | 19.7k | len = FDKreadBits(hBs, 8); |
1547 | 19.7k | eldExtLen += len; |
1548 | | |
1549 | 19.7k | if (len == 0xff) { |
1550 | 8.46k | len = FDKreadBits(hBs, 16); |
1551 | 8.46k | eldExtLen += len; |
1552 | 8.46k | } |
1553 | 19.7k | } |
1554 | | |
1555 | 358k | switch (eldExtType) { |
1556 | 79.8k | case ELDEXT_LDSAC: |
1557 | 79.8k | esc->m_useLdQmfTimeAlign = 1; |
1558 | 79.8k | if (cb->cbSsc != NULL) { |
1559 | 79.8k | ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc( |
1560 | 79.8k | cb->cbSscData, hBs, asc->m_aot, |
1561 | 79.8k | asc->m_samplingFrequency << esc->m_sbrSamplingRate, |
1562 | 79.8k | asc->m_samplesPerFrame << esc->m_sbrSamplingRate, |
1563 | 79.8k | asc->m_channelConfiguration, 1, /* stereoConfigIndex */ |
1564 | 79.8k | -1, /* nTimeSlots: read from bitstream */ |
1565 | 79.8k | eldExtLen, asc->configMode, &asc->SacConfigChanged); |
1566 | 79.8k | if (ErrorStatus != TRANSPORTDEC_OK) { |
1567 | 7.98k | return TRANSPORTDEC_PARSE_ERROR; |
1568 | 7.98k | } |
1569 | 71.8k | if (esc->m_downscaledSamplingFrequency != asc->m_samplingFrequency) { |
1570 | 3.82k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled |
1571 | | mode not allowed */ |
1572 | 3.82k | } |
1573 | 68.0k | break; |
1574 | 71.8k | } |
1575 | | |
1576 | 79.8k | FDK_FALLTHROUGH; |
1577 | 254k | default: |
1578 | 103M | for (cnt = 0; cnt < eldExtLen; cnt++) { |
1579 | 103M | FDKreadBits(hBs, 8); |
1580 | 103M | } |
1581 | 254k | break; |
1582 | | |
1583 | 24.4k | case ELDEXT_DOWNSCALEINFO: |
1584 | 24.4k | UCHAR tmpDownscaleFreqIdx; |
1585 | 24.4k | esc->m_downscaledSamplingFrequency = |
1586 | 24.4k | getSampleRate(hBs, &tmpDownscaleFreqIdx, 4); |
1587 | 24.4k | if (esc->m_downscaledSamplingFrequency == 0 || |
1588 | 24.4k | esc->m_downscaledSamplingFrequency > 96000) { |
1589 | 1.62k | return TRANSPORTDEC_PARSE_ERROR; |
1590 | 1.62k | } |
1591 | 22.8k | downscale_fill_nibble = FDKreadBits(hBs, 4); |
1592 | 22.8k | if (downscale_fill_nibble != 0x0) { |
1593 | 3.07k | return TRANSPORTDEC_PARSE_ERROR; |
1594 | 3.07k | } |
1595 | 19.7k | if (esc->m_useLdQmfTimeAlign == 1) { |
1596 | 578 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled |
1597 | | mode not allowed */ |
1598 | 578 | } |
1599 | 19.1k | break; |
1600 | 358k | } |
1601 | 358k | } |
1602 | 158k | if (eldExtType != ELDEXT_TERM) { |
1603 | 8.58k | return TRANSPORTDEC_PARSE_ERROR; |
1604 | 8.58k | } |
1605 | | |
1606 | 150k | if ((INT)FDKgetValidBits(hBs) < 0) { |
1607 | 983 | return TRANSPORTDEC_PARSE_ERROR; |
1608 | 983 | } |
1609 | | |
1610 | 149k | if (esc->m_sbrPresentFlag == 1 && numSbrHeader != 0) { |
1611 | 104k | INT dsFactor = 1; /* Downscale factor must be 1 or even for SBR */ |
1612 | 104k | if (esc->m_downscaledSamplingFrequency != 0) { |
1613 | 104k | if (asc->m_samplingFrequency % esc->m_downscaledSamplingFrequency != 0) { |
1614 | 762 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
1615 | 762 | } |
1616 | 104k | dsFactor = asc->m_samplingFrequency / esc->m_downscaledSamplingFrequency; |
1617 | 104k | if (dsFactor != 1 && (dsFactor)&1) { |
1618 | 1.10k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* SBR needs an even downscale |
1619 | | factor */ |
1620 | 1.10k | } |
1621 | 103k | if (dsFactor != 1 && dsFactor != 2 && dsFactor != 4) { |
1622 | 433 | dsFactor = 1; /* don't apply dsf for not yet supported even dsfs */ |
1623 | 433 | } |
1624 | 103k | if ((INT)asc->m_samplesPerFrame % dsFactor != 0) { |
1625 | 0 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* frameSize/dsf must be an |
1626 | | integer number */ |
1627 | 0 | } |
1628 | 103k | } |
1629 | 103k | eldExtLenSum = eldExtLenSum - FDKgetValidBits(hBs); |
1630 | 103k | FDKpushBack(hBs, eldExtLenSum + ldSbrLen); |
1631 | 103k | if (0 != ld_sbr_header(asc, dsFactor, hBs, cb)) { |
1632 | 10.7k | return TRANSPORTDEC_PARSE_ERROR; |
1633 | 10.7k | } |
1634 | 92.3k | FDKpushFor(hBs, eldExtLenSum); |
1635 | 92.3k | } |
1636 | 136k | return (ErrorStatus); |
1637 | 149k | } |
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 | 424k | UCHAR *configTargetBuffer, const USHORT configTargetBufferSize_bytes) { |
1648 | 424k | FDK_BITSTREAM usacConf; |
1649 | 424k | UINT const nBits = fAbs(configSize_bits); |
1650 | 424k | UINT j, tmp; |
1651 | | |
1652 | 424k | if (nBits > 8 * (UINT)configTargetBufferSize_bytes) { |
1653 | 993 | return 1; |
1654 | 993 | } |
1655 | 423k | FDKmemclear(configTargetBuffer, configTargetBufferSize_bytes); |
1656 | | |
1657 | 423k | FDKinitBitStream(&usacConf, configTargetBuffer, configTargetBufferSize_bytes, |
1658 | 423k | nBits, BS_WRITER); |
1659 | 423k | if (configSize_bits < 0) { |
1660 | 423k | FDKpushBack(hBs, nBits); |
1661 | 423k | } |
1662 | 1.60M | for (j = nBits; j > 31; j -= 32) { |
1663 | 1.18M | tmp = FDKreadBits(hBs, 32); |
1664 | 1.18M | FDKwriteBits(&usacConf, tmp, 32); |
1665 | 1.18M | } |
1666 | 423k | if (j > 0) { |
1667 | 422k | tmp = FDKreadBits(hBs, j); |
1668 | 422k | FDKwriteBits(&usacConf, tmp, j); |
1669 | 422k | } |
1670 | 423k | FDKsyncCache(&usacConf); |
1671 | 423k | if (configSize_bits > 0) { |
1672 | 0 | FDKpushBack(hBs, nBits); |
1673 | 0 | } |
1674 | | |
1675 | 423k | return 0; |
1676 | 424k | } |
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 | 464k | const AUDIO_OBJECT_TYPE aot) { |
1695 | 464k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
1696 | | |
1697 | 464k | UINT usacExtElementType = escapedValue(hBs, 4, 8, 16); |
1698 | | |
1699 | | /* recurve extension elements which are invalid for USAC */ |
1700 | 464k | if (aot == AOT_USAC) { |
1701 | 464k | switch (usacExtElementType) { |
1702 | 42.9k | case ID_EXT_ELE_FILL: |
1703 | 46.6k | case ID_EXT_ELE_MPEGS: |
1704 | 52.0k | case ID_EXT_ELE_SAOC: |
1705 | 76.3k | case ID_EXT_ELE_AUDIOPREROLL: |
1706 | 321k | case ID_EXT_ELE_UNI_DRC: |
1707 | 321k | break; |
1708 | 143k | default: |
1709 | 143k | usacExtElementType = ID_EXT_ELE_UNKNOWN; |
1710 | 143k | break; |
1711 | 464k | } |
1712 | 464k | } |
1713 | | |
1714 | 464k | int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16); |
1715 | 464k | extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength; |
1716 | 464k | INT bsAnchor; |
1717 | | |
1718 | 464k | if (FDKreadBit(hBs)) /* usacExtElementDefaultLengthPresent */ |
1719 | 38.6k | extElement->usacExtElementDefaultLength = escapedValue(hBs, 8, 16, 0) + 1; |
1720 | 426k | else |
1721 | 426k | extElement->usacExtElementDefaultLength = 0; |
1722 | | |
1723 | 464k | extElement->usacExtElementPayloadFrag = FDKreadBit(hBs); |
1724 | | |
1725 | 464k | bsAnchor = (INT)FDKgetValidBits(hBs); |
1726 | | |
1727 | 464k | switch (usacExtElementType) { |
1728 | 143k | case ID_EXT_ELE_UNKNOWN: |
1729 | 186k | case ID_EXT_ELE_FILL: |
1730 | 186k | break; |
1731 | 24.2k | case ID_EXT_ELE_AUDIOPREROLL: |
1732 | | /* No configuration element */ |
1733 | 24.2k | extElement->usacExtElementHasAudioPreRoll = 1; |
1734 | 24.2k | break; |
1735 | 245k | case ID_EXT_ELE_UNI_DRC: { |
1736 | 245k | if (cb->cbUniDrc != NULL) { |
1737 | 245k | ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( |
1738 | 245k | cb->cbUniDrcData, hBs, usacExtElementConfigLength, |
1739 | 245k | 0, /* uniDrcConfig */ |
1740 | 245k | subStreamIndex, 0, aot); |
1741 | 245k | if (ErrorStatus != TRANSPORTDEC_OK) { |
1742 | 0 | return ErrorStatus; |
1743 | 0 | } |
1744 | 245k | } |
1745 | 245k | } break; |
1746 | 245k | default: |
1747 | 9.07k | usacExtElementType = ID_EXT_ELE_UNKNOWN; |
1748 | 9.07k | break; |
1749 | 464k | } |
1750 | 464k | 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 | 464k | { |
1755 | 464k | INT left_bits = (usacExtElementConfigLength << 3) - |
1756 | 464k | (bsAnchor - (INT)FDKgetValidBits(hBs)); |
1757 | 464k | if (left_bits >= 0) { |
1758 | 455k | FDKpushFor(hBs, left_bits); |
1759 | 455k | } else { |
1760 | | /* parsed too many bits */ |
1761 | 9.53k | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
1762 | 9.53k | } |
1763 | 464k | } |
1764 | | |
1765 | 464k | return ErrorStatus; |
1766 | 464k | } |
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 | 40.5k | const CSTpCallBacks *cb) { |
1776 | 40.5k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
1777 | | |
1778 | 40.5k | int numConfigExtensions; |
1779 | 40.5k | UINT usacConfigExtType; |
1780 | 40.5k | int usacConfigExtLength; |
1781 | 40.5k | int loudnessInfoSetIndex = |
1782 | 40.5k | -1; /* index of loudnessInfoSet config extension. -1 if not contained. */ |
1783 | 40.5k | int tmp_subStreamIndex = 0; |
1784 | 40.5k | AUDIO_OBJECT_TYPE tmp_aot = AOT_USAC; |
1785 | | |
1786 | 40.5k | numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1; |
1787 | 318k | for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) { |
1788 | 302k | INT nbits; |
1789 | 302k | int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs); |
1790 | 302k | usacConfigExtType = escapedValue(hBs, 4, 8, 16); |
1791 | 302k | usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16); |
1792 | | |
1793 | | /* Start bit position of config extension */ |
1794 | 302k | nbits = (INT)FDKgetValidBits(hBs); |
1795 | | |
1796 | | /* Return an error in case the bitbuffer fill level is too low. */ |
1797 | 302k | if (nbits < usacConfigExtLength * 8) { |
1798 | 9.15k | return TRANSPORTDEC_PARSE_ERROR; |
1799 | 9.15k | } |
1800 | | |
1801 | 293k | switch (usacConfigExtType) { |
1802 | 87.2k | case ID_CONFIG_EXT_FILL: |
1803 | 90.5k | for (int i = 0; i < usacConfigExtLength; i++) { |
1804 | 5.07k | if (FDKreadBits(hBs, 8) != 0xa5) { |
1805 | 1.86k | return TRANSPORTDEC_PARSE_ERROR; |
1806 | 1.86k | } |
1807 | 5.07k | } |
1808 | 85.4k | break; |
1809 | 85.4k | case ID_CONFIG_EXT_LOUDNESS_INFO: { |
1810 | 43.5k | if (cb->cbUniDrc != NULL) { |
1811 | 43.5k | ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( |
1812 | 43.5k | cb->cbUniDrcData, hBs, usacConfigExtLength, |
1813 | 43.5k | 1, /* loudnessInfoSet */ |
1814 | 43.5k | tmp_subStreamIndex, loudnessInfoSetConfigExtensionPosition, |
1815 | 43.5k | tmp_aot); |
1816 | 43.5k | if (ErrorStatus != TRANSPORTDEC_OK) { |
1817 | 0 | return ErrorStatus; |
1818 | 0 | } |
1819 | 43.5k | loudnessInfoSetIndex = confExtIdx; |
1820 | 43.5k | } |
1821 | 43.5k | } break; |
1822 | 162k | default: |
1823 | 162k | break; |
1824 | 293k | } |
1825 | | |
1826 | | /* Skip remaining bits. If too many bits were parsed, assume error. */ |
1827 | 291k | usacConfigExtLength = |
1828 | 291k | 8 * usacConfigExtLength - (nbits - (INT)FDKgetValidBits(hBs)); |
1829 | 291k | if (usacConfigExtLength < 0) { |
1830 | 13.6k | return TRANSPORTDEC_PARSE_ERROR; |
1831 | 13.6k | } |
1832 | 277k | FDKpushFor(hBs, usacConfigExtLength); |
1833 | 277k | } |
1834 | | |
1835 | 15.8k | if (loudnessInfoSetIndex == -1 && cb->cbUniDrc != NULL) { |
1836 | | /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding |
1837 | | * an empty config extension */ |
1838 | 13.1k | ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( |
1839 | 13.1k | cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, tmp_subStreamIndex, |
1840 | 13.1k | 0, tmp_aot); |
1841 | 13.1k | if (ErrorStatus != TRANSPORTDEC_OK) { |
1842 | 0 | return ErrorStatus; |
1843 | 0 | } |
1844 | 13.1k | } |
1845 | | |
1846 | 15.8k | return ErrorStatus; |
1847 | 15.8k | } |
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 | 280k | const CSTpCallBacks *cb) { |
1856 | 280k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
1857 | 280k | CSUsacConfig *usc = &asc->m_sc.m_usacConfig; |
1858 | 280k | int i, numberOfElements; |
1859 | 280k | int channelElementIdx = |
1860 | 280k | 0; /* index for elements which contain audio channels (sce, cpe, lfe) */ |
1861 | 280k | SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0}; |
1862 | 280k | int uniDrcElement = |
1863 | 280k | -1; /* index of uniDrc extension element. -1 if not contained. */ |
1864 | | |
1865 | 280k | numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1; |
1866 | 280k | usc->m_usacNumElements = numberOfElements; |
1867 | 280k | if (numberOfElements > TP_USAC_MAX_ELEMENTS) { |
1868 | 1.19k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
1869 | 1.19k | } |
1870 | 279k | usc->m_nUsacChannels = 0; |
1871 | 279k | usc->m_channelConfigurationIndex = asc->m_channelConfiguration; |
1872 | | |
1873 | 279k | if (asc->m_aot == AOT_USAC) { |
1874 | 279k | sc_chan_config = sc_chan_config_tab[usc->m_channelConfigurationIndex]; |
1875 | | |
1876 | 279k | if (sc_chan_config.nCh > (SCHAR)TP_USAC_MAX_SPEAKERS) { |
1877 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
1878 | 0 | } |
1879 | 279k | } |
1880 | | |
1881 | 981k | for (i = 0; i < numberOfElements; i++) { |
1882 | 737k | MP4_ELEMENT_ID usacElementType = (MP4_ELEMENT_ID)( |
1883 | 737k | FDKreadBits(hBs, 2) | USAC_ID_BIT); /* set USAC_ID_BIT to map |
1884 | | usacElementType to |
1885 | | MP4_ELEMENT_ID enum */ |
1886 | 737k | usc->element[i].usacElementType = usacElementType; |
1887 | | |
1888 | | /* sanity check: update element counter */ |
1889 | 737k | if (asc->m_aot == AOT_USAC) { |
1890 | 737k | switch (usacElementType) { |
1891 | 106k | case ID_USAC_SCE: |
1892 | 106k | sc_chan_config.nSCE--; |
1893 | 106k | break; |
1894 | 163k | case ID_USAC_CPE: |
1895 | 163k | sc_chan_config.nCPE--; |
1896 | 163k | break; |
1897 | 2.43k | case ID_USAC_LFE: |
1898 | 2.43k | sc_chan_config.nLFE--; |
1899 | 2.43k | break; |
1900 | 464k | default: |
1901 | 464k | break; |
1902 | 737k | } |
1903 | 737k | if (usc->m_channelConfigurationIndex) { |
1904 | | /* sanity check: no element counter may be smaller zero */ |
1905 | 737k | if (sc_chan_config.nCPE < 0 || sc_chan_config.nSCE < 0 || |
1906 | 737k | sc_chan_config.nLFE < 0) { |
1907 | 15.2k | return TRANSPORTDEC_PARSE_ERROR; |
1908 | 15.2k | } |
1909 | 737k | } |
1910 | 737k | } |
1911 | | |
1912 | 721k | switch (usacElementType) { |
1913 | 98.3k | case ID_USAC_SCE: |
1914 | | /* UsacCoreConfig() ISO/IEC FDIS 23003-3 Table 10 */ |
1915 | 98.3k | if (FDKreadBit(hBs)) { /* tw_mdct */ |
1916 | 1.13k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
1917 | 1.13k | } |
1918 | 97.2k | usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1); |
1919 | | /* end of UsacCoreConfig() */ |
1920 | 97.2k | if (usc->m_sbrRatioIndex > 0) { |
1921 | 51.9k | if (cb->cbSbr == NULL) { |
1922 | 0 | return TRANSPORTDEC_UNKOWN_ERROR; |
1923 | 0 | } |
1924 | | /* SbrConfig() ISO/IEC FDIS 23003-3 Table 11 */ |
1925 | 51.9k | usc->element[i].m_harmonicSBR = FDKreadBit(hBs); |
1926 | 51.9k | usc->element[i].m_interTes = FDKreadBit(hBs); |
1927 | 51.9k | usc->element[i].m_pvc = FDKreadBit(hBs); |
1928 | 51.9k | if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, |
1929 | 51.9k | asc->m_extensionSamplingFrequency, |
1930 | 51.9k | asc->m_samplesPerFrame, asc->m_aot, ID_SCE, |
1931 | 51.9k | channelElementIdx, usc->element[i].m_harmonicSBR, |
1932 | 51.9k | usc->element[i].m_stereoConfigIndex, asc->configMode, |
1933 | 51.9k | &asc->SbrConfigChanged, 1)) { |
1934 | 577 | return TRANSPORTDEC_PARSE_ERROR; |
1935 | 577 | } |
1936 | | /* end of SbrConfig() */ |
1937 | 51.9k | } |
1938 | 96.6k | usc->m_nUsacChannels += 1; |
1939 | 96.6k | channelElementIdx++; |
1940 | 96.6k | break; |
1941 | | |
1942 | 158k | case ID_USAC_CPE: |
1943 | | /* UsacCoreConfig() ISO/IEC FDIS 23003-3 Table 10 */ |
1944 | 158k | if (FDKreadBit(hBs)) { /* tw_mdct */ |
1945 | 2.18k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
1946 | 2.18k | } |
1947 | 156k | usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1); |
1948 | | /* end of UsacCoreConfig() */ |
1949 | 156k | if (usc->m_sbrRatioIndex > 0) { |
1950 | 151k | if (cb->cbSbr == NULL) return TRANSPORTDEC_UNKOWN_ERROR; |
1951 | | /* SbrConfig() ISO/IEC FDIS 23003-3 */ |
1952 | 151k | usc->element[i].m_harmonicSBR = FDKreadBit(hBs); |
1953 | 151k | usc->element[i].m_interTes = FDKreadBit(hBs); |
1954 | 151k | usc->element[i].m_pvc = FDKreadBit(hBs); |
1955 | 151k | { |
1956 | 151k | INT bitsToSkip = skipSbrHeader(hBs, 1); |
1957 | | /* read stereoConfigIndex */ |
1958 | 151k | usc->element[i].m_stereoConfigIndex = FDKreadBits(hBs, 2); |
1959 | | /* rewind */ |
1960 | 151k | FDKpushBack(hBs, bitsToSkip + 2); |
1961 | 151k | } |
1962 | 151k | { |
1963 | 151k | MP4_ELEMENT_ID el_type = |
1964 | 151k | (usc->element[i].m_stereoConfigIndex == 1 || |
1965 | 151k | usc->element[i].m_stereoConfigIndex == 2) |
1966 | 151k | ? ID_SCE |
1967 | 151k | : ID_CPE; |
1968 | 151k | if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, |
1969 | 151k | asc->m_extensionSamplingFrequency, |
1970 | 151k | asc->m_samplesPerFrame, asc->m_aot, el_type, |
1971 | 151k | channelElementIdx, usc->element[i].m_harmonicSBR, |
1972 | 151k | usc->element[i].m_stereoConfigIndex, asc->configMode, |
1973 | 151k | &asc->SbrConfigChanged, 1)) { |
1974 | 442 | return TRANSPORTDEC_PARSE_ERROR; |
1975 | 442 | } |
1976 | 151k | } |
1977 | | /* end of SbrConfig() */ |
1978 | | |
1979 | 150k | usc->element[i].m_stereoConfigIndex = |
1980 | 150k | FDKreadBits(hBs, 2); /* Needed in RM5 syntax */ |
1981 | | |
1982 | 150k | if (usc->element[i].m_stereoConfigIndex > 0) { |
1983 | 102k | if (cb->cbSsc != NULL) { |
1984 | 102k | int samplesPerFrame = asc->m_samplesPerFrame; |
1985 | | |
1986 | 102k | if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2; |
1987 | 102k | if (usc->m_sbrRatioIndex == 2) |
1988 | 13.9k | samplesPerFrame = (samplesPerFrame * 8) / 3; |
1989 | 102k | if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1; |
1990 | | |
1991 | | /* Mps212Config() ISO/IEC FDIS 23003-3 */ |
1992 | 102k | if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot, |
1993 | 102k | asc->m_extensionSamplingFrequency, samplesPerFrame, |
1994 | 102k | 1, /* only downmix channels (residual channels are |
1995 | | not counted) */ |
1996 | 102k | usc->element[i].m_stereoConfigIndex, |
1997 | 102k | usc->m_coreSbrFrameLengthIndex, |
1998 | 102k | 0, /* don't know the length */ |
1999 | 102k | asc->configMode, &asc->SacConfigChanged)) { |
2000 | 5.19k | return TRANSPORTDEC_PARSE_ERROR; |
2001 | 5.19k | } |
2002 | | /* end of Mps212Config() */ |
2003 | 102k | } else { |
2004 | 0 | return TRANSPORTDEC_UNKOWN_ERROR; |
2005 | 0 | } |
2006 | 102k | } |
2007 | 150k | } else { |
2008 | 5.41k | usc->element[i].m_stereoConfigIndex = 0; |
2009 | 5.41k | } |
2010 | 150k | usc->m_nUsacChannels += 2; |
2011 | | |
2012 | 150k | channelElementIdx++; |
2013 | 150k | 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 | 464k | case ID_USAC_EXT: |
2037 | 464k | ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0, |
2038 | 464k | asc->m_samplesPerFrame, 0, asc->m_aot); |
2039 | 464k | if (usc->element[i].extElement.usacExtElementType == |
2040 | 464k | ID_EXT_ELE_UNI_DRC) { |
2041 | 245k | uniDrcElement = i; |
2042 | 245k | } |
2043 | | |
2044 | 464k | if (ErrorStatus) { |
2045 | 9.53k | return ErrorStatus; |
2046 | 9.53k | } |
2047 | 455k | break; |
2048 | | |
2049 | 455k | default: |
2050 | | /* non USAC-element encountered */ |
2051 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
2052 | 721k | } |
2053 | 721k | } |
2054 | | |
2055 | 244k | if (asc->m_aot == AOT_USAC) { |
2056 | 244k | if (usc->m_channelConfigurationIndex) { |
2057 | | /* sanity check: all element counter must be zero */ |
2058 | 244k | if (sc_chan_config.nCPE | sc_chan_config.nSCE | sc_chan_config.nLFE) { |
2059 | 7.53k | return TRANSPORTDEC_PARSE_ERROR; |
2060 | 7.53k | } |
2061 | 244k | } 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 | 244k | } |
2070 | | |
2071 | 237k | if (uniDrcElement == -1 && cb->cbUniDrc != NULL) { |
2072 | | /* no uniDrcConfig contained. Clear the uniDrcConfig struct by feeding an |
2073 | | * empty extension element */ |
2074 | 227k | int subStreamIndex = 0; |
2075 | 227k | ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( |
2076 | 227k | cb->cbUniDrcData, NULL, 0, 0 /* uniDrcConfig */, subStreamIndex, 0, |
2077 | 227k | asc->m_aot); |
2078 | 227k | if (ErrorStatus != TRANSPORTDEC_OK) { |
2079 | 0 | return ErrorStatus; |
2080 | 0 | } |
2081 | 227k | } |
2082 | | |
2083 | 237k | return ErrorStatus; |
2084 | 237k | } |
2085 | | |
2086 | | /* Mapping of coreSbrFrameLengthIndex defined by Table 70 in ISO/IEC 23003-3 */ |
2087 | | static TRANSPORTDEC_ERROR UsacConfig_SetCoreSbrFrameLengthIndex( |
2088 | 289k | CSAudioSpecificConfig *asc, int coreSbrFrameLengthIndex) { |
2089 | 289k | int sbrRatioIndex_val; |
2090 | | |
2091 | 289k | if (coreSbrFrameLengthIndex > 4) { |
2092 | 2.97k | return TRANSPORTDEC_PARSE_ERROR; /* reserved values */ |
2093 | 2.97k | } |
2094 | 286k | asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex = coreSbrFrameLengthIndex; |
2095 | 286k | asc->m_samplesPerFrame = usacFrameLength[coreSbrFrameLengthIndex]; |
2096 | 286k | sbrRatioIndex_val = sbrRatioIndex[coreSbrFrameLengthIndex]; |
2097 | 286k | asc->m_sc.m_usacConfig.m_sbrRatioIndex = sbrRatioIndex_val; |
2098 | | |
2099 | 286k | if (sbrRatioIndex_val > 0) { |
2100 | 219k | asc->m_sbrPresentFlag = 1; |
2101 | 219k | asc->m_extensionSamplingFrequency = asc->m_samplingFrequency; |
2102 | 219k | asc->m_extensionSamplingFrequencyIndex = asc->m_samplingFrequencyIndex; |
2103 | 219k | switch (sbrRatioIndex_val) { |
2104 | 64.8k | case 1: /* sbrRatio = 4:1 */ |
2105 | 64.8k | asc->m_samplingFrequency >>= 2; |
2106 | 64.8k | asc->m_samplesPerFrame >>= 2; |
2107 | 64.8k | break; |
2108 | 65.6k | case 2: /* sbrRatio = 8:3 */ |
2109 | 65.6k | asc->m_samplingFrequency = (asc->m_samplingFrequency * 3) / 8; |
2110 | 65.6k | asc->m_samplesPerFrame = (asc->m_samplesPerFrame * 3) / 8; |
2111 | 65.6k | break; |
2112 | 88.9k | case 3: /* sbrRatio = 2:1 */ |
2113 | 88.9k | asc->m_samplingFrequency >>= 1; |
2114 | 88.9k | asc->m_samplesPerFrame >>= 1; |
2115 | 88.9k | break; |
2116 | 0 | default: |
2117 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
2118 | 219k | } |
2119 | 219k | asc->m_samplingFrequencyIndex = |
2120 | 219k | getSamplingRateIndex(asc->m_samplingFrequency, 4); |
2121 | 219k | } |
2122 | | |
2123 | 286k | return TRANSPORTDEC_OK; |
2124 | 286k | } |
2125 | | |
2126 | | static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc, |
2127 | | HANDLE_FDK_BITSTREAM hBs, |
2128 | 294k | CSTpCallBacks *cb) { |
2129 | 294k | int usacSamplingFrequency, channelConfigurationIndex, coreSbrFrameLengthIndex; |
2130 | 294k | TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; |
2131 | | |
2132 | | /* Start bit position of usacConfig */ |
2133 | 294k | INT nbits = (INT)FDKgetValidBits(hBs); |
2134 | | |
2135 | 294k | usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5); |
2136 | 294k | if (usacSamplingFrequency == 0 || usacSamplingFrequency > 96000) { |
2137 | 4.27k | return TRANSPORTDEC_PARSE_ERROR; |
2138 | 4.27k | } |
2139 | 289k | asc->m_samplingFrequency = (UINT)usacSamplingFrequency; |
2140 | | |
2141 | 289k | coreSbrFrameLengthIndex = FDKreadBits(hBs, 3); |
2142 | 289k | if (UsacConfig_SetCoreSbrFrameLengthIndex(asc, coreSbrFrameLengthIndex) != |
2143 | 289k | TRANSPORTDEC_OK) { |
2144 | 2.97k | return TRANSPORTDEC_PARSE_ERROR; |
2145 | 2.97k | } |
2146 | | |
2147 | 286k | channelConfigurationIndex = FDKreadBits(hBs, 5); |
2148 | 286k | if (channelConfigurationIndex > 2) { |
2149 | 4.20k | return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2] |
2150 | | are supported */ |
2151 | 4.20k | } |
2152 | | |
2153 | 282k | if (channelConfigurationIndex == 0) { |
2154 | 2.34k | return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2] |
2155 | | are supported */ |
2156 | 2.34k | } |
2157 | 280k | asc->m_channelConfiguration = channelConfigurationIndex; |
2158 | | |
2159 | 280k | err = UsacRsv60DecoderConfig_Parse(asc, hBs, cb); |
2160 | 280k | if (err != TRANSPORTDEC_OK) { |
2161 | 43.0k | return err; |
2162 | 43.0k | } |
2163 | | |
2164 | 237k | if (FDKreadBits(hBs, 1)) { /* usacConfigExtensionPresent */ |
2165 | 40.5k | err = configExtension(&asc->m_sc.m_usacConfig, hBs, cb); |
2166 | 40.5k | if (err != TRANSPORTDEC_OK) { |
2167 | 24.6k | return err; |
2168 | 24.6k | } |
2169 | 196k | } else if (cb->cbUniDrc != NULL) { |
2170 | | /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding |
2171 | | * an empty config extension */ |
2172 | 196k | err = (TRANSPORTDEC_ERROR)cb->cbUniDrc( |
2173 | 196k | cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, 0, 0, asc->m_aot); |
2174 | 196k | if (err != TRANSPORTDEC_OK) { |
2175 | 0 | return err; |
2176 | 0 | } |
2177 | 196k | } |
2178 | | |
2179 | | /* sanity check whether number of channels signaled in UsacDecoderConfig() |
2180 | | matches the number of channels required by channelConfigurationIndex */ |
2181 | 212k | if ((channelConfigurationIndex > 0) && |
2182 | 212k | (sc_chan_config_tab[channelConfigurationIndex].nCh != |
2183 | 212k | 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 | 212k | INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits; |
2189 | 212k | if (StoreConfigAsBitstream(hBs, configSize_bits, |
2190 | 212k | asc->m_sc.m_usacConfig.UsacConfig, |
2191 | 212k | TP_USAC_MAX_CONFIG_LEN)) { |
2192 | 640 | return TRANSPORTDEC_PARSE_ERROR; |
2193 | 640 | } |
2194 | 211k | asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits); |
2195 | | |
2196 | 211k | return err; |
2197 | 212k | } |
2198 | | |
2199 | | static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse( |
2200 | 17.3k | CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb) { |
2201 | 17.3k | TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN; |
2202 | 17.3k | INT bitsAvailable = (INT)FDKgetValidBits(bs); |
2203 | | |
2204 | 44.9k | while (bitsAvailable >= 11) { |
2205 | 39.5k | lastAscExt = ascExtId; |
2206 | 39.5k | ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11); |
2207 | 39.5k | bitsAvailable -= 11; |
2208 | | |
2209 | 39.5k | switch (ascExtId) { |
2210 | 12.2k | case ASCEXT_SBR: /* 0x2b7 */ |
2211 | 12.2k | if ((self->m_extensionAudioObjectType != AOT_SBR) && |
2212 | 12.2k | (bitsAvailable >= 5)) { |
2213 | 11.6k | self->m_extensionAudioObjectType = getAOT(bs); |
2214 | | |
2215 | 11.6k | if ((self->m_extensionAudioObjectType == AOT_SBR) || |
2216 | 11.6k | (self->m_extensionAudioObjectType == |
2217 | 9.48k | AOT_ER_BSAC)) { /* Get SBR extension configuration */ |
2218 | 9.48k | self->m_sbrPresentFlag = FDKreadBits(bs, 1); |
2219 | 9.48k | if (self->m_aot == AOT_USAC && self->m_sbrPresentFlag > 0 && |
2220 | 9.48k | self->m_sc.m_usacConfig.m_sbrRatioIndex == 0) { |
2221 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
2222 | 0 | } |
2223 | | |
2224 | 9.48k | if (self->m_sbrPresentFlag == 1) { |
2225 | 7.93k | self->m_extensionSamplingFrequency = getSampleRate( |
2226 | 7.93k | bs, &self->m_extensionSamplingFrequencyIndex, 4); |
2227 | | |
2228 | 7.93k | if (self->m_extensionSamplingFrequency == 0 || |
2229 | 7.93k | self->m_extensionSamplingFrequency > 96000) { |
2230 | 1.01k | return TRANSPORTDEC_PARSE_ERROR; |
2231 | 1.01k | } |
2232 | 7.93k | } |
2233 | 8.46k | if (self->m_extensionAudioObjectType == AOT_ER_BSAC) { |
2234 | 1.49k | self->m_extensionChannelConfiguration = FDKreadBits(bs, 4); |
2235 | 1.49k | } |
2236 | 8.46k | } |
2237 | | /* Update counter because of variable length fields (AOT and sampling |
2238 | | * rate) */ |
2239 | 10.6k | bitsAvailable = (INT)FDKgetValidBits(bs); |
2240 | 10.6k | } |
2241 | 11.2k | break; |
2242 | 11.2k | case ASCEXT_PS: /* 0x548 */ |
2243 | 7.52k | if ((lastAscExt == ASCEXT_SBR) && |
2244 | 7.52k | (self->m_extensionAudioObjectType == AOT_SBR) && |
2245 | 7.52k | (bitsAvailable > 0)) { /* Get PS extension configuration */ |
2246 | 5.67k | self->m_psPresentFlag = FDKreadBits(bs, 1); |
2247 | 5.67k | bitsAvailable -= 1; |
2248 | 5.67k | } |
2249 | 7.52k | break; |
2250 | 917 | case ASCEXT_MPS: /* 0x76a */ |
2251 | 917 | if (self->m_extensionAudioObjectType == AOT_MPEGS) break; |
2252 | 917 | FDK_FALLTHROUGH; |
2253 | 3.62k | case ASCEXT_LDMPS: /* 0x7cc */ |
2254 | 3.62k | if ((ascExtId == ASCEXT_LDMPS) && |
2255 | 3.62k | (self->m_extensionAudioObjectType == AOT_LD_MPEGS)) |
2256 | 396 | break; |
2257 | 3.22k | if (bitsAvailable >= 1) { |
2258 | 2.91k | bitsAvailable -= 1; |
2259 | 2.91k | if (FDKreadBits(bs, 1)) { /* self->m_mpsPresentFlag */ |
2260 | 1.70k | int sscLen = FDKreadBits(bs, 8); |
2261 | 1.70k | bitsAvailable -= 8; |
2262 | 1.70k | if (sscLen == 0xFF) { |
2263 | 414 | sscLen += FDKreadBits(bs, 16); |
2264 | 414 | bitsAvailable -= 16; |
2265 | 414 | } |
2266 | 1.70k | FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next |
2267 | | extension if there is one. */ |
2268 | | |
2269 | 1.70k | bitsAvailable -= sscLen * 8; |
2270 | 1.70k | } |
2271 | 2.91k | } |
2272 | 3.22k | break; |
2273 | 4.61k | case ASCEXT_SAOC: |
2274 | 4.61k | if ((ascExtId == ASCEXT_SAOC) && |
2275 | 4.61k | (self->m_extensionAudioObjectType == AOT_SAOC)) |
2276 | 292 | break; |
2277 | 4.31k | if (FDKreadBits(bs, 1)) { /* saocPresent */ |
2278 | 2.96k | int saocscLen = FDKreadBits(bs, 8); |
2279 | 2.96k | bitsAvailable -= 8; |
2280 | 2.96k | if (saocscLen == 0xFF) { |
2281 | 612 | saocscLen += FDKreadBits(bs, 16); |
2282 | 612 | bitsAvailable -= 16; |
2283 | 612 | } |
2284 | 2.96k | FDKpushFor(bs, saocscLen); |
2285 | 2.96k | bitsAvailable -= saocscLen * 8; |
2286 | 2.96k | } |
2287 | 4.31k | break; |
2288 | 10.9k | default: |
2289 | | /* Just ignore anything. */ |
2290 | 10.9k | return TRANSPORTDEC_OK; |
2291 | 39.5k | } |
2292 | 39.5k | } |
2293 | | |
2294 | 5.39k | return TRANSPORTDEC_OK; |
2295 | 17.3k | } |
2296 | | |
2297 | | /* |
2298 | | * API Functions |
2299 | | */ |
2300 | | |
2301 | 790k | void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc) { |
2302 | 790k | FDKmemclear(asc, sizeof(CSAudioSpecificConfig)); |
2303 | | |
2304 | | /* Init all values that should not be zero. */ |
2305 | 790k | asc->m_aot = AOT_NONE; |
2306 | 790k | asc->m_samplingFrequencyIndex = 0xf; |
2307 | 790k | asc->m_epConfig = -1; |
2308 | 790k | asc->m_extensionAudioObjectType = AOT_NULL_OBJECT; |
2309 | 790k | CProgramConfig_Init(&asc->m_progrConfigElement); |
2310 | 790k | } |
2311 | | |
2312 | | TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( |
2313 | | CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, |
2314 | | int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode, |
2315 | 790k | UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot) { |
2316 | 790k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
2317 | 790k | UINT ascStartAnchor = FDKgetValidBits(bs); |
2318 | 790k | int frameLengthFlag = -1; |
2319 | | |
2320 | 790k | AudioSpecificConfig_Init(self); |
2321 | | |
2322 | 790k | self->configMode = configMode; |
2323 | 790k | self->AacConfigChanged = configChanged; |
2324 | 790k | self->SbrConfigChanged = configChanged; |
2325 | 790k | self->SacConfigChanged = configChanged; |
2326 | | |
2327 | 790k | if (m_aot != AOT_NULL_OBJECT) { |
2328 | 52 | self->m_aot = m_aot; |
2329 | 790k | } else { |
2330 | 790k | self->m_aot = getAOT(bs); |
2331 | 790k | self->m_samplingFrequency = |
2332 | 790k | getSampleRate(bs, &self->m_samplingFrequencyIndex, 4); |
2333 | 790k | if (self->m_samplingFrequency <= 0 || |
2334 | 790k | (self->m_samplingFrequency > 96000 && self->m_aot != 39) || |
2335 | 790k | self->m_samplingFrequency > 4 * 96000) { |
2336 | 13.5k | return TRANSPORTDEC_PARSE_ERROR; |
2337 | 13.5k | } |
2338 | | |
2339 | 777k | 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 | 777k | if ((self->m_channelConfiguration == 0) && |
2347 | 777k | ((self->m_aot == AOT_ER_AAC_LC) || (self->m_aot == AOT_ER_AAC_LTP) || |
2348 | 186k | (self->m_aot == AOT_ER_AAC_LD) || (self->m_aot == AOT_ER_AAC_SCAL) || |
2349 | 186k | (self->m_aot == AOT_ER_AAC_ELD))) { |
2350 | 113k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
2351 | 113k | } |
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 | 664k | if ((self->m_channelConfiguration > 2) && |
2355 | 664k | ((self->m_aot == AOT_AAC_SCAL) || (self->m_aot == AOT_ER_AAC_SCAL))) { |
2356 | 8.47k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
2357 | 8.47k | } |
2358 | | |
2359 | | /* SBR extension ( explicit non-backwards compatible mode ) */ |
2360 | 655k | self->m_sbrPresentFlag = 0; |
2361 | 655k | self->m_psPresentFlag = 0; |
2362 | | |
2363 | 655k | if (self->m_aot == AOT_SBR || self->m_aot == AOT_PS) { |
2364 | 18.4k | self->m_extensionAudioObjectType = AOT_SBR; |
2365 | | |
2366 | 18.4k | self->m_sbrPresentFlag = 1; |
2367 | 18.4k | if (self->m_aot == AOT_PS) { |
2368 | 16.0k | self->m_psPresentFlag = 1; |
2369 | 16.0k | } |
2370 | | |
2371 | 18.4k | self->m_extensionSamplingFrequency = |
2372 | 18.4k | getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4); |
2373 | 18.4k | if (self->m_extensionSamplingFrequency == 0 || |
2374 | 18.4k | self->m_extensionSamplingFrequency > 96000) { |
2375 | 2.12k | return TRANSPORTDEC_PARSE_ERROR; |
2376 | 2.12k | } |
2377 | 16.3k | self->m_aot = getAOT(bs); |
2378 | | |
2379 | 16.3k | switch (self->m_aot) { |
2380 | 13.7k | case AOT_AAC_LC: |
2381 | 13.7k | break; |
2382 | 904 | case AOT_ER_BSAC: |
2383 | 904 | break; |
2384 | 1.72k | default: |
2385 | 1.72k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
2386 | 16.3k | } |
2387 | | |
2388 | 14.6k | if (self->m_aot == AOT_ER_BSAC) { |
2389 | 904 | self->m_extensionChannelConfiguration = FDKreadBits(bs, 4); |
2390 | 904 | } |
2391 | 637k | } else { |
2392 | 637k | self->m_extensionAudioObjectType = AOT_NULL_OBJECT; |
2393 | 637k | } |
2394 | 655k | } |
2395 | | |
2396 | | /* Parse whatever specific configs */ |
2397 | 651k | switch (self->m_aot) { |
2398 | 60.6k | case AOT_AAC_LC: |
2399 | 61.2k | case AOT_AAC_SCAL: |
2400 | 72.5k | case AOT_ER_AAC_LC: |
2401 | 83.0k | case AOT_ER_AAC_LD: |
2402 | 132k | case AOT_ER_AAC_SCAL: |
2403 | 134k | case AOT_ER_BSAC: |
2404 | 134k | if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig, |
2405 | 134k | self, bs, ascStartAnchor)) != |
2406 | 134k | TRANSPORTDEC_OK) { |
2407 | 0 | return (ErrorStatus); |
2408 | 0 | } |
2409 | 134k | frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag; |
2410 | 134k | break; |
2411 | 713 | case AOT_MPEGS: |
2412 | 713 | if (cb->cbSsc != NULL) { |
2413 | 713 | if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency, |
2414 | 713 | self->m_samplesPerFrame, self->m_channelConfiguration, 1, |
2415 | 713 | -1, /* nTimeSlots: read from bitstream */ |
2416 | 713 | 0, /* don't know the length */ |
2417 | 713 | self->configMode, &self->SacConfigChanged)) { |
2418 | 713 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
2419 | 713 | } |
2420 | 713 | } else { |
2421 | 0 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
2422 | 0 | } |
2423 | 0 | break; |
2424 | 176k | case AOT_ER_AAC_ELD: |
2425 | 176k | if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) != |
2426 | 176k | TRANSPORTDEC_OK) { |
2427 | 39.2k | return (ErrorStatus); |
2428 | 39.2k | } |
2429 | 136k | frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag; |
2430 | 136k | self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag; |
2431 | 136k | self->m_extensionSamplingFrequency = |
2432 | 136k | (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate + 1) * |
2433 | 136k | self->m_samplingFrequency; |
2434 | 136k | break; |
2435 | 294k | case AOT_USAC: |
2436 | 294k | if ((ErrorStatus = UsacConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK) { |
2437 | 82.1k | return (ErrorStatus); |
2438 | 82.1k | } |
2439 | 211k | break; |
2440 | | |
2441 | 211k | default: |
2442 | 46.8k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
2443 | 651k | } |
2444 | | |
2445 | | /* Frame length */ |
2446 | 482k | switch (self->m_aot) { |
2447 | 60.6k | case AOT_AAC_LC: |
2448 | 61.2k | case AOT_AAC_SCAL: |
2449 | 72.5k | case AOT_ER_AAC_LC: |
2450 | 121k | case AOT_ER_AAC_SCAL: |
2451 | 123k | case AOT_ER_BSAC: |
2452 | | /*case AOT_USAC:*/ |
2453 | 123k | if (!frameLengthFlag) |
2454 | 55.3k | self->m_samplesPerFrame = 1024; |
2455 | 68.4k | else |
2456 | 68.4k | self->m_samplesPerFrame = 960; |
2457 | 123k | break; |
2458 | 10.4k | case AOT_ER_AAC_LD: |
2459 | 10.4k | if (!frameLengthFlag) |
2460 | 4.06k | self->m_samplesPerFrame = 512; |
2461 | 6.39k | else |
2462 | 6.39k | self->m_samplesPerFrame = 480; |
2463 | 10.4k | break; |
2464 | 348k | default: |
2465 | 348k | break; |
2466 | 482k | } |
2467 | | |
2468 | 482k | switch (self->m_aot) { |
2469 | 11.3k | case AOT_ER_AAC_LC: |
2470 | 21.7k | case AOT_ER_AAC_LD: |
2471 | 158k | case AOT_ER_AAC_ELD: |
2472 | 207k | case AOT_ER_AAC_SCAL: |
2473 | 207k | case AOT_ER_CELP: |
2474 | 207k | case AOT_ER_HVXC: |
2475 | 209k | case AOT_ER_BSAC: |
2476 | 209k | self->m_epConfig = FDKreadBits(bs, 2); |
2477 | | |
2478 | 209k | if (self->m_epConfig > 1) { |
2479 | 1.98k | return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG; |
2480 | 1.98k | } |
2481 | 207k | break; |
2482 | 273k | default: |
2483 | 273k | break; |
2484 | 482k | } |
2485 | | |
2486 | 480k | if (fExplicitBackwardCompatible && |
2487 | 480k | (self->m_aot == AOT_AAC_LC || self->m_aot == AOT_ER_AAC_LD || |
2488 | 29.2k | self->m_aot == AOT_ER_BSAC)) { |
2489 | 17.3k | ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb); |
2490 | 17.3k | } |
2491 | | |
2492 | | /* Copy config() to asc->config[] buffer. */ |
2493 | 480k | if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) { |
2494 | 211k | INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor; |
2495 | 211k | if (StoreConfigAsBitstream(bs, configSize_bits, self->config, |
2496 | 211k | TP_USAC_MAX_CONFIG_LEN)) { |
2497 | 353 | return TRANSPORTDEC_PARSE_ERROR; |
2498 | 353 | } |
2499 | 211k | self->configBits = fAbs(configSize_bits); |
2500 | 211k | } |
2501 | | |
2502 | 480k | return (ErrorStatus); |
2503 | 480k | } |
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 | } |