/src/aac/libMpegTPDec/src/tpdec_adts.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): Josef Hoepfl |
98 | | |
99 | | Description: ADTS interface |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "tpdec_adts.h" |
104 | | |
105 | | #include "FDK_bitstream.h" |
106 | | |
107 | | void adtsRead_CrcInit( |
108 | | HANDLE_ADTS pAdts) /*!< pointer to adts crc info stucture */ |
109 | 0 | { |
110 | 0 | FDKcrcInit(&pAdts->crcInfo, 0x8005, 0xFFFF, 16); |
111 | 0 | } |
112 | | |
113 | | int adtsRead_CrcStartReg( |
114 | | HANDLE_ADTS pAdts, /*!< pointer to adts stucture */ |
115 | | HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */ |
116 | | int mBits /*!< number of bits in crc region */ |
117 | 0 | ) { |
118 | 0 | if (pAdts->bs.protection_absent) { |
119 | 0 | return 0; |
120 | 0 | } |
121 | | |
122 | 0 | return (FDKcrcStartReg(&pAdts->crcInfo, hBs, mBits)); |
123 | 0 | } |
124 | | |
125 | | void adtsRead_CrcEndReg( |
126 | | HANDLE_ADTS pAdts, /*!< pointer to adts crc info stucture */ |
127 | | HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */ |
128 | | int reg /*!< crc region */ |
129 | 0 | ) { |
130 | 0 | if (pAdts->bs.protection_absent == 0) { |
131 | 0 | FDKcrcEndReg(&pAdts->crcInfo, hBs, reg); |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | 0 | TRANSPORTDEC_ERROR adtsRead_CrcCheck(HANDLE_ADTS pAdts) { |
136 | 0 | TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; |
137 | 0 | USHORT crc; |
138 | |
|
139 | 0 | if (pAdts->bs.protection_absent) return TRANSPORTDEC_OK; |
140 | | |
141 | 0 | crc = FDKcrcGetCRC(&pAdts->crcInfo); |
142 | 0 | if (crc != pAdts->crcReadValue) { |
143 | 0 | return (TRANSPORTDEC_CRC_ERROR); |
144 | 0 | } |
145 | | |
146 | 0 | return (ErrorStatus); |
147 | 0 | } |
148 | | |
149 | | #define Adts_Length_SyncWord 12 |
150 | 0 | #define Adts_Length_Id 1 |
151 | 0 | #define Adts_Length_Layer 2 |
152 | 0 | #define Adts_Length_ProtectionAbsent 1 |
153 | 0 | #define Adts_Length_Profile 2 |
154 | 0 | #define Adts_Length_SamplingFrequencyIndex 4 |
155 | 0 | #define Adts_Length_PrivateBit 1 |
156 | 0 | #define Adts_Length_ChannelConfiguration 3 |
157 | 0 | #define Adts_Length_OriginalCopy 1 |
158 | 0 | #define Adts_Length_Home 1 |
159 | 0 | #define Adts_Length_CopyrightIdentificationBit 1 |
160 | 0 | #define Adts_Length_CopyrightIdentificationStart 1 |
161 | 0 | #define Adts_Length_FrameLength 13 |
162 | 0 | #define Adts_Length_BufferFullness 11 |
163 | 0 | #define Adts_Length_NumberOfRawDataBlocksInFrame 2 |
164 | 0 | #define Adts_Length_CrcCheck 16 |
165 | | |
166 | | TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts, |
167 | | CSAudioSpecificConfig *pAsc, |
168 | | HANDLE_FDK_BITSTREAM hBs, |
169 | 0 | const INT ignoreBufferFullness) { |
170 | 0 | INT crcReg; |
171 | |
|
172 | 0 | INT valBits; |
173 | 0 | INT cmp_buffer_fullness; |
174 | 0 | int i, adtsHeaderLength; |
175 | |
|
176 | 0 | STRUCT_ADTS_BS bs; |
177 | |
|
178 | 0 | CProgramConfig oldPce; |
179 | | /* Store the old PCE temporarily. Maybe we'll need it later if we |
180 | | have channelConfig=0 and no PCE in this frame. */ |
181 | 0 | FDKmemcpy(&oldPce, &pAsc->m_progrConfigElement, sizeof(CProgramConfig)); |
182 | |
|
183 | 0 | valBits = FDKgetValidBits(hBs) + ADTS_SYNCLENGTH; |
184 | |
|
185 | 0 | if (valBits < ADTS_HEADERLENGTH) { |
186 | 0 | return TRANSPORTDEC_NOT_ENOUGH_BITS; |
187 | 0 | } |
188 | | |
189 | | /* adts_fixed_header */ |
190 | 0 | bs.mpeg_id = FDKreadBits(hBs, Adts_Length_Id); |
191 | 0 | bs.layer = FDKreadBits(hBs, Adts_Length_Layer); |
192 | 0 | bs.protection_absent = FDKreadBits(hBs, Adts_Length_ProtectionAbsent); |
193 | 0 | bs.profile = FDKreadBits(hBs, Adts_Length_Profile); |
194 | 0 | bs.sample_freq_index = FDKreadBits(hBs, Adts_Length_SamplingFrequencyIndex); |
195 | 0 | bs.private_bit = FDKreadBits(hBs, Adts_Length_PrivateBit); |
196 | 0 | bs.channel_config = FDKreadBits(hBs, Adts_Length_ChannelConfiguration); |
197 | 0 | bs.original = FDKreadBits(hBs, Adts_Length_OriginalCopy); |
198 | 0 | bs.home = FDKreadBits(hBs, Adts_Length_Home); |
199 | | |
200 | | /* adts_variable_header */ |
201 | 0 | bs.copyright_id = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit); |
202 | 0 | bs.copyright_start = |
203 | 0 | FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart); |
204 | 0 | bs.frame_length = FDKreadBits(hBs, Adts_Length_FrameLength); |
205 | 0 | bs.adts_fullness = FDKreadBits(hBs, Adts_Length_BufferFullness); |
206 | 0 | bs.num_raw_blocks = |
207 | 0 | FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame); |
208 | 0 | bs.num_pce_bits = 0; |
209 | |
|
210 | 0 | adtsHeaderLength = ADTS_HEADERLENGTH; |
211 | |
|
212 | 0 | if (valBits < bs.frame_length * 8) { |
213 | 0 | goto bail; |
214 | 0 | } |
215 | | |
216 | 0 | FDKcrcReset(&pAdts->crcInfo); |
217 | 0 | if (!bs.protection_absent) { |
218 | 0 | FDKpushBack(hBs, 56); /* complete fixed and variable header! */ |
219 | 0 | crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0); |
220 | 0 | FDKpushFor(hBs, 56); |
221 | 0 | } |
222 | |
|
223 | 0 | if (!bs.protection_absent && bs.num_raw_blocks > 0) { |
224 | 0 | if ((INT)FDKgetValidBits(hBs) < bs.num_raw_blocks * 16) { |
225 | 0 | goto bail; |
226 | 0 | } |
227 | 0 | for (i = 0; i < bs.num_raw_blocks; i++) { |
228 | 0 | pAdts->rawDataBlockDist[i] = (USHORT)FDKreadBits(hBs, 16); |
229 | 0 | adtsHeaderLength += 16; |
230 | 0 | } |
231 | | /* Change raw data blocks to delta values */ |
232 | 0 | pAdts->rawDataBlockDist[bs.num_raw_blocks] = |
233 | 0 | bs.frame_length - 7 - bs.num_raw_blocks * 2 - 2; |
234 | 0 | for (i = bs.num_raw_blocks; i > 0; i--) { |
235 | 0 | pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i - 1]; |
236 | 0 | } |
237 | 0 | } |
238 | | |
239 | | /* adts_error_check */ |
240 | 0 | if (!bs.protection_absent) { |
241 | 0 | USHORT crc_check; |
242 | |
|
243 | 0 | FDKcrcEndReg(&pAdts->crcInfo, hBs, crcReg); |
244 | |
|
245 | 0 | if ((INT)FDKgetValidBits(hBs) < Adts_Length_CrcCheck) { |
246 | 0 | goto bail; |
247 | 0 | } |
248 | | |
249 | 0 | crc_check = FDKreadBits(hBs, Adts_Length_CrcCheck); |
250 | 0 | adtsHeaderLength += Adts_Length_CrcCheck; |
251 | |
|
252 | 0 | pAdts->crcReadValue = crc_check; |
253 | | /* Check header CRC in case of multiple raw data blocks */ |
254 | 0 | if (bs.num_raw_blocks > 0) { |
255 | 0 | if (pAdts->crcReadValue != FDKcrcGetCRC(&pAdts->crcInfo)) { |
256 | 0 | return TRANSPORTDEC_CRC_ERROR; |
257 | 0 | } |
258 | | /* Reset CRC for the upcoming raw_data_block() */ |
259 | 0 | FDKcrcReset(&pAdts->crcInfo); |
260 | 0 | } |
261 | 0 | } |
262 | | |
263 | | /* check if valid header */ |
264 | 0 | if ((bs.layer != 0) || // we only support MPEG ADTS |
265 | 0 | (bs.sample_freq_index >= 13) // we only support 96kHz - 7350kHz |
266 | 0 | ) { |
267 | 0 | FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later |
268 | 0 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
269 | 0 | } |
270 | | |
271 | | /* special treatment of id-bit */ |
272 | 0 | if ((bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0)) { |
273 | | /* MPEG-2 decoder cannot play MPEG-4 bitstreams */ |
274 | |
|
275 | 0 | FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later |
276 | 0 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
277 | 0 | } |
278 | | |
279 | 0 | if (!ignoreBufferFullness) { |
280 | 0 | cmp_buffer_fullness = |
281 | 0 | bs.frame_length * 8 + |
282 | 0 | bs.adts_fullness * 32 * getNumberOfEffectiveChannels(bs.channel_config); |
283 | | |
284 | | /* Evaluate buffer fullness */ |
285 | 0 | if (bs.adts_fullness != 0x7FF) { |
286 | 0 | if (pAdts->BufferFullnesStartFlag) { |
287 | 0 | if (valBits < cmp_buffer_fullness) { |
288 | | /* Condition for start of decoding is not fulfilled */ |
289 | | |
290 | | /* The current frame will not be decoded */ |
291 | 0 | FDKpushBack(hBs, adtsHeaderLength); |
292 | |
|
293 | 0 | if ((cmp_buffer_fullness + adtsHeaderLength) > |
294 | 0 | (((8192 * 4) << 3) - 7)) { |
295 | 0 | return TRANSPORTDEC_SYNC_ERROR; |
296 | 0 | } else { |
297 | 0 | return TRANSPORTDEC_NOT_ENOUGH_BITS; |
298 | 0 | } |
299 | 0 | } else { |
300 | 0 | pAdts->BufferFullnesStartFlag = 0; |
301 | 0 | } |
302 | 0 | } |
303 | 0 | } |
304 | 0 | } |
305 | | |
306 | | /* Get info from ADTS header */ |
307 | 0 | AudioSpecificConfig_Init(pAsc); |
308 | 0 | pAsc->m_aot = (AUDIO_OBJECT_TYPE)(bs.profile + 1); |
309 | 0 | pAsc->m_samplingFrequencyIndex = bs.sample_freq_index; |
310 | 0 | pAsc->m_samplingFrequency = SamplingRateTable[bs.sample_freq_index]; |
311 | 0 | pAsc->m_channelConfiguration = bs.channel_config; |
312 | 0 | pAsc->m_samplesPerFrame = 1024; |
313 | |
|
314 | 0 | if (bs.channel_config == 0) { |
315 | 0 | int pceBits = 0; |
316 | 0 | UINT alignAnchor = FDKgetValidBits(hBs); |
317 | 0 | CProgramConfig tmpPce; |
318 | |
|
319 | 0 | if (FDKreadBits(hBs, 3) == ID_PCE) { |
320 | | /* Got luck! Parse the PCE */ |
321 | 0 | crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0); |
322 | |
|
323 | 0 | CProgramConfig_Init(&tmpPce); |
324 | 0 | CProgramConfig_Read(&tmpPce, hBs, alignAnchor); |
325 | |
|
326 | 0 | if (CProgramConfig_IsValid(&tmpPce)) { |
327 | 0 | if (CProgramConfig_IsValid(&oldPce)) { |
328 | | /* Compare the new and the old PCE (tags ignored) */ |
329 | 0 | switch (CProgramConfig_Compare(&tmpPce, &oldPce)) { |
330 | 0 | case 0: /* Nothing to do because PCE matches the old one exactly. */ |
331 | 0 | case 1: /* Channel configuration not changed. Just new metadata. */ |
332 | 0 | FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce, |
333 | 0 | sizeof(CProgramConfig)); |
334 | 0 | break; |
335 | 0 | case 2: /* The number of channels are identical but not the config |
336 | | */ |
337 | 0 | case -1: /* The channel configuration is completely different */ |
338 | 0 | default: |
339 | 0 | FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, |
340 | 0 | sizeof(CProgramConfig)); |
341 | 0 | FDKpushBack(hBs, adtsHeaderLength); |
342 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
343 | 0 | } |
344 | 0 | } else { |
345 | 0 | FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce, |
346 | 0 | sizeof(CProgramConfig)); |
347 | 0 | } |
348 | 0 | } else { |
349 | 0 | if (CProgramConfig_IsValid(&oldPce)) { |
350 | 0 | FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, |
351 | 0 | sizeof(CProgramConfig)); |
352 | 0 | } else { |
353 | 0 | FDKpushBack(hBs, adtsHeaderLength); |
354 | 0 | return TRANSPORTDEC_PARSE_ERROR; |
355 | 0 | } |
356 | 0 | } |
357 | | |
358 | 0 | adtsRead_CrcEndReg(pAdts, hBs, crcReg); |
359 | 0 | pceBits = (INT)alignAnchor - (INT)FDKgetValidBits(hBs); |
360 | 0 | adtsHeaderLength += pceBits; |
361 | |
|
362 | 0 | if (pceBits > (INT)alignAnchor) { |
363 | 0 | goto bail; |
364 | 0 | } |
365 | | |
366 | | /* store the number of PCE bits */ |
367 | 0 | bs.num_pce_bits = pceBits; |
368 | 0 | } else { |
369 | | /* No PCE in this frame! Push back the ID tag bits. */ |
370 | 0 | FDKpushBack(hBs, 3); |
371 | | |
372 | | /* Encoders do not have to write a PCE in each frame. |
373 | | So if we already have a valid PCE we have to use it. */ |
374 | 0 | if (oldPce.isValid && |
375 | 0 | (bs.sample_freq_index == |
376 | 0 | pAdts->bs.sample_freq_index) /* we could compare the complete fixed |
377 | | header (bytes) here! */ |
378 | 0 | && (bs.channel_config == pAdts->bs.channel_config) /* == 0 */ |
379 | 0 | && |
380 | 0 | (bs.mpeg_id == |
381 | 0 | pAdts->bs.mpeg_id)) { /* Restore previous PCE which is still valid */ |
382 | 0 | FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, sizeof(CProgramConfig)); |
383 | 0 | } else if (bs.mpeg_id == 0) { |
384 | | /* If not it seems that we have a implicit channel configuration. |
385 | | This mode is not allowed in the context of ISO/IEC 14496-3. |
386 | | Skip this frame and try the next one. */ |
387 | 0 | FDKpushFor(hBs, (bs.frame_length << 3) - adtsHeaderLength - 3); |
388 | 0 | return TRANSPORTDEC_UNSUPPORTED_FORMAT; |
389 | 0 | } |
390 | | /* else { |
391 | | ISO/IEC 13818-7 implicit channel mapping is allowed. |
392 | | So just open the box of chocolates to see what we got. |
393 | | } */ |
394 | 0 | } |
395 | 0 | } |
396 | | |
397 | | /* Copy bit stream data struct to persistent memory now, once we passed all |
398 | | * sanity checks above. */ |
399 | 0 | FDKmemcpy(&pAdts->bs, &bs, sizeof(STRUCT_ADTS_BS)); |
400 | |
|
401 | 0 | return TRANSPORTDEC_OK; |
402 | | |
403 | 0 | bail: |
404 | 0 | FDKpushBack(hBs, adtsHeaderLength); |
405 | 0 | return TRANSPORTDEC_NOT_ENOUGH_BITS; |
406 | 0 | } |
407 | | |
408 | 0 | int adtsRead_GetRawDataBlockLength(HANDLE_ADTS pAdts, INT blockNum) { |
409 | 0 | int length; |
410 | |
|
411 | 0 | if (pAdts->bs.num_raw_blocks == 0) { |
412 | 0 | length = |
413 | 0 | (pAdts->bs.frame_length - 7) |
414 | 0 | << 3; /* aac_frame_length subtracted by the header size (7 bytes). */ |
415 | 0 | if (pAdts->bs.protection_absent == 0) |
416 | 0 | length -= 16; /* substract 16 bit CRC */ |
417 | 0 | } else { |
418 | 0 | if (pAdts->bs.protection_absent) { |
419 | 0 | length = -1; /* raw data block length is unknown */ |
420 | 0 | } else { |
421 | 0 | if (blockNum < 0 || blockNum > 3) { |
422 | 0 | length = -1; |
423 | 0 | } else { |
424 | 0 | length = (pAdts->rawDataBlockDist[blockNum] << 3) - 16; |
425 | 0 | } |
426 | 0 | } |
427 | 0 | } |
428 | 0 | if (blockNum == 0 && length > 0) { |
429 | 0 | length -= pAdts->bs.num_pce_bits; |
430 | 0 | } |
431 | 0 | return length; |
432 | 0 | } |