/src/aac/libMpegTPDec/src/tpdec_latm.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /******************* MPEG transport format decoder library ********************* |
96 | | |
97 | | Author(s): Daniel Homm |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "tpdec_latm.h" |
104 | | |
105 | | #include "FDK_bitstream.h" |
106 | | |
107 | 4.91M | #define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l)) |
108 | | |
109 | 39.6k | static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) { |
110 | 39.6k | UCHAR bytesForValue = 0, tmp = 0; |
111 | 39.6k | int value = 0; |
112 | | |
113 | 39.6k | bytesForValue = (UCHAR)FDKreadBits(bs, 2); |
114 | | |
115 | 122k | for (UINT i = 0; i <= bytesForValue; i++) { |
116 | 82.8k | value <<= 8; |
117 | 82.8k | tmp = (UCHAR)FDKreadBits(bs, 8); |
118 | 82.8k | value += tmp; |
119 | 82.8k | } |
120 | | |
121 | 39.6k | return value; |
122 | 39.6k | } |
123 | | |
124 | | static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( |
125 | | HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent, |
126 | | CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, |
127 | 519k | int *pfConfigFound) { |
128 | 519k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
129 | | |
130 | 519k | if (m_muxConfigPresent) { |
131 | 519k | pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1); |
132 | | |
133 | 519k | if (!pLatmDemux->m_useSameStreamMux) { |
134 | 499k | int i; |
135 | 499k | UCHAR configChanged = 0; |
136 | 499k | UCHAR configMode = 0; |
137 | | |
138 | 499k | FDK_BITSTREAM bsAnchor; |
139 | | |
140 | 499k | FDK_BITSTREAM bsAnchorDummyParse; |
141 | | |
142 | 499k | if (!pLatmDemux->applyAsc) { |
143 | 124k | bsAnchorDummyParse = *bs; |
144 | 124k | pLatmDemux->newCfgHasAudioPreRoll = 0; |
145 | | /* do dummy-parsing of ASC to determine if there is an audioPreRoll */ |
146 | 124k | configMode |= AC_CM_DET_CFG_CHANGE; |
147 | 124k | if (TRANSPORTDEC_OK != |
148 | 124k | (ErrorStatus = CLatmDemux_ReadStreamMuxConfig( |
149 | 124k | bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound, |
150 | 124k | configMode, configChanged))) { |
151 | 4.38k | goto bail; |
152 | 4.38k | } |
153 | | |
154 | | /* Allow flushing only when audioPreroll functionality is enabled in |
155 | | * current and new config otherwise the new config can be applied |
156 | | * immediately. */ |
157 | 120k | if (pAsc->m_sc.m_usacConfig.element[0] |
158 | 120k | .extElement.usacExtElementHasAudioPreRoll && |
159 | 120k | pLatmDemux->newCfgHasAudioPreRoll) { |
160 | 231 | pLatmDemux->newCfgHasAudioPreRoll = 0; |
161 | | /* with audioPreRoll we must flush before applying new cfg */ |
162 | 231 | pLatmDemux->applyAsc = 0; |
163 | 120k | } else { |
164 | 120k | *bs = bsAnchorDummyParse; |
165 | 120k | pLatmDemux->applyAsc = 1; /* apply new config immediate */ |
166 | 120k | } |
167 | 120k | } |
168 | | |
169 | 494k | if (pLatmDemux->applyAsc) { |
170 | 1.14M | for (i = 0; i < 2; i++) { |
171 | 823k | configMode = 0; |
172 | | |
173 | 823k | if (i == 0) { |
174 | 494k | configMode |= AC_CM_DET_CFG_CHANGE; |
175 | 494k | bsAnchor = *bs; |
176 | 494k | } else { |
177 | 328k | configMode |= AC_CM_ALLOC_MEM; |
178 | 328k | *bs = bsAnchor; |
179 | 328k | } |
180 | | |
181 | 823k | if (TRANSPORTDEC_OK != |
182 | 823k | (ErrorStatus = CLatmDemux_ReadStreamMuxConfig( |
183 | 823k | bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound, |
184 | 823k | configMode, configChanged))) { |
185 | 173k | goto bail; |
186 | 173k | } |
187 | | |
188 | 649k | if (ErrorStatus == TRANSPORTDEC_OK) { |
189 | 649k | if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged || |
190 | 328k | pAsc->SacConfigChanged)) { |
191 | 229k | int errC; |
192 | | |
193 | 229k | configChanged = 1; |
194 | 229k | errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData, |
195 | 229k | pAsc); |
196 | 229k | if (errC != 0) { |
197 | 0 | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
198 | 0 | goto bail; |
199 | 0 | } |
200 | 229k | } |
201 | 649k | } |
202 | 649k | } |
203 | 494k | } |
204 | 494k | } |
205 | 519k | } |
206 | | |
207 | | /* If there was no configuration read, its not possible to parse |
208 | | * PayloadLengthInfo below. */ |
209 | 341k | if (!*pfConfigFound) { |
210 | 15.7k | ErrorStatus = TRANSPORTDEC_SYNC_ERROR; |
211 | 15.7k | goto bail; |
212 | 15.7k | } |
213 | | |
214 | 325k | if (pLatmDemux->m_AudioMuxVersionA == 0) { |
215 | | /* Do only once per call, because parsing and decoding is done in-line. */ |
216 | 325k | if (TRANSPORTDEC_OK != |
217 | 325k | (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) { |
218 | 179k | *pfConfigFound = 0; |
219 | 179k | goto bail; |
220 | 179k | } |
221 | 325k | } else { |
222 | | /* audioMuxVersionA > 0 is reserved for future extensions */ |
223 | 0 | ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; |
224 | 0 | *pfConfigFound = 0; |
225 | 0 | goto bail; |
226 | 0 | } |
227 | | |
228 | 519k | bail: |
229 | 519k | if (ErrorStatus != TRANSPORTDEC_OK) { |
230 | 373k | pLatmDemux->applyAsc = 1; |
231 | 373k | } |
232 | | |
233 | 519k | return (ErrorStatus); |
234 | 325k | } |
235 | | |
236 | | TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs, |
237 | | CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt, |
238 | | CSTpCallBacks *pTpDecCallbacks, |
239 | | CSAudioSpecificConfig *pAsc, |
240 | | int *pfConfigFound, |
241 | 519k | const INT ignoreBufferFullness) { |
242 | 519k | UINT cntBits; |
243 | 519k | UINT cmpBufferFullness; |
244 | 519k | UINT audioMuxLengthBytesLast = 0; |
245 | 519k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
246 | | |
247 | 519k | cntBits = FDKgetValidBits(bs); |
248 | | |
249 | 519k | if ((INT)cntBits < MIN_LATM_HEADERLENGTH) { |
250 | 207 | return TRANSPORTDEC_NOT_ENOUGH_BITS; |
251 | 207 | } |
252 | | |
253 | 519k | if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement( |
254 | 519k | bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0), |
255 | 519k | pTpDecCallbacks, pAsc, pfConfigFound))) |
256 | 373k | return (ErrorStatus); |
257 | | |
258 | 145k | if (!ignoreBufferFullness) { |
259 | 47.0k | cmpBufferFullness = |
260 | 47.0k | 24 + audioMuxLengthBytesLast * 8 + |
261 | 47.0k | pLatmDemux->m_linfo[0][0].m_bufferFullness * |
262 | 47.0k | pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32; |
263 | | |
264 | | /* evaluate buffer fullness */ |
265 | | |
266 | 47.0k | if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) { |
267 | 46.5k | if (!pLatmDemux->BufferFullnessAchieved) { |
268 | 32.9k | if (cntBits < cmpBufferFullness) { |
269 | | /* condition for start of decoding is not fulfilled */ |
270 | | |
271 | | /* the current frame will not be decoded */ |
272 | 110 | return TRANSPORTDEC_NOT_ENOUGH_BITS; |
273 | 32.8k | } else { |
274 | 32.8k | pLatmDemux->BufferFullnessAchieved = 1; |
275 | 32.8k | } |
276 | 32.9k | } |
277 | 46.5k | } |
278 | 47.0k | } |
279 | | |
280 | 145k | return (ErrorStatus); |
281 | 145k | } |
282 | | |
283 | | TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig( |
284 | | HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, |
285 | | CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, |
286 | 948k | int *pfConfigFound, UCHAR configMode, UCHAR configChanged) { |
287 | 948k | CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing, |
288 | | after that new config can be parsed */ |
289 | 948k | CSAudioSpecificConfig *pAscDummy; |
290 | 948k | pAscDummy = &ascDummy; |
291 | 948k | pLatmDemux->usacExplicitCfgChanged = 0; |
292 | 948k | LATM_LAYER_INFO *p_linfo = NULL; |
293 | 948k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
294 | 948k | UCHAR updateConfig[1 * 1] = {0}; |
295 | | |
296 | 948k | pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1); |
297 | | |
298 | 948k | if (pLatmDemux->m_AudioMuxVersion == 0) { |
299 | 921k | pLatmDemux->m_AudioMuxVersionA = 0; |
300 | 921k | } else { |
301 | 26.5k | pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1); |
302 | 26.5k | } |
303 | | |
304 | 948k | if (pLatmDemux->m_AudioMuxVersionA == 0) { |
305 | 947k | if (pLatmDemux->m_AudioMuxVersion == 1) { |
306 | 25.8k | pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs); |
307 | 25.8k | } |
308 | 947k | pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1); |
309 | 947k | pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1; |
310 | 947k | pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1; |
311 | | |
312 | 947k | if (pLatmDemux->m_numProgram > LATM_MAX_PROG) { |
313 | 21.5k | ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; |
314 | 21.5k | goto bail; |
315 | 21.5k | } |
316 | | |
317 | 925k | int idCnt = 0; |
318 | 1.71M | for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) { |
319 | 925k | pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1; |
320 | 925k | if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) { |
321 | 10.4k | ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; |
322 | 10.4k | goto bail; |
323 | 10.4k | } |
324 | | |
325 | 1.70M | for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { |
326 | 915k | int useSameConfig; |
327 | 915k | p_linfo = &pLatmDemux->m_linfo[prog][lay]; |
328 | | |
329 | 915k | p_linfo->m_streamID = idCnt++; |
330 | 915k | p_linfo->m_frameLengthInBits = 0; |
331 | | |
332 | 915k | if ((prog == 0) && (lay == 0)) { |
333 | 915k | useSameConfig = 0; |
334 | 915k | } else { |
335 | 0 | useSameConfig = FDKreadBits(bs, 1); |
336 | 0 | } |
337 | | |
338 | 915k | if (useSameConfig) { |
339 | 0 | if (lay > 0) { |
340 | 0 | FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)], |
341 | 0 | &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)], |
342 | 0 | sizeof(CSAudioSpecificConfig)); |
343 | 0 | } else { |
344 | 0 | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
345 | 0 | goto bail; |
346 | 0 | } |
347 | 915k | } else { |
348 | 915k | UINT usacConfigLengthPrev = 0; |
349 | 915k | UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN]; |
350 | | |
351 | 915k | if (!(pLatmDemux->applyAsc) && |
352 | 915k | (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) { |
353 | 44.7k | usacConfigLengthPrev = |
354 | 44.7k | (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)] |
355 | 44.7k | .m_sc.m_usacConfig.UsacConfigBits + |
356 | 44.7k | 7) >> |
357 | 44.7k | 3; /* store previous USAC config length */ |
358 | 44.7k | if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) { |
359 | 0 | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
360 | 0 | goto bail; |
361 | 0 | } |
362 | 44.7k | FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN); |
363 | 44.7k | FDKmemcpy( |
364 | 44.7k | usacConfigPrev, |
365 | 44.7k | &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig, |
366 | 44.7k | usacConfigLengthPrev); /* store previous USAC config */ |
367 | 44.7k | } |
368 | 915k | if (pLatmDemux->m_AudioMuxVersion == 1) { |
369 | 12.3k | FDK_BITSTREAM tmpBs; |
370 | 12.3k | INT ascLen = 0; |
371 | 12.3k | ascLen = CLatmDemux_GetValue(bs); |
372 | | /* The ascLen could be wrong, so check if validBits<=bufBits*/ |
373 | 12.3k | if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) { |
374 | 1.37k | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
375 | 1.37k | goto bail; |
376 | 1.37k | } |
377 | 11.0k | FDKsyncCache(bs); |
378 | 11.0k | tmpBs = *bs; |
379 | 11.0k | tmpBs.hBitBuf.ValidBits = ascLen; |
380 | | |
381 | | /* Read ASC */ |
382 | 11.0k | if (pLatmDemux->applyAsc) { |
383 | 10.5k | if (TRANSPORTDEC_OK != |
384 | 10.5k | (ErrorStatus = AudioSpecificConfig_Parse( |
385 | 10.5k | &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1, |
386 | 10.5k | pTpDecCallbacks, configMode, configChanged, |
387 | 10.5k | AOT_NULL_OBJECT))) |
388 | 2.92k | goto bail; |
389 | 10.5k | } else { |
390 | 434 | if (TRANSPORTDEC_OK != |
391 | 434 | (ErrorStatus = AudioSpecificConfig_Parse( |
392 | 434 | pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode, |
393 | 434 | configChanged, AOT_NULL_OBJECT))) |
394 | 216 | goto bail; |
395 | 434 | } |
396 | | |
397 | | /* The field p_linfo->m_ascLen could be wrong, so check if */ |
398 | 7.86k | if (0 > (INT)FDKgetValidBits(&tmpBs)) { |
399 | 2.64k | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
400 | 2.64k | goto bail; |
401 | 2.64k | } |
402 | 5.22k | FDKpushFor(bs, ascLen); /* position bitstream after ASC */ |
403 | 902k | } else { |
404 | | /* Read ASC */ |
405 | 902k | if (pLatmDemux->applyAsc) { |
406 | 779k | if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse( |
407 | 779k | &pAsc[TPDEC_TRACKINDEX(prog, lay)], |
408 | 779k | bs, 0, pTpDecCallbacks, configMode, |
409 | 779k | configChanged, AOT_NULL_OBJECT))) |
410 | 101k | goto bail; |
411 | 779k | } else { |
412 | 123k | if (TRANSPORTDEC_OK != |
413 | 123k | (ErrorStatus = AudioSpecificConfig_Parse( |
414 | 123k | pAscDummy, bs, 0, pTpDecCallbacks, configMode, |
415 | 123k | configChanged, AOT_NULL_OBJECT))) |
416 | 2.98k | goto bail; |
417 | 123k | } |
418 | 902k | } |
419 | 803k | if (!pLatmDemux->applyAsc) { |
420 | 120k | updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0; |
421 | 682k | } else { |
422 | 682k | updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1; |
423 | 682k | } |
424 | | |
425 | 803k | if (!pLatmDemux->applyAsc) { |
426 | 120k | if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot == |
427 | 120k | AOT_USAC) { /* flush in case SMC has changed */ |
428 | 43.8k | const UINT usacConfigLength = |
429 | 43.8k | (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3; |
430 | 43.8k | if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) { |
431 | 0 | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
432 | 0 | goto bail; |
433 | 0 | } |
434 | 43.8k | if (usacConfigLength != usacConfigLengthPrev) { |
435 | 1.67k | FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)] |
436 | 1.67k | .m_sc.m_usacConfig.UsacConfig, |
437 | 1.67k | TP_USAC_MAX_CONFIG_LEN); |
438 | 1.67k | FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)] |
439 | 1.67k | .m_sc.m_usacConfig.UsacConfig, |
440 | 1.67k | &pAscDummy->m_sc.m_usacConfig.UsacConfig, |
441 | 1.67k | usacConfigLength); /* store new USAC config */ |
442 | 1.67k | pAsc[TPDEC_TRACKINDEX(prog, lay)] |
443 | 1.67k | .m_sc.m_usacConfig.UsacConfigBits = |
444 | 1.67k | pAscDummy->m_sc.m_usacConfig.UsacConfigBits; |
445 | 1.67k | pLatmDemux->usacExplicitCfgChanged = 1; |
446 | 42.1k | } else { |
447 | 42.1k | if (FDKmemcmp(usacConfigPrev, |
448 | 42.1k | pAscDummy->m_sc.m_usacConfig.UsacConfig, |
449 | 42.1k | usacConfigLengthPrev)) { |
450 | 22.5k | FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)] |
451 | 22.5k | .m_sc.m_usacConfig.UsacConfig, |
452 | 22.5k | TP_USAC_MAX_CONFIG_LEN); |
453 | 22.5k | FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)] |
454 | 22.5k | .m_sc.m_usacConfig.UsacConfig, |
455 | 22.5k | &pAscDummy->m_sc.m_usacConfig.UsacConfig, |
456 | 22.5k | usacConfigLength); /* store new USAC config */ |
457 | 22.5k | pAsc[TPDEC_TRACKINDEX(prog, lay)] |
458 | 22.5k | .m_sc.m_usacConfig.UsacConfigBits = |
459 | 22.5k | pAscDummy->m_sc.m_usacConfig.UsacConfigBits; |
460 | 22.5k | pLatmDemux->usacExplicitCfgChanged = 1; |
461 | 22.5k | } |
462 | 42.1k | } |
463 | | |
464 | 43.8k | if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)] |
465 | 43.8k | .m_sc.m_usacConfig.m_usacNumElements) { |
466 | 43.8k | if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)] |
467 | 43.8k | .m_sc.m_usacConfig.element[0] |
468 | 43.8k | .extElement.usacExtElementHasAudioPreRoll) { |
469 | 822 | pLatmDemux->newCfgHasAudioPreRoll = |
470 | 822 | 1; /* if dummy parsed cfg has audioPreRoll we first flush |
471 | | before applying new cfg */ |
472 | 822 | } |
473 | 43.8k | } |
474 | 43.8k | } |
475 | 120k | } |
476 | 803k | } |
477 | | |
478 | 803k | p_linfo->m_frameLengthType = FDKreadBits(bs, 3); |
479 | 803k | switch (p_linfo->m_frameLengthType) { |
480 | 770k | case 0: |
481 | 770k | p_linfo->m_bufferFullness = FDKreadBits(bs, 8); |
482 | | |
483 | 770k | if (!pLatmDemux->m_allStreamsSameTimeFraming) { |
484 | 236k | if ((lay > 0) && |
485 | 236k | (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL || |
486 | 0 | pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == |
487 | 0 | AOT_ER_AAC_SCAL) && |
488 | 236k | (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP || |
489 | 0 | pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == |
490 | 0 | AOT_ER_CELP)) { /* The layer maybe |
491 | | ignored later so |
492 | | read it anyway: */ |
493 | 0 | /* coreFrameOffset = */ FDKreadBits(bs, 6); |
494 | 0 | } |
495 | 236k | } |
496 | 770k | break; |
497 | 23.3k | case 1: |
498 | 23.3k | p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9); |
499 | 23.3k | break; |
500 | 1.60k | case 3: |
501 | 3.47k | case 4: |
502 | 4.40k | case 5: |
503 | | /* CELP */ |
504 | 5.85k | case 6: |
505 | 7.49k | case 7: |
506 | | /* HVXC */ |
507 | 9.58k | default: |
508 | 9.58k | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
509 | 9.58k | goto bail; |
510 | 803k | } /* switch framelengthtype*/ |
511 | | |
512 | 803k | } /* layer loop */ |
513 | 915k | } /* prog loop */ |
514 | | |
515 | 794k | pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1); |
516 | 794k | pLatmDemux->m_otherDataLength = 0; |
517 | | |
518 | 794k | if (pLatmDemux->m_otherDataPresent) { |
519 | 258k | if (pLatmDemux->m_AudioMuxVersion == 1) { |
520 | 1.35k | pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs); |
521 | 257k | } else { |
522 | 257k | int otherDataLenEsc = 0; |
523 | 449k | do { |
524 | 449k | pLatmDemux->m_otherDataLength <<= 8; // *= 256 |
525 | 449k | otherDataLenEsc = FDKreadBits(bs, 1); |
526 | 449k | pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8); |
527 | 449k | } while (otherDataLenEsc); |
528 | 257k | } |
529 | 258k | if (pLatmDemux->m_audioMuxLengthBytes < |
530 | 258k | (pLatmDemux->m_otherDataLength >> 3)) { |
531 | 8.19k | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; |
532 | 8.19k | goto bail; |
533 | 8.19k | } |
534 | 258k | } |
535 | | |
536 | 786k | pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1); |
537 | | |
538 | 786k | if (pLatmDemux->m_crcCheckPresent) { |
539 | 372k | FDKreadBits(bs, 8); |
540 | 372k | } |
541 | | |
542 | 786k | } else { |
543 | | /* audioMuxVersionA > 0 is reserved for future extensions */ |
544 | 646 | ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; |
545 | 646 | } |
546 | | |
547 | | /* Configure source decoder: */ |
548 | 786k | if (ErrorStatus == TRANSPORTDEC_OK) { |
549 | 786k | UINT prog; |
550 | 1.55M | for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) { |
551 | 786k | UINT lay; |
552 | 1.55M | for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { |
553 | 786k | if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) { |
554 | 665k | int cbError; |
555 | 665k | cbError = pTpDecCallbacks->cbUpdateConfig( |
556 | 665k | pTpDecCallbacks->cbUpdateConfigData, |
557 | 665k | &pAsc[TPDEC_TRACKINDEX(prog, lay)], |
558 | 665k | pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode, |
559 | 665k | &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged); |
560 | 665k | if (cbError == TRANSPORTDEC_NEED_TO_RESTART) { |
561 | 0 | *pfConfigFound = 0; |
562 | 0 | ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART; |
563 | 0 | goto bail; |
564 | 0 | } |
565 | 665k | if (cbError != 0) { |
566 | 16.1k | *pfConfigFound = 0; |
567 | 16.1k | if (lay == 0) { |
568 | 16.1k | ErrorStatus = TRANSPORTDEC_SYNC_ERROR; |
569 | 16.1k | goto bail; |
570 | 16.1k | } |
571 | 649k | } else { |
572 | 649k | *pfConfigFound = 1; |
573 | 649k | } |
574 | 665k | } else { |
575 | 120k | *pfConfigFound = 1; |
576 | 120k | } |
577 | 786k | } |
578 | 786k | } |
579 | 786k | } |
580 | | |
581 | 948k | bail: |
582 | 948k | if (ErrorStatus != TRANSPORTDEC_OK) { |
583 | 178k | UCHAR applyAsc = pLatmDemux->applyAsc; |
584 | 178k | FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */ |
585 | 178k | pLatmDemux->applyAsc = applyAsc; |
586 | 769k | } else { |
587 | | /* no error and config parsing is finished */ |
588 | 769k | if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0; |
589 | 769k | } |
590 | | |
591 | 948k | return (ErrorStatus); |
592 | 786k | } |
593 | | |
594 | 523k | static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { |
595 | 523k | int len = 0, tmp = 255; |
596 | 523k | int validBytes = (int)FDKgetValidBits(bs) >> 3; |
597 | | |
598 | 1.11M | while (tmp == 255 && validBytes-- > 0) { |
599 | 588k | tmp = (int)FDKreadBits(bs, 8); |
600 | 588k | len += tmp; |
601 | 588k | } |
602 | | |
603 | 523k | return ((tmp == 255) ? -1 : (len << 3)); |
604 | 523k | } |
605 | | |
606 | | TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, |
607 | 636k | CLatmDemux *pLatmDemux) { |
608 | 636k | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
609 | 636k | int totalPayloadBits = 0; |
610 | | |
611 | 636k | if (pLatmDemux->m_allStreamsSameTimeFraming == 1) { |
612 | 530k | FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG); |
613 | 1.05M | for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) { |
614 | 530k | FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER); |
615 | 1.05M | for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { |
616 | 530k | LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay]; |
617 | 530k | int auChunkLengthInfo = 0; |
618 | | |
619 | 530k | switch (p_linfo->m_frameLengthType) { |
620 | 523k | case 0: |
621 | 523k | auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs); |
622 | 523k | if (auChunkLengthInfo >= 0) { |
623 | 521k | p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo; |
624 | 521k | totalPayloadBits += p_linfo->m_frameLengthInBits; |
625 | 521k | } else { |
626 | 2.60k | return TRANSPORTDEC_PARSE_ERROR; |
627 | 2.60k | } |
628 | 521k | break; |
629 | 521k | case 3: |
630 | 0 | case 5: |
631 | 0 | case 7: |
632 | 6.46k | default: |
633 | 6.46k | return TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE; |
634 | 530k | } |
635 | 530k | } |
636 | 530k | } |
637 | 530k | } else { |
638 | 106k | ErrorStatus = TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_TIMEFRAMING; |
639 | 106k | } |
640 | 627k | if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 && |
641 | 627k | totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) { |
642 | 68.0k | return TRANSPORTDEC_PARSE_ERROR; |
643 | 68.0k | } |
644 | | |
645 | 559k | return (ErrorStatus); |
646 | 627k | } |
647 | | |
648 | | UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog, |
649 | 425k | const UINT layer) { |
650 | 425k | UINT nFrameLenBits = 0; |
651 | 425k | if (prog < pLatmDemux->m_numProgram) { |
652 | 425k | if (layer < pLatmDemux->m_numLayer[prog]) { |
653 | 425k | nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits; |
654 | 425k | } |
655 | 425k | } |
656 | 425k | return nFrameLenBits; |
657 | 425k | } |
658 | | |
659 | 11.6k | UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) { |
660 | 11.6k | return pLatmDemux->m_otherDataPresent ? 1 : 0; |
661 | 11.6k | } |
662 | | |
663 | 5.11k | UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) { |
664 | 5.11k | return pLatmDemux->m_otherDataLength; |
665 | 5.11k | } |
666 | | |
667 | 145k | UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) { |
668 | 145k | return pLatmDemux->m_noSubFrames; |
669 | 145k | } |
670 | | |
671 | 851k | UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) { |
672 | 851k | UINT numLayer = 0; |
673 | 851k | if (prog < pLatmDemux->m_numProgram) { |
674 | 851k | numLayer = pLatmDemux->m_numLayer[prog]; |
675 | 851k | } |
676 | 851k | return numLayer; |
677 | 851k | } |