/src/aac/libAACdec/src/aacdecoder_lib.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 - 2023 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 | | /**************************** AAC decoder library ****************************** |
96 | | |
97 | | Author(s): Manuel Jander |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "aacdecoder_lib.h" |
104 | | |
105 | | #include "aac_ram.h" |
106 | | #include "aacdecoder.h" |
107 | | #include "tpdec_lib.h" |
108 | | #include "FDK_core.h" /* FDK_tools version info */ |
109 | | |
110 | | #include "sbrdecoder.h" |
111 | | |
112 | | #include "conceal.h" |
113 | | |
114 | | #include "aacdec_drc.h" |
115 | | |
116 | | #include "sac_dec_lib.h" |
117 | | |
118 | | #include "pcm_utils.h" |
119 | | |
120 | | /* Decoder library info */ |
121 | | #define AACDECODER_LIB_VL0 3 |
122 | | #define AACDECODER_LIB_VL1 2 |
123 | | #define AACDECODER_LIB_VL2 0 |
124 | 0 | #define AACDECODER_LIB_TITLE "AAC Decoder Lib" |
125 | | #ifdef SUPPRESS_BUILD_DATE_INFO |
126 | | #define AACDECODER_LIB_BUILD_DATE "" |
127 | | #define AACDECODER_LIB_BUILD_TIME "" |
128 | | #else |
129 | 0 | #define AACDECODER_LIB_BUILD_DATE __DATE__ |
130 | 0 | #define AACDECODER_LIB_BUILD_TIME __TIME__ |
131 | | #endif |
132 | | |
133 | | static AAC_DECODER_ERROR setConcealMethod(const HANDLE_AACDECODER self, |
134 | | const INT method); |
135 | | |
136 | | static void aacDecoder_setMetadataExpiry(const HANDLE_AACDECODER self, |
137 | 5.49k | const INT value) { |
138 | | /* check decoder handle */ |
139 | 5.49k | if (self != NULL) { |
140 | 5.49k | INT mdExpFrame = 0; /* default: disable */ |
141 | | |
142 | 5.49k | if ((value > 0) && |
143 | 5.49k | (self->streamInfo.aacSamplesPerFrame > |
144 | 0 | 0)) { /* Determine the corresponding number of frames: */ |
145 | 0 | FIXP_DBL frameTime = fDivNorm(self->streamInfo.aacSampleRate, |
146 | 0 | self->streamInfo.aacSamplesPerFrame * 1000); |
147 | 0 | mdExpFrame = fMultIceil(frameTime, value); |
148 | 0 | } |
149 | | |
150 | | /* Configure DRC module */ |
151 | 5.49k | aacDecoder_drcSetParam(self->hDrcInfo, DRC_DATA_EXPIRY_FRAME, mdExpFrame); |
152 | | |
153 | | /* Configure PCM downmix module */ |
154 | 5.49k | pcmDmx_SetParam(self->hPcmUtils, DMX_BS_DATA_EXPIRY_FRAME, mdExpFrame); |
155 | 5.49k | } |
156 | 5.49k | } |
157 | | |
158 | | LINKSPEC_CPP AAC_DECODER_ERROR |
159 | 0 | aacDecoder_GetFreeBytes(const HANDLE_AACDECODER self, UINT *pFreeBytes) { |
160 | | /* reset free bytes */ |
161 | 0 | *pFreeBytes = 0; |
162 | | |
163 | | /* check handle */ |
164 | 0 | if (!self) return AAC_DEC_INVALID_HANDLE; |
165 | | |
166 | | /* return nr of free bytes */ |
167 | 0 | HANDLE_FDK_BITSTREAM hBs = transportDec_GetBitstream(self->hInput, 0); |
168 | 0 | *pFreeBytes = FDKgetFreeBits(hBs) >> 3; |
169 | | |
170 | | /* success */ |
171 | 0 | return AAC_DEC_OK; |
172 | 0 | } |
173 | | |
174 | | /** |
175 | | * Config Decoder using a CSAudioSpecificConfig struct. |
176 | | */ |
177 | | static LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Config( |
178 | | HANDLE_AACDECODER self, const CSAudioSpecificConfig *pAscStruct, |
179 | 5.85k | UCHAR configMode, UCHAR *configChanged) { |
180 | 5.85k | AAC_DECODER_ERROR err; |
181 | | |
182 | | /* Initialize AAC core decoder, and update self->streaminfo */ |
183 | 5.85k | err = CAacDecoder_Init(self, pAscStruct, configMode, configChanged); |
184 | | |
185 | 5.85k | if (!FDK_chMapDescr_isValid(&self->mapDescr)) { |
186 | 0 | return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; |
187 | 0 | } |
188 | | |
189 | 5.85k | return err; |
190 | 5.85k | } |
191 | | |
192 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw(HANDLE_AACDECODER self, |
193 | | UCHAR *conf[], |
194 | 6.87k | const UINT length[]) { |
195 | 6.87k | AAC_DECODER_ERROR err = AAC_DEC_OK; |
196 | 6.87k | TRANSPORTDEC_ERROR errTp; |
197 | 6.87k | UINT layer, nrOfLayers = self->nrOfLayers; |
198 | | |
199 | 9.53k | for (layer = 0; layer < nrOfLayers; layer++) { |
200 | 6.87k | if (length[layer] > 0) { |
201 | 6.87k | errTp = transportDec_OutOfBandConfig(self->hInput, conf[layer], |
202 | 6.87k | length[layer], layer); |
203 | 6.87k | if (errTp != TRANSPORTDEC_OK) { |
204 | 4.22k | switch (errTp) { |
205 | 0 | case TRANSPORTDEC_NEED_TO_RESTART: |
206 | 0 | err = AAC_DEC_NEED_TO_RESTART; |
207 | 0 | break; |
208 | 134 | case TRANSPORTDEC_UNSUPPORTED_FORMAT: |
209 | 134 | err = AAC_DEC_UNSUPPORTED_FORMAT; |
210 | 134 | break; |
211 | 4.08k | default: |
212 | 4.08k | err = AAC_DEC_UNKNOWN; |
213 | 4.08k | break; |
214 | 4.22k | } |
215 | | /* if baselayer is OK we continue decoding */ |
216 | 4.22k | if (layer >= 1) { |
217 | 0 | self->nrOfLayers = layer; |
218 | 0 | err = AAC_DEC_OK; |
219 | 0 | } |
220 | 4.22k | break; |
221 | 4.22k | } |
222 | 6.87k | } |
223 | 6.87k | } |
224 | | |
225 | 6.87k | return err; |
226 | 6.87k | } |
227 | | |
228 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_RawISOBMFFData(HANDLE_AACDECODER self, |
229 | | UCHAR *buffer, |
230 | 0 | UINT length) { |
231 | 0 | FDK_BITSTREAM bs; |
232 | 0 | HANDLE_FDK_BITSTREAM hBs = &bs; |
233 | 0 | AAC_DECODER_ERROR err = AAC_DEC_OK; |
234 | |
|
235 | 0 | if (length < 8) return AAC_DEC_UNKNOWN; |
236 | | |
237 | 0 | while (length >= 8) { |
238 | 0 | UINT size = |
239 | 0 | (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; |
240 | 0 | DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK; |
241 | |
|
242 | 0 | if (length < size) return AAC_DEC_UNKNOWN; |
243 | 0 | if (size <= 8) return AAC_DEC_UNKNOWN; |
244 | | |
245 | 0 | FDKinitBitStream(hBs, buffer + 8, 0x10000000, (size - 8) * 8); |
246 | |
|
247 | 0 | if ((buffer[4] == 'l') && (buffer[5] == 'u') && (buffer[6] == 'd') && |
248 | 0 | (buffer[7] == 't')) { |
249 | 0 | uniDrcErr = FDK_drcDec_ReadLoudnessBox(self->hUniDrcDecoder, hBs); |
250 | 0 | } else if ((buffer[4] == 'd') && (buffer[5] == 'm') && (buffer[6] == 'i') && |
251 | 0 | (buffer[7] == 'x')) { |
252 | 0 | uniDrcErr = |
253 | 0 | FDK_drcDec_ReadDownmixInstructions_Box(self->hUniDrcDecoder, hBs); |
254 | 0 | } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'i') && |
255 | 0 | (buffer[7] == '2')) { |
256 | 0 | uniDrcErr = |
257 | 0 | FDK_drcDec_ReadUniDrcInstructions_Box(self->hUniDrcDecoder, hBs); |
258 | 0 | } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'c') && |
259 | 0 | (buffer[7] == '2')) { |
260 | 0 | uniDrcErr = |
261 | 0 | FDK_drcDec_ReadUniDrcCoefficients_Box(self->hUniDrcDecoder, hBs); |
262 | 0 | } |
263 | |
|
264 | 0 | if (uniDrcErr != DRC_DEC_OK) err = AAC_DEC_UNKNOWN; |
265 | |
|
266 | 0 | buffer += size; |
267 | 0 | length -= size; |
268 | 0 | } |
269 | | |
270 | 0 | return err; |
271 | 0 | } |
272 | | |
273 | | static INT aacDecoder_ConfigCallback(void *handle, |
274 | | const CSAudioSpecificConfig *pAscStruct, |
275 | 5.85k | UCHAR configMode, UCHAR *configChanged) { |
276 | 5.85k | HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle; |
277 | 5.85k | AAC_DECODER_ERROR err = AAC_DEC_OK; |
278 | 5.85k | TRANSPORTDEC_ERROR errTp; |
279 | | |
280 | 5.85k | FDK_ASSERT(self != NULL); |
281 | 5.85k | { |
282 | 5.85k | { err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); } |
283 | 5.85k | } |
284 | 5.85k | if (err == AAC_DEC_OK) { |
285 | | /* |
286 | | revert concealment method if either |
287 | | - Interpolation concealment might not be meaningful |
288 | | - Interpolation concealment is not implemented |
289 | | */ |
290 | 5.49k | if ((self->flags[0] & (AC_LD | AC_ELD) && |
291 | 5.49k | (self->concealMethodUser == ConcealMethodNone) && |
292 | 5.49k | CConcealment_GetDelay(&self->concealCommonData) > |
293 | 861 | 0) /* might not be meaningful but allow if user has set it |
294 | | expicitly */ |
295 | 5.49k | || (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && |
296 | 4.98k | CConcealment_GetDelay(&self->concealCommonData) > |
297 | 3.65k | 0) /* not implemented */ |
298 | 5.49k | ) { |
299 | | /* Revert to error concealment method Noise Substitution. |
300 | | Because interpolation is not implemented for USAC or |
301 | | the additional delay is unwanted for low delay codecs. */ |
302 | 2.34k | setConcealMethod(self, 1); |
303 | 2.34k | } |
304 | 5.49k | aacDecoder_setMetadataExpiry(self, self->metadataExpiry); |
305 | 5.49k | errTp = TRANSPORTDEC_OK; |
306 | 5.49k | } else { |
307 | 369 | if (err == AAC_DEC_NEED_TO_RESTART) { |
308 | 0 | errTp = TRANSPORTDEC_NEED_TO_RESTART; |
309 | 369 | } else if (IS_INIT_ERROR(err)) { |
310 | 369 | errTp = TRANSPORTDEC_UNSUPPORTED_FORMAT; |
311 | 369 | } /* Fatal errors */ |
312 | 0 | else { |
313 | 0 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
314 | 0 | } |
315 | 369 | } |
316 | | |
317 | 5.85k | return errTp; |
318 | 5.85k | } |
319 | | |
320 | | static INT aacDecoder_FreeMemCallback(void *handle, |
321 | 2.83k | const CSAudioSpecificConfig *pAscStruct) { |
322 | 2.83k | TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK; |
323 | 2.83k | HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle; |
324 | | |
325 | 2.83k | const int subStreamIndex = 0; |
326 | | |
327 | 2.83k | FDK_ASSERT(self != NULL); |
328 | | |
329 | 2.83k | if (CAacDecoder_FreeMem(self, subStreamIndex) != AAC_DEC_OK) { |
330 | 0 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
331 | 0 | } |
332 | | |
333 | | /* free Ram_SbrDecoder and Ram_SbrDecChannel */ |
334 | 2.83k | if (self->hSbrDecoder != NULL) { |
335 | 2.83k | if (sbrDecoder_FreeMem(&self->hSbrDecoder) != SBRDEC_OK) { |
336 | 0 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
337 | 0 | } |
338 | 2.83k | } |
339 | | |
340 | | /* free pSpatialDec and mpsData */ |
341 | 2.83k | if (self->pMpegSurroundDecoder != NULL) { |
342 | 2.83k | if (mpegSurroundDecoder_FreeMem( |
343 | 2.83k | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) != MPS_OK) { |
344 | 0 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
345 | 0 | } |
346 | 2.83k | } |
347 | | |
348 | | /* free persistent qmf domain buffer, QmfWorkBufferCore3, QmfWorkBufferCore4, |
349 | | * QmfWorkBufferCore5 and configuration variables */ |
350 | 2.83k | FDK_QmfDomain_FreeMem(&self->qmfDomain); |
351 | | |
352 | 2.83k | return errTp; |
353 | 2.83k | } |
354 | | |
355 | | static INT aacDecoder_CtrlCFGChangeCallback( |
356 | 0 | void *handle, const CCtrlCFGChange *pCtrlCFGChangeStruct) { |
357 | 0 | TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK; |
358 | 0 | HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle; |
359 | |
|
360 | 0 | if (self != NULL) { |
361 | 0 | CAacDecoder_CtrlCFGChange( |
362 | 0 | self, pCtrlCFGChangeStruct->flushStatus, pCtrlCFGChangeStruct->flushCnt, |
363 | 0 | pCtrlCFGChangeStruct->buildUpStatus, pCtrlCFGChangeStruct->buildUpCnt); |
364 | 0 | } else { |
365 | 0 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
366 | 0 | } |
367 | |
|
368 | 0 | return errTp; |
369 | 0 | } |
370 | | |
371 | | static INT aacDecoder_SbrCallback( |
372 | | void *handle, HANDLE_FDK_BITSTREAM hBs, const INT sampleRateIn, |
373 | | const INT sampleRateOut, const INT samplesPerFrame, |
374 | | const AUDIO_OBJECT_TYPE coreCodec, const MP4_ELEMENT_ID elementID, |
375 | | const INT elementIndex, const UCHAR harmonicSBR, |
376 | | const UCHAR stereoConfigIndex, const UCHAR configMode, UCHAR *configChanged, |
377 | 2.48k | const INT downscaleFactor) { |
378 | 2.48k | HANDLE_SBRDECODER self = (HANDLE_SBRDECODER)handle; |
379 | | |
380 | 2.48k | INT errTp = sbrDecoder_Header(self, hBs, sampleRateIn, sampleRateOut, |
381 | 2.48k | samplesPerFrame, coreCodec, elementID, |
382 | 2.48k | elementIndex, harmonicSBR, stereoConfigIndex, |
383 | 2.48k | configMode, configChanged, downscaleFactor); |
384 | | |
385 | 2.48k | return errTp; |
386 | 2.48k | } |
387 | | |
388 | | static INT aacDecoder_SscCallback( |
389 | | void *handle, HANDLE_FDK_BITSTREAM hBs, const AUDIO_OBJECT_TYPE coreCodec, |
390 | | const INT samplingRate, const INT frameSize, const INT numChannels, |
391 | | const INT stereoConfigIndex, const INT coreSbrFrameLengthIndex, |
392 | 1.01k | const INT configBytes, const UCHAR configMode, UCHAR *configChanged) { |
393 | 1.01k | SACDEC_ERROR err; |
394 | 1.01k | TRANSPORTDEC_ERROR errTp; |
395 | 1.01k | HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; |
396 | | |
397 | 1.01k | err = mpegSurroundDecoder_Config( |
398 | 1.01k | (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec, |
399 | 1.01k | samplingRate, frameSize, numChannels, stereoConfigIndex, |
400 | 1.01k | coreSbrFrameLengthIndex, configBytes, configMode, configChanged); |
401 | | |
402 | 1.01k | switch (err) { |
403 | 239 | case MPS_UNSUPPORTED_CONFIG: |
404 | | /* MPS found but invalid or not decodable by this instance */ |
405 | | /* We switch off MPS and keep going */ |
406 | 239 | hAacDecoder->mpsEnableCurr = 0; |
407 | 239 | hAacDecoder->mpsApplicable = 0; |
408 | 239 | errTp = TRANSPORTDEC_OK; |
409 | 239 | break; |
410 | 258 | case MPS_PARSE_ERROR: |
411 | | /* MPS found but invalid or not decodable by this instance */ |
412 | 258 | hAacDecoder->mpsEnableCurr = 0; |
413 | 258 | hAacDecoder->mpsApplicable = 0; |
414 | 258 | if ((coreCodec == AOT_USAC) || (coreCodec == AOT_DRM_USAC) || |
415 | 258 | IS_LOWDELAY(coreCodec)) { |
416 | 258 | errTp = TRANSPORTDEC_PARSE_ERROR; |
417 | 258 | } else { |
418 | 0 | errTp = TRANSPORTDEC_OK; |
419 | 0 | } |
420 | 258 | break; |
421 | 513 | case MPS_OK: |
422 | 513 | hAacDecoder->mpsApplicable = 1; |
423 | 513 | errTp = TRANSPORTDEC_OK; |
424 | 513 | break; |
425 | 1 | default: |
426 | | /* especially Parsing error is critical for transport layer */ |
427 | 1 | hAacDecoder->mpsApplicable = 0; |
428 | 1 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
429 | 1.01k | } |
430 | | |
431 | 1.01k | return (INT)errTp; |
432 | 1.01k | } |
433 | | |
434 | | static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, |
435 | | const INT fullPayloadLength, |
436 | | const INT payloadType, |
437 | | const INT subStreamIndex, |
438 | | const INT payloadStart, |
439 | 36.4k | const AUDIO_OBJECT_TYPE aot) { |
440 | 36.4k | DRC_DEC_ERROR err = DRC_DEC_OK; |
441 | 36.4k | TRANSPORTDEC_ERROR errTp; |
442 | 36.4k | HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; |
443 | 36.4k | DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED; |
444 | 36.4k | UCHAR dummyBuffer[4] = {0}; |
445 | 36.4k | FDK_BITSTREAM dummyBs; |
446 | 36.4k | HANDLE_FDK_BITSTREAM hReadBs; |
447 | | |
448 | 36.4k | if (subStreamIndex != 0) { |
449 | 0 | return TRANSPORTDEC_OK; |
450 | 0 | } |
451 | | |
452 | 36.4k | if (hBs == NULL) { |
453 | | /* use dummy zero payload to clear memory */ |
454 | 3.83k | hReadBs = &dummyBs; |
455 | 3.83k | FDKinitBitStream(hReadBs, dummyBuffer, 4, 24); |
456 | 32.6k | } else { |
457 | 32.6k | hReadBs = hBs; |
458 | 32.6k | } |
459 | | |
460 | 36.4k | if (aot == AOT_USAC) { |
461 | 36.4k | drcDecCodecMode = DRC_DEC_MPEG_D_USAC; |
462 | 36.4k | } |
463 | | |
464 | 36.4k | err = FDK_drcDec_SetCodecMode(hAacDecoder->hUniDrcDecoder, drcDecCodecMode); |
465 | 36.4k | if (err) return (INT)TRANSPORTDEC_UNKOWN_ERROR; |
466 | | |
467 | 36.4k | if (payloadType == 0) /* uniDrcConfig */ |
468 | 31.3k | { |
469 | 31.3k | err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hReadBs); |
470 | 31.3k | } else /* loudnessInfoSet */ |
471 | 5.19k | { |
472 | 5.19k | err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hReadBs); |
473 | 5.19k | hAacDecoder->loudnessInfoSetPosition[1] = payloadStart; |
474 | 5.19k | hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength; |
475 | 5.19k | } |
476 | | |
477 | 36.4k | if (err == DRC_DEC_OK) |
478 | 36.4k | errTp = TRANSPORTDEC_OK; |
479 | 0 | else |
480 | 0 | errTp = TRANSPORTDEC_UNKOWN_ERROR; |
481 | | |
482 | 36.4k | return (INT)errTp; |
483 | 36.4k | } |
484 | | |
485 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self, |
486 | 0 | UCHAR *buffer, int size) { |
487 | 0 | CAncData *ancData = &self->ancData; |
488 | |
|
489 | 0 | return CAacDecoder_AncDataInit(ancData, buffer, size); |
490 | 0 | } |
491 | | |
492 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self, |
493 | | int index, UCHAR **ptr, |
494 | 0 | int *size) { |
495 | 0 | CAncData *ancData = &self->ancData; |
496 | |
|
497 | 0 | return CAacDecoder_AncDataGet(ancData, index, ptr, size); |
498 | 0 | } |
499 | | |
500 | | /* If MPS is present in stream, but not supported by this instance, we'll |
501 | | have to switch off MPS and use QMF synthesis in the SBR module if required */ |
502 | | static int isSupportedMpsConfig(AUDIO_OBJECT_TYPE aot, |
503 | | unsigned int numInChannels, |
504 | 0 | unsigned int fMpsPresent) { |
505 | 0 | LIB_INFO libInfo[FDK_MODULE_LAST]; |
506 | 0 | UINT mpsCaps; |
507 | 0 | int isSupportedCfg = 1; |
508 | |
|
509 | 0 | FDKinitLibInfo(libInfo); |
510 | |
|
511 | 0 | mpegSurroundDecoder_GetLibInfo(libInfo); |
512 | |
|
513 | 0 | mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC); |
514 | |
|
515 | 0 | if (!(mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot)) { |
516 | | /* We got an LD AOT but MPS decoder does not support LD. */ |
517 | 0 | isSupportedCfg = 0; |
518 | 0 | } |
519 | 0 | if ((mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot) && !fMpsPresent) { |
520 | | /* We got an LD AOT and the MPS decoder supports it. |
521 | | * But LD-MPS is not explicitly signaled. */ |
522 | 0 | isSupportedCfg = 0; |
523 | 0 | } |
524 | 0 | if (!(mpsCaps & CAPF_MPS_USAC) && IS_USAC(aot)) { |
525 | | /* We got an USAC AOT but MPS decoder does not support USAC. */ |
526 | 0 | isSupportedCfg = 0; |
527 | 0 | } |
528 | 0 | if (!(mpsCaps & CAPF_MPS_STD) && !IS_LOWDELAY(aot) && !IS_USAC(aot)) { |
529 | | /* We got an GA AOT but MPS decoder does not support it. */ |
530 | 0 | isSupportedCfg = 0; |
531 | 0 | } |
532 | | /* Check whether the MPS modul supports the given number of input channels: */ |
533 | 0 | switch (numInChannels) { |
534 | 0 | case 1: |
535 | 0 | if (!(mpsCaps & CAPF_MPS_1CH_IN)) { |
536 | | /* We got a one channel input to MPS decoder but it does not support it. |
537 | | */ |
538 | 0 | isSupportedCfg = 0; |
539 | 0 | } |
540 | 0 | break; |
541 | 0 | case 2: |
542 | 0 | if (!(mpsCaps & CAPF_MPS_2CH_IN)) { |
543 | | /* We got a two channel input to MPS decoder but it does not support it. |
544 | | */ |
545 | 0 | isSupportedCfg = 0; |
546 | 0 | } |
547 | 0 | break; |
548 | 0 | case 5: |
549 | 0 | case 6: |
550 | 0 | if (!(mpsCaps & CAPF_MPS_6CH_IN)) { |
551 | | /* We got a six channel input to MPS decoder but it does not support it. |
552 | | */ |
553 | 0 | isSupportedCfg = 0; |
554 | 0 | } |
555 | 0 | break; |
556 | 0 | default: |
557 | 0 | isSupportedCfg = 0; |
558 | 0 | } |
559 | | |
560 | 0 | return (isSupportedCfg); |
561 | 0 | } |
562 | | |
563 | | static AAC_DECODER_ERROR setConcealMethod( |
564 | | const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */ |
565 | 9.22k | const INT method) { |
566 | 9.22k | AAC_DECODER_ERROR errorStatus = AAC_DEC_OK; |
567 | 9.22k | CConcealParams *pConcealData = NULL; |
568 | 9.22k | int method_revert = 0; |
569 | 9.22k | HANDLE_SBRDECODER hSbrDec = NULL; |
570 | 9.22k | HANDLE_AAC_DRC hDrcInfo = NULL; |
571 | 9.22k | HANDLE_PCM_DOWNMIX hPcmDmx = NULL; |
572 | 9.22k | CConcealmentMethod backupMethod = ConcealMethodNone; |
573 | 9.22k | int backupDelay = 0; |
574 | 9.22k | int bsDelay = 0; |
575 | | |
576 | | /* check decoder handle */ |
577 | 9.22k | if (self != NULL) { |
578 | 9.22k | pConcealData = &self->concealCommonData; |
579 | 9.22k | hSbrDec = self->hSbrDecoder; |
580 | 9.22k | hDrcInfo = self->hDrcInfo; |
581 | 9.22k | hPcmDmx = self->hPcmUtils; |
582 | 9.22k | if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) { |
583 | | /* Interpolation concealment is not implemented for USAC/RSVD50 */ |
584 | | /* errorStatus = AAC_DEC_SET_PARAM_FAIL; |
585 | | goto bail; */ |
586 | 0 | method_revert = 1; |
587 | 0 | } |
588 | 9.22k | if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) { |
589 | | /* Interpolation concealment is not implemented for USAC/RSVD50 */ |
590 | 0 | errorStatus = AAC_DEC_SET_PARAM_FAIL; |
591 | 0 | goto bail; |
592 | 0 | } |
593 | 9.22k | } |
594 | | |
595 | | /* Get current method/delay */ |
596 | 9.22k | backupMethod = CConcealment_GetMethod(pConcealData); |
597 | 9.22k | backupDelay = CConcealment_GetDelay(pConcealData); |
598 | | |
599 | | /* Be sure to set AAC and SBR concealment method simultaneously! */ |
600 | 9.22k | errorStatus = CConcealment_SetParams( |
601 | 9.22k | pConcealData, |
602 | 9.22k | (method_revert == 0) ? (int)method : (int)1, // concealMethod |
603 | 9.22k | AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeOutSlope |
604 | 9.22k | AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeInSlope |
605 | 9.22k | AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealMuteRelease |
606 | 9.22k | AACDEC_CONCEAL_PARAM_NOT_SPECIFIED // concealComfNoiseLevel |
607 | 9.22k | ); |
608 | 9.22k | if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { |
609 | 0 | goto bail; |
610 | 0 | } |
611 | | |
612 | | /* Get new delay */ |
613 | 9.22k | bsDelay = CConcealment_GetDelay(pConcealData); |
614 | | |
615 | 9.22k | { |
616 | 9.22k | SBR_ERROR sbrErr = SBRDEC_OK; |
617 | | |
618 | | /* set SBR bitstream delay */ |
619 | 9.22k | sbrErr = sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, bsDelay); |
620 | | |
621 | 9.22k | switch (sbrErr) { |
622 | 9.22k | case SBRDEC_OK: |
623 | 9.22k | case SBRDEC_NOT_INITIALIZED: |
624 | 9.22k | if (self != NULL) { |
625 | | /* save the param value and set later |
626 | | (when SBR has been initialized) */ |
627 | 9.22k | self->sbrParams.bsDelay = bsDelay; |
628 | 9.22k | } |
629 | 9.22k | break; |
630 | 0 | default: |
631 | 0 | errorStatus = AAC_DEC_SET_PARAM_FAIL; |
632 | 0 | goto bail; |
633 | 9.22k | } |
634 | 9.22k | } |
635 | | |
636 | 9.22k | errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay); |
637 | 9.22k | if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { |
638 | 0 | goto bail; |
639 | 0 | } |
640 | | |
641 | 9.22k | if (errorStatus == AAC_DEC_OK) { |
642 | 9.22k | PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay); |
643 | 9.22k | switch (err) { |
644 | 0 | case PCMDMX_INVALID_HANDLE: |
645 | 0 | errorStatus = AAC_DEC_INVALID_HANDLE; |
646 | 0 | break; |
647 | 9.22k | case PCMDMX_OK: |
648 | 9.22k | break; |
649 | 0 | default: |
650 | 0 | errorStatus = AAC_DEC_SET_PARAM_FAIL; |
651 | 0 | goto bail; |
652 | 9.22k | } |
653 | 9.22k | } |
654 | | |
655 | 9.22k | bail: |
656 | 9.22k | if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { |
657 | | /* Revert to the initial state */ |
658 | 0 | CConcealment_SetParams( |
659 | 0 | pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, |
660 | 0 | AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, |
661 | 0 | AACDEC_CONCEAL_PARAM_NOT_SPECIFIED); |
662 | | /* Revert SBR bitstream delay */ |
663 | 0 | sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay); |
664 | | /* Revert DRC bitstream delay */ |
665 | 0 | aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay); |
666 | | /* Revert PCM mixdown bitstream delay */ |
667 | 0 | pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay); |
668 | 0 | } |
669 | | |
670 | 9.22k | return errorStatus; |
671 | 9.22k | } |
672 | | |
673 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam( |
674 | | const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */ |
675 | | const AACDEC_PARAM param, /*!< Parameter to set */ |
676 | | const INT value) /*!< Parameter valued */ |
677 | 0 | { |
678 | 0 | AAC_DECODER_ERROR errorStatus = AAC_DEC_OK; |
679 | 0 | HANDLE_TRANSPORTDEC hTpDec = NULL; |
680 | 0 | TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK; |
681 | 0 | HANDLE_AAC_DRC hDrcInfo = NULL; |
682 | 0 | HANDLE_PCM_DOWNMIX hPcmDmx = NULL; |
683 | 0 | PCMDMX_ERROR dmxErr = PCMDMX_OK; |
684 | 0 | TDLimiterPtr hPcmTdl = NULL; |
685 | 0 | DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK; |
686 | | |
687 | | /* check decoder handle */ |
688 | 0 | if (self != NULL) { |
689 | 0 | hTpDec = self->hInput; |
690 | 0 | hDrcInfo = self->hDrcInfo; |
691 | 0 | hPcmDmx = self->hPcmUtils; |
692 | 0 | hPcmTdl = self->hLimiter; |
693 | 0 | } else { |
694 | 0 | errorStatus = AAC_DEC_INVALID_HANDLE; |
695 | 0 | goto bail; |
696 | 0 | } |
697 | | |
698 | | /* configure the subsystems */ |
699 | 0 | switch (param) { |
700 | 0 | case AAC_PCM_MIN_OUTPUT_CHANNELS: |
701 | 0 | if (value < -1 || value > (8)) { |
702 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
703 | 0 | } |
704 | 0 | dmxErr = pcmDmx_SetParam(hPcmDmx, MIN_NUMBER_OF_OUTPUT_CHANNELS, value); |
705 | 0 | break; |
706 | | |
707 | 0 | case AAC_PCM_MAX_OUTPUT_CHANNELS: |
708 | 0 | if (value < -1 || value > (8)) { |
709 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
710 | 0 | } |
711 | 0 | dmxErr = pcmDmx_SetParam(hPcmDmx, MAX_NUMBER_OF_OUTPUT_CHANNELS, value); |
712 | |
|
713 | 0 | if (dmxErr != PCMDMX_OK) { |
714 | 0 | goto bail; |
715 | 0 | } |
716 | 0 | errorStatus = |
717 | 0 | aacDecoder_drcSetParam(hDrcInfo, MAX_OUTPUT_CHANNELS, value); |
718 | 0 | if (value > 0) { |
719 | 0 | uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, |
720 | 0 | DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED, |
721 | 0 | (FIXP_DBL)value); |
722 | 0 | } |
723 | 0 | break; |
724 | | |
725 | 0 | case AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE: |
726 | 0 | dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_DUAL_CHANNEL_MODE, value); |
727 | 0 | break; |
728 | | |
729 | 0 | case AAC_PCM_LIMITER_ENABLE: |
730 | 0 | if (value < -2 || value > 1) { |
731 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
732 | 0 | } |
733 | 0 | self->limiterEnableUser = value; |
734 | 0 | break; |
735 | | |
736 | 0 | case AAC_PCM_LIMITER_ATTACK_TIME: |
737 | 0 | if (value <= 0) { /* module function converts value to unsigned */ |
738 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
739 | 0 | } |
740 | 0 | switch (pcmLimiter_SetAttack(hPcmTdl, value)) { |
741 | 0 | case TDLIMIT_OK: |
742 | 0 | break; |
743 | 0 | case TDLIMIT_INVALID_HANDLE: |
744 | 0 | return AAC_DEC_INVALID_HANDLE; |
745 | 0 | case TDLIMIT_INVALID_PARAMETER: |
746 | 0 | default: |
747 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
748 | 0 | } |
749 | 0 | break; |
750 | | |
751 | 0 | case AAC_PCM_LIMITER_RELEAS_TIME: |
752 | 0 | if (value <= 0) { /* module function converts value to unsigned */ |
753 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
754 | 0 | } |
755 | 0 | switch (pcmLimiter_SetRelease(hPcmTdl, value)) { |
756 | 0 | case TDLIMIT_OK: |
757 | 0 | break; |
758 | 0 | case TDLIMIT_INVALID_HANDLE: |
759 | 0 | return AAC_DEC_INVALID_HANDLE; |
760 | 0 | case TDLIMIT_INVALID_PARAMETER: |
761 | 0 | default: |
762 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
763 | 0 | } |
764 | 0 | break; |
765 | | |
766 | 0 | case AAC_METADATA_PROFILE: { |
767 | 0 | DMX_PROFILE_TYPE dmxProfile; |
768 | 0 | INT mdExpiry = -1; /* in ms (-1: don't change) */ |
769 | |
|
770 | 0 | switch ((AAC_MD_PROFILE)value) { |
771 | 0 | case AAC_MD_PROFILE_MPEG_STANDARD: |
772 | 0 | dmxProfile = DMX_PRFL_STANDARD; |
773 | 0 | break; |
774 | 0 | case AAC_MD_PROFILE_MPEG_LEGACY: |
775 | 0 | dmxProfile = DMX_PRFL_MATRIX_MIX; |
776 | 0 | break; |
777 | 0 | case AAC_MD_PROFILE_MPEG_LEGACY_PRIO: |
778 | 0 | dmxProfile = DMX_PRFL_FORCE_MATRIX_MIX; |
779 | 0 | break; |
780 | 0 | case AAC_MD_PROFILE_ARIB_JAPAN: |
781 | 0 | dmxProfile = DMX_PRFL_ARIB_JAPAN; |
782 | 0 | mdExpiry = 550; /* ms */ |
783 | 0 | break; |
784 | 0 | default: |
785 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
786 | 0 | } |
787 | 0 | dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_PROFILE_SETTING, (INT)dmxProfile); |
788 | 0 | if (dmxErr != PCMDMX_OK) { |
789 | 0 | goto bail; |
790 | 0 | } |
791 | 0 | if ((self != NULL) && (mdExpiry >= 0)) { |
792 | 0 | self->metadataExpiry = mdExpiry; |
793 | | /* Determine the corresponding number of frames and configure all |
794 | | * related modules. */ |
795 | 0 | aacDecoder_setMetadataExpiry(self, mdExpiry); |
796 | 0 | } |
797 | 0 | } break; |
798 | | |
799 | 0 | case AAC_METADATA_EXPIRY_TIME: |
800 | 0 | if (value < 0) { |
801 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
802 | 0 | } |
803 | 0 | if (self != NULL) { |
804 | 0 | self->metadataExpiry = value; |
805 | | /* Determine the corresponding number of frames and configure all |
806 | | * related modules. */ |
807 | 0 | aacDecoder_setMetadataExpiry(self, value); |
808 | 0 | } |
809 | 0 | break; |
810 | | |
811 | 0 | case AAC_PCM_OUTPUT_CHANNEL_MAPPING: |
812 | 0 | if (value < 0 || value > 1) { |
813 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
814 | 0 | } |
815 | | /* CAUTION: The given value must be inverted to match the logic! */ |
816 | 0 | FDK_chMapDescr_setPassThrough(&self->mapDescr, !value); |
817 | 0 | break; |
818 | | |
819 | 0 | case AAC_QMF_LOWPOWER: |
820 | 0 | if (value < -1 || value > 1) { |
821 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
822 | 0 | } |
823 | | |
824 | | /** |
825 | | * Set QMF mode (might be overriden) |
826 | | * 0:HQ (complex) |
827 | | * 1:LP (partially complex) |
828 | | */ |
829 | 0 | self->qmfModeUser = (QMF_MODE)value; |
830 | 0 | break; |
831 | | |
832 | 0 | case AAC_DRC_ATTENUATION_FACTOR: |
833 | | /* DRC compression factor (where 0 is no and 127 is max compression) */ |
834 | 0 | if ((value < 0) || (value > 127)) { |
835 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
836 | 0 | } |
837 | 0 | errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value); |
838 | 0 | uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_COMPRESS, |
839 | 0 | value * (FL2FXCONST_DBL(0.5f / 127.0f))); |
840 | 0 | break; |
841 | | |
842 | 0 | case AAC_DRC_BOOST_FACTOR: |
843 | | /* DRC boost factor (where 0 is no and 127 is max boost) */ |
844 | 0 | if ((value < 0) || (value > 127)) { |
845 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
846 | 0 | } |
847 | 0 | errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value); |
848 | 0 | uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_BOOST, |
849 | 0 | value * (FL2FXCONST_DBL(0.5f / 127.0f))); |
850 | 0 | break; |
851 | | |
852 | 0 | case AAC_DRC_REFERENCE_LEVEL: |
853 | 0 | if ((value >= 0) && |
854 | 0 | ((value < 40) || (value > 127))) /* allowed range: -10 to -31.75 dB */ |
855 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
856 | | /* DRC target reference level quantized in 0.25dB steps using values |
857 | | [40..127]. Negative values switch off loudness normalisation. Negative |
858 | | values also switch off MPEG-4 DRC, while MPEG-D DRC can be separately |
859 | | switched on/off with AAC_UNIDRC_SET_EFFECT */ |
860 | 0 | errorStatus = aacDecoder_drcSetParam(hDrcInfo, TARGET_REF_LEVEL, value); |
861 | 0 | uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, |
862 | 0 | DRC_DEC_LOUDNESS_NORMALIZATION_ON, |
863 | 0 | (FIXP_DBL)(value >= 0)); |
864 | | /* set target loudness also for MPEG-D DRC */ |
865 | 0 | self->defaultTargetLoudness = (SCHAR)value; |
866 | 0 | break; |
867 | | |
868 | 0 | case AAC_DRC_HEAVY_COMPRESSION: |
869 | | /* Don't need to overwrite cut/boost values */ |
870 | 0 | errorStatus = |
871 | 0 | aacDecoder_drcSetParam(hDrcInfo, APPLY_HEAVY_COMPRESSION, value); |
872 | 0 | break; |
873 | | |
874 | 0 | case AAC_DRC_DEFAULT_PRESENTATION_MODE: |
875 | | /* DRC default presentation mode */ |
876 | 0 | errorStatus = |
877 | 0 | aacDecoder_drcSetParam(hDrcInfo, DEFAULT_PRESENTATION_MODE, value); |
878 | 0 | break; |
879 | | |
880 | 0 | case AAC_DRC_ENC_TARGET_LEVEL: |
881 | | /* Encoder target level for light (i.e. not heavy) compression: |
882 | | Target reference level assumed at encoder for deriving limiting gains |
883 | | */ |
884 | 0 | errorStatus = |
885 | 0 | aacDecoder_drcSetParam(hDrcInfo, ENCODER_TARGET_LEVEL, value); |
886 | 0 | break; |
887 | | |
888 | 0 | case AAC_UNIDRC_SET_EFFECT: |
889 | 0 | if ((value < -1) || (value > 6)) return AAC_DEC_SET_PARAM_FAIL; |
890 | 0 | uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_EFFECT_TYPE, |
891 | 0 | (FIXP_DBL)value); |
892 | 0 | break; |
893 | 0 | case AAC_UNIDRC_ALBUM_MODE: |
894 | 0 | uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_ALBUM_MODE, |
895 | 0 | (FIXP_DBL)value); |
896 | 0 | break; |
897 | | |
898 | 0 | case AAC_TPDEC_CLEAR_BUFFER: |
899 | 0 | errTp = transportDec_SetParam(hTpDec, TPDEC_PARAM_RESET, 1); |
900 | 0 | self->streamInfo.numLostAccessUnits = 0; |
901 | 0 | self->streamInfo.numBadBytes = 0; |
902 | 0 | self->streamInfo.numTotalBytes = 0; |
903 | | /* aacDecoder_SignalInterruption(self); */ |
904 | 0 | break; |
905 | 0 | case AAC_CONCEAL_METHOD: |
906 | | /* Changing the concealment method can introduce additional bitstream |
907 | | delay. And that in turn affects sub libraries and modules which makes |
908 | | the whole thing quite complex. So the complete changing routine is |
909 | | packed into a helper function which keeps all modules and libs in a |
910 | | consistent state even in the case an error occures. */ |
911 | 0 | errorStatus = setConcealMethod(self, value); |
912 | 0 | if (errorStatus == AAC_DEC_OK) { |
913 | 0 | self->concealMethodUser = (CConcealmentMethod)value; |
914 | 0 | } |
915 | 0 | break; |
916 | | |
917 | 0 | default: |
918 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
919 | 0 | } /* switch(param) */ |
920 | | |
921 | 0 | bail: |
922 | |
|
923 | 0 | if (errorStatus == AAC_DEC_OK) { |
924 | | /* Check error code returned by DMX module library: */ |
925 | 0 | switch (dmxErr) { |
926 | 0 | case PCMDMX_OK: |
927 | 0 | break; |
928 | 0 | case PCMDMX_INVALID_HANDLE: |
929 | 0 | errorStatus = AAC_DEC_INVALID_HANDLE; |
930 | 0 | break; |
931 | 0 | default: |
932 | 0 | errorStatus = AAC_DEC_SET_PARAM_FAIL; |
933 | 0 | } |
934 | 0 | } |
935 | | |
936 | 0 | if (errTp != TRANSPORTDEC_OK && errorStatus == AAC_DEC_OK) { |
937 | 0 | errorStatus = AAC_DEC_SET_PARAM_FAIL; |
938 | 0 | } |
939 | |
|
940 | 0 | if (errorStatus == AAC_DEC_OK) { |
941 | | /* Check error code returned by MPEG-D DRC decoder library: */ |
942 | 0 | switch (uniDrcErr) { |
943 | 0 | case 0: |
944 | 0 | break; |
945 | 0 | case -9998: |
946 | 0 | errorStatus = AAC_DEC_INVALID_HANDLE; |
947 | 0 | break; |
948 | 0 | default: |
949 | 0 | errorStatus = AAC_DEC_SET_PARAM_FAIL; |
950 | 0 | break; |
951 | 0 | } |
952 | 0 | } |
953 | | |
954 | 0 | return (errorStatus); |
955 | 0 | } |
956 | | LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, |
957 | 6.87k | UINT nrOfLayers) { |
958 | 6.87k | AAC_DECODER_INSTANCE *aacDec = NULL; |
959 | 6.87k | HANDLE_TRANSPORTDEC pIn; |
960 | 6.87k | int err = 0; |
961 | 6.87k | int stereoConfigIndex = -1; |
962 | | |
963 | 6.87k | UINT nrOfLayers_min = fMin(nrOfLayers, (UINT)1); |
964 | | |
965 | | /* Allocate transport layer struct. */ |
966 | 6.87k | pIn = transportDec_Open(transportFmt, TP_FLAG_MPEG4, nrOfLayers_min); |
967 | 6.87k | if (pIn == NULL) { |
968 | 0 | return NULL; |
969 | 0 | } |
970 | | |
971 | | /* Allocate AAC decoder core struct. */ |
972 | 6.87k | aacDec = CAacDecoder_Open(transportFmt); |
973 | | |
974 | 6.87k | if (aacDec == NULL) { |
975 | 0 | transportDec_Close(&pIn); |
976 | 0 | goto bail; |
977 | 0 | } |
978 | 6.87k | aacDec->hInput = pIn; |
979 | | |
980 | 6.87k | aacDec->nrOfLayers = nrOfLayers_min; |
981 | | |
982 | | /* Setup channel mapping descriptor. */ |
983 | 6.87k | FDK_chMapDescr_init(&aacDec->mapDescr, NULL, 0, 0); |
984 | | |
985 | | /* Register Config Update callback. */ |
986 | 6.87k | transportDec_RegisterAscCallback(pIn, aacDecoder_ConfigCallback, |
987 | 6.87k | (void *)aacDec); |
988 | | |
989 | | /* Register Free Memory callback. */ |
990 | 6.87k | transportDec_RegisterFreeMemCallback(pIn, aacDecoder_FreeMemCallback, |
991 | 6.87k | (void *)aacDec); |
992 | | |
993 | | /* Register config switch control callback. */ |
994 | 6.87k | transportDec_RegisterCtrlCFGChangeCallback( |
995 | 6.87k | pIn, aacDecoder_CtrlCFGChangeCallback, (void *)aacDec); |
996 | | |
997 | 6.87k | FDKmemclear(&aacDec->qmfDomain, sizeof(FDK_QMF_DOMAIN)); |
998 | | /* open SBR decoder */ |
999 | 6.87k | if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) { |
1000 | 0 | err = -1; |
1001 | 0 | goto bail; |
1002 | 0 | } |
1003 | 6.87k | aacDec->qmfModeUser = NOT_DEFINED; |
1004 | 6.87k | transportDec_RegisterSbrCallback(aacDec->hInput, aacDecoder_SbrCallback, |
1005 | 6.87k | (void *)aacDec->hSbrDecoder); |
1006 | | |
1007 | 6.87k | if (mpegSurroundDecoder_Open( |
1008 | 6.87k | (CMpegSurroundDecoder **)&aacDec->pMpegSurroundDecoder, |
1009 | 6.87k | stereoConfigIndex, &aacDec->qmfDomain)) { |
1010 | 0 | err = -1; |
1011 | 0 | goto bail; |
1012 | 0 | } |
1013 | | /* Set MPEG Surround defaults */ |
1014 | 6.87k | aacDec->mpsEnableUser = 0; |
1015 | 6.87k | aacDec->mpsEnableCurr = 0; |
1016 | 6.87k | aacDec->mpsApplicable = 0; |
1017 | 6.87k | aacDec->mpsOutputMode = (SCHAR)SACDEC_OUT_MODE_NORMAL; |
1018 | 6.87k | transportDec_RegisterSscCallback(pIn, aacDecoder_SscCallback, (void *)aacDec); |
1019 | | |
1020 | 6.87k | { |
1021 | 6.87k | if (FDK_drcDec_Open(&(aacDec->hUniDrcDecoder), DRC_DEC_ALL) != 0) { |
1022 | 0 | err = -1; |
1023 | 0 | goto bail; |
1024 | 0 | } |
1025 | 6.87k | } |
1026 | | |
1027 | 6.87k | transportDec_RegisterUniDrcConfigCallback(pIn, aacDecoder_UniDrcCallback, |
1028 | 6.87k | (void *)aacDec, |
1029 | 6.87k | aacDec->loudnessInfoSetPosition); |
1030 | 6.87k | aacDec->defaultTargetLoudness = (SCHAR)96; |
1031 | | |
1032 | 6.87k | pcmDmx_Open(&aacDec->hPcmUtils); |
1033 | 6.87k | if (aacDec->hPcmUtils == NULL) { |
1034 | 0 | err = -1; |
1035 | 0 | goto bail; |
1036 | 0 | } |
1037 | | |
1038 | 6.87k | aacDec->hLimiter = |
1039 | 6.87k | pcmLimiter_Create(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS, |
1040 | 6.87k | (FIXP_DBL)MAXVAL_DBL, (8), 96000); |
1041 | 6.87k | if (NULL == aacDec->hLimiter) { |
1042 | 0 | err = -1; |
1043 | 0 | goto bail; |
1044 | 0 | } |
1045 | 6.87k | aacDec->limiterEnableUser = (UCHAR)-1; |
1046 | 6.87k | aacDec->limiterEnableCurr = 0; |
1047 | | |
1048 | | /* Assure that all modules have same delay */ |
1049 | 6.87k | if (setConcealMethod(aacDec, |
1050 | 6.87k | CConcealment_GetMethod(&aacDec->concealCommonData))) { |
1051 | 0 | err = -1; |
1052 | 0 | goto bail; |
1053 | 0 | } |
1054 | | |
1055 | 6.87k | bail: |
1056 | 6.87k | if (err == -1) { |
1057 | 0 | aacDecoder_Close(aacDec); |
1058 | 0 | aacDec = NULL; |
1059 | 0 | } |
1060 | 6.87k | return aacDec; |
1061 | 6.87k | } |
1062 | | |
1063 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self, |
1064 | | UCHAR *pBuffer[], |
1065 | | const UINT bufferSize[], |
1066 | 0 | UINT *pBytesValid) { |
1067 | 0 | TRANSPORTDEC_ERROR tpErr; |
1068 | | /* loop counter for layers; if not TT_MP4_RAWPACKETS used as index for only |
1069 | | available layer */ |
1070 | 0 | INT layer = 0; |
1071 | 0 | INT nrOfLayers = self->nrOfLayers; |
1072 | |
|
1073 | 0 | { |
1074 | 0 | for (layer = 0; layer < nrOfLayers; layer++) { |
1075 | 0 | { |
1076 | 0 | tpErr = transportDec_FillData(self->hInput, pBuffer[layer], |
1077 | 0 | bufferSize[layer], &pBytesValid[layer], |
1078 | 0 | layer); |
1079 | 0 | if (tpErr != TRANSPORTDEC_OK) { |
1080 | 0 | return AAC_DEC_UNKNOWN; /* Must be an internal error */ |
1081 | 0 | } |
1082 | 0 | } |
1083 | 0 | } |
1084 | 0 | } |
1085 | | |
1086 | 0 | return AAC_DEC_OK; |
1087 | 0 | } |
1088 | | |
1089 | 0 | static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) { |
1090 | 0 | CAacDecoder_SignalInterruption(self); |
1091 | |
|
1092 | 0 | if (self->hSbrDecoder != NULL) { |
1093 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 1); |
1094 | 0 | } |
1095 | 0 | if (self->mpsEnableUser) { |
1096 | 0 | mpegSurroundDecoder_SetParam( |
1097 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, |
1098 | 0 | SACDEC_BS_INTERRUPTION, 1); |
1099 | 0 | } |
1100 | 0 | } |
1101 | | |
1102 | | static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi, |
1103 | | HANDLE_FDK_BITSTREAM hBs, |
1104 | | INT nBits, |
1105 | 0 | AAC_DECODER_ERROR ErrorStatus) { |
1106 | | /* calculate bit difference (amount of bits moved forward) */ |
1107 | 0 | nBits = nBits - (INT)FDKgetValidBits(hBs); |
1108 | | |
1109 | | /* Note: The amount of bits consumed might become negative when parsing a |
1110 | | bit stream with several sub frames, and we find out at the last sub frame |
1111 | | that the total frame length does not match the sum of sub frame length. |
1112 | | If this happens, the transport decoder might want to rewind to the supposed |
1113 | | ending of the transport frame, and this position might be before the last |
1114 | | access unit beginning. */ |
1115 | | |
1116 | | /* Calc bitrate. */ |
1117 | 0 | if (pSi->frameSize > 0) { |
1118 | | /* bitRate = nBits * sampleRate / frameSize */ |
1119 | 0 | int ratio_e = 0; |
1120 | 0 | FIXP_DBL ratio_m = fDivNorm(pSi->sampleRate, pSi->frameSize, &ratio_e); |
1121 | 0 | pSi->bitRate = (INT)fMultNorm(nBits, DFRACT_BITS - 1, ratio_m, ratio_e, |
1122 | 0 | DFRACT_BITS - 1); |
1123 | 0 | } |
1124 | | |
1125 | | /* bit/byte counters */ |
1126 | 0 | { |
1127 | 0 | INT nBytes; |
1128 | |
|
1129 | 0 | nBytes = nBits >> 3; |
1130 | 0 | pSi->numTotalBytes += nBytes; |
1131 | 0 | if (IS_OUTPUT_VALID(ErrorStatus)) { |
1132 | 0 | pSi->numTotalAccessUnits++; |
1133 | 0 | } |
1134 | 0 | if (IS_DECODE_ERROR(ErrorStatus)) { |
1135 | 0 | pSi->numBadBytes += nBytes; |
1136 | 0 | pSi->numBadAccessUnits++; |
1137 | 0 | } |
1138 | 0 | } |
1139 | 0 | } |
1140 | | |
1141 | 0 | static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) { |
1142 | 0 | INT n; |
1143 | |
|
1144 | 0 | transportDec_GetMissingAccessUnitCount(&n, self->hInput); |
1145 | |
|
1146 | 0 | return n; |
1147 | 0 | } |
1148 | | |
1149 | | LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, |
1150 | | INT_PCM *pTimeData, |
1151 | | const INT timeDataSize, |
1152 | 0 | const UINT flags) { |
1153 | 0 | AAC_DECODER_ERROR ErrorStatus; |
1154 | 0 | INT layer; |
1155 | 0 | INT nBits; |
1156 | 0 | INT timeData2Size; |
1157 | 0 | INT timeData3Size; |
1158 | 0 | INT timeDataHeadroom; |
1159 | 0 | HANDLE_FDK_BITSTREAM hBs; |
1160 | 0 | int fTpInterruption = 0; /* Transport originated interruption detection. */ |
1161 | 0 | int fTpConceal = 0; /* Transport originated concealment. */ |
1162 | 0 | UINT accessUnit = 0; |
1163 | 0 | UINT numAccessUnits = 1; |
1164 | 0 | UINT numPrerollAU = 0; |
1165 | 0 | int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */ |
1166 | 0 | int applyCrossfade = 1; /* flag indicates if flushing was possible */ |
1167 | 0 | PCM_DEC *pTimeData2; |
1168 | 0 | PCM_AAC *pTimeData3; |
1169 | 0 | INT pcmLimiterScale = 0; |
1170 | 0 | INT interleaved = 0; |
1171 | |
|
1172 | 0 | if (self == NULL) { |
1173 | 0 | return AAC_DEC_INVALID_HANDLE; |
1174 | 0 | } |
1175 | | |
1176 | 0 | if (flags & AACDEC_INTR) { |
1177 | 0 | self->streamInfo.numLostAccessUnits = 0; |
1178 | 0 | } |
1179 | 0 | hBs = transportDec_GetBitstream(self->hInput, 0); |
1180 | | |
1181 | | /* Get current bits position for bitrate calculation. */ |
1182 | 0 | nBits = FDKgetValidBits(hBs); |
1183 | |
|
1184 | 0 | if (flags & AACDEC_CLRHIST) { |
1185 | 0 | if (self->flags[0] & AC_USAC) { |
1186 | | /* 1) store AudioSpecificConfig always in AudioSpecificConfig_Parse() */ |
1187 | | /* 2) free memory of dynamic allocated data */ |
1188 | 0 | CSAudioSpecificConfig asc; |
1189 | 0 | transportDec_GetAsc(self->hInput, 0, &asc); |
1190 | 0 | aacDecoder_FreeMemCallback(self, &asc); |
1191 | 0 | self->streamInfo.numChannels = 0; |
1192 | | /* 3) restore AudioSpecificConfig */ |
1193 | 0 | if (asc.configBits <= (TP_USAC_MAX_CONFIG_LEN << 3)) { |
1194 | 0 | transportDec_OutOfBandConfig(self->hInput, asc.config, |
1195 | 0 | (asc.configBits + 7) >> 3, 0); |
1196 | 0 | } |
1197 | 0 | } |
1198 | 0 | } |
1199 | |
|
1200 | 0 | if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || |
1201 | 0 | (self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) || |
1202 | 0 | (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) || |
1203 | 0 | (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND))) { |
1204 | 0 | TRANSPORTDEC_ERROR err; |
1205 | |
|
1206 | 0 | for (layer = 0; layer < self->nrOfLayers; layer++) { |
1207 | 0 | err = transportDec_ReadAccessUnit(self->hInput, layer); |
1208 | 0 | if (err != TRANSPORTDEC_OK) { |
1209 | 0 | switch (err) { |
1210 | 0 | case TRANSPORTDEC_NOT_ENOUGH_BITS: |
1211 | 0 | ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS; |
1212 | 0 | goto bail; |
1213 | 0 | case TRANSPORTDEC_SYNC_ERROR: |
1214 | 0 | self->streamInfo.numLostAccessUnits = |
1215 | 0 | aacDecoder_EstimateNumberOfLostFrames(self); |
1216 | 0 | fTpInterruption = 1; |
1217 | 0 | break; |
1218 | 0 | case TRANSPORTDEC_NEED_TO_RESTART: |
1219 | 0 | ErrorStatus = AAC_DEC_NEED_TO_RESTART; |
1220 | 0 | goto bail; |
1221 | 0 | case TRANSPORTDEC_CRC_ERROR: |
1222 | 0 | fTpConceal = 1; |
1223 | 0 | break; |
1224 | 0 | case TRANSPORTDEC_UNSUPPORTED_FORMAT: |
1225 | 0 | ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; |
1226 | 0 | goto bail; |
1227 | 0 | default: |
1228 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; |
1229 | 0 | goto bail; |
1230 | 0 | } |
1231 | 0 | } |
1232 | 0 | } |
1233 | 0 | } else { |
1234 | 0 | if (self->streamInfo.numLostAccessUnits > 0) { |
1235 | 0 | self->streamInfo.numLostAccessUnits--; |
1236 | 0 | } |
1237 | 0 | } |
1238 | | |
1239 | 0 | self->frameOK = 1; |
1240 | |
|
1241 | 0 | UINT prerollAUOffset[AACDEC_MAX_NUM_PREROLL_AU]; |
1242 | 0 | UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU]; |
1243 | 0 | for (int i = 0; i < AACDEC_MAX_NUM_PREROLL_AU + 1; i++) |
1244 | 0 | self->prerollAULength[i] = 0; |
1245 | |
|
1246 | 0 | INT auStartAnchor; |
1247 | 0 | HANDLE_FDK_BITSTREAM hBsAu; |
1248 | | |
1249 | | /* Process preroll frames and current frame */ |
1250 | 0 | do { |
1251 | 0 | if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && |
1252 | 0 | (self->flushStatus != AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON) && |
1253 | 0 | (accessUnit == 0) && |
1254 | 0 | (self->hasAudioPreRoll || |
1255 | 0 | (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) && |
1256 | 0 | !fTpInterruption && |
1257 | 0 | !fTpConceal /* Bit stream pointer needs to be at the beginning of a |
1258 | | (valid) AU. */ |
1259 | 0 | ) { |
1260 | 0 | ErrorStatus = CAacDecoder_PreRollExtensionPayloadParse( |
1261 | 0 | self, &numPrerollAU, prerollAUOffset, prerollAULength); |
1262 | |
|
1263 | 0 | if (ErrorStatus != AAC_DEC_OK) { |
1264 | 0 | switch (ErrorStatus) { |
1265 | 0 | case AAC_DEC_NOT_ENOUGH_BITS: |
1266 | 0 | goto bail; |
1267 | 0 | case AAC_DEC_PARSE_ERROR: |
1268 | 0 | self->frameOK = 0; |
1269 | 0 | break; |
1270 | 0 | default: |
1271 | 0 | break; |
1272 | 0 | } |
1273 | 0 | } |
1274 | | |
1275 | 0 | numAccessUnits += numPrerollAU; |
1276 | 0 | } |
1277 | | |
1278 | 0 | hBsAu = transportDec_GetBitstream(self->hInput, 0); |
1279 | 0 | auStartAnchor = (INT)FDKgetValidBits(hBsAu); |
1280 | |
|
1281 | 0 | self->accessUnit = accessUnit; |
1282 | 0 | if (accessUnit < numPrerollAU) { |
1283 | 0 | FDKpushFor(hBsAu, prerollAUOffset[accessUnit]); |
1284 | 0 | } |
1285 | | |
1286 | | /* Signal bit stream interruption to other modules if required. */ |
1287 | 0 | if (fTpInterruption || ((flags & AACDEC_INTR) && (accessUnit == 0))) { |
1288 | 0 | aacDecoder_SignalInterruption(self); |
1289 | 0 | if (!((flags & AACDEC_INTR) && (accessUnit == 0))) { |
1290 | 0 | ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR; |
1291 | 0 | goto bail; |
1292 | 0 | } |
1293 | 0 | } |
1294 | | |
1295 | | /* Clearing core data will be done in CAacDecoder_DecodeFrame() below. |
1296 | | Tell other modules to clear states if required. */ |
1297 | 0 | if (flags & AACDEC_CLRHIST) { |
1298 | 0 | if (!(self->flags[0] & AC_USAC)) { |
1299 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, 1); |
1300 | 0 | mpegSurroundDecoder_SetParam( |
1301 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, |
1302 | 0 | SACDEC_CLEAR_HISTORY, 1); |
1303 | 0 | if (FDK_QmfDomain_ClearPersistentMemory(&self->qmfDomain) != 0) { |
1304 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; |
1305 | 0 | goto bail; |
1306 | 0 | } |
1307 | 0 | } |
1308 | 0 | } |
1309 | | |
1310 | | /* Empty bit buffer in case of flush request. */ |
1311 | 0 | if (flags & AACDEC_FLUSH && !(flags & AACDEC_CONCEAL)) { |
1312 | 0 | if (!self->flushStatus) { |
1313 | 0 | transportDec_SetParam(self->hInput, TPDEC_PARAM_RESET, 1); |
1314 | 0 | self->streamInfo.numLostAccessUnits = 0; |
1315 | 0 | self->streamInfo.numBadBytes = 0; |
1316 | 0 | self->streamInfo.numTotalBytes = 0; |
1317 | 0 | } |
1318 | 0 | } |
1319 | | /* Reset the output delay field. The modules will add their figures one |
1320 | | * after another. */ |
1321 | 0 | self->streamInfo.outputDelay = 0; |
1322 | |
|
1323 | 0 | if (self->limiterEnableUser == (UCHAR)-2) { |
1324 | | /* Enable limiter only for RSVD60. */ |
1325 | 0 | self->limiterEnableCurr = (self->flags[0] & AC_RSV603DA) ? 1 : 0; |
1326 | 0 | } else if (self->limiterEnableUser == (UCHAR)-1) { |
1327 | | /* Enable limiter for all non-lowdelay AOT's. */ |
1328 | 0 | self->limiterEnableCurr = (self->flags[0] & (AC_LD | AC_ELD)) ? 0 : 1; |
1329 | 0 | } else { |
1330 | | /* Use limiter configuration as requested. */ |
1331 | 0 | self->limiterEnableCurr = self->limiterEnableUser; |
1332 | 0 | } |
1333 | | |
1334 | | /* reset DRC level normalization gain on a per frame basis */ |
1335 | 0 | self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE; |
1336 | |
|
1337 | 0 | pTimeData2 = self->pTimeData2; |
1338 | 0 | timeData2Size = self->timeData2Size / sizeof(PCM_DEC); |
1339 | 0 | pTimeData3 = (PCM_AAC *)self->pTimeData2; |
1340 | 0 | timeData3Size = self->timeData2Size / sizeof(PCM_AAC); |
1341 | |
|
1342 | 0 | ErrorStatus = CAacDecoder_DecodeFrame( |
1343 | 0 | self, |
1344 | 0 | flags | (fTpConceal ? AACDEC_CONCEAL : 0) | |
1345 | 0 | ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH |
1346 | 0 | : 0), |
1347 | 0 | pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0); |
1348 | |
|
1349 | 0 | timeDataHeadroom = self->aacOutDataHeadroom; |
1350 | | |
1351 | | /* if flushing for USAC DASH IPF was not possible go on with decoding |
1352 | | * preroll */ |
1353 | 0 | if ((self->flags[0] & AC_USAC) && |
1354 | 0 | (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) && |
1355 | 0 | !(flags & AACDEC_CONCEAL) && (ErrorStatus != AAC_DEC_OK)) { |
1356 | 0 | applyCrossfade = 0; |
1357 | 0 | } else /* USAC DASH IPF flushing possible begin */ |
1358 | 0 | { |
1359 | 0 | if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || fTpConceal || |
1360 | 0 | self->flushStatus) && |
1361 | 0 | (!(IS_OUTPUT_VALID(ErrorStatus)) || !(accessUnit < numPrerollAU))) { |
1362 | 0 | TRANSPORTDEC_ERROR tpErr; |
1363 | 0 | tpErr = transportDec_EndAccessUnit(self->hInput); |
1364 | 0 | if (tpErr != TRANSPORTDEC_OK) { |
1365 | 0 | self->frameOK = 0; |
1366 | 0 | } |
1367 | 0 | } else { /* while preroll processing later possibly an error in the |
1368 | | renderer part occurrs */ |
1369 | 0 | if (IS_OUTPUT_VALID(ErrorStatus)) { |
1370 | 0 | fEndAuNotAdjusted = 1; |
1371 | 0 | } |
1372 | 0 | } |
1373 | | |
1374 | | /* If the current pTimeData2 does not contain a valid signal, there |
1375 | | * nothing else we can do, so bail. */ |
1376 | 0 | if (!IS_OUTPUT_VALID(ErrorStatus)) { |
1377 | 0 | goto bail; |
1378 | 0 | } |
1379 | | |
1380 | 0 | { |
1381 | 0 | self->streamInfo.sampleRate = self->streamInfo.aacSampleRate; |
1382 | 0 | self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame; |
1383 | 0 | } |
1384 | |
|
1385 | 0 | self->streamInfo.numChannels = self->streamInfo.aacNumChannels; |
1386 | |
|
1387 | 0 | { |
1388 | 0 | FDK_Delay_Apply( |
1389 | 0 | &self->usacResidualDelay, |
1390 | 0 | pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0, |
1391 | 0 | self->streamInfo.frameSize, 0); |
1392 | 0 | } |
1393 | | |
1394 | | /* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode |
1395 | | if decoder is unable to decode with user defined qmfMode */ |
1396 | 0 | if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD))) { |
1397 | 0 | self->mpsEnableCurr = |
1398 | 0 | (self->mpsEnableUser && |
1399 | 0 | isSupportedMpsConfig(self->streamInfo.aot, |
1400 | 0 | self->streamInfo.numChannels, |
1401 | 0 | (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0)); |
1402 | 0 | } |
1403 | |
|
1404 | 0 | if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig && |
1405 | 0 | self->mpsEnableCurr) { |
1406 | | /* if not done yet, allocate full MPEG Surround decoder instance */ |
1407 | 0 | if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable( |
1408 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) == |
1409 | 0 | SAC_INSTANCE_NOT_FULL_AVAILABLE) { |
1410 | 0 | if (mpegSurroundDecoder_Open( |
1411 | 0 | (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1, |
1412 | 0 | &self->qmfDomain)) { |
1413 | 0 | return AAC_DEC_OUT_OF_MEMORY; |
1414 | 0 | } |
1415 | 0 | } |
1416 | 0 | } |
1417 | | |
1418 | 0 | CAacDecoder_SyncQmfMode(self); |
1419 | |
|
1420 | 0 | if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig && |
1421 | 0 | self->mpsEnableCurr) { |
1422 | 0 | SAC_INPUT_CONFIG sac_interface = (self->sbrEnabled && self->hSbrDecoder) |
1423 | 0 | ? SAC_INTERFACE_QMF |
1424 | 0 | : SAC_INTERFACE_TIME; |
1425 | | /* needs to be done before first SBR apply. */ |
1426 | 0 | mpegSurroundDecoder_ConfigureQmfDomain( |
1427 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface, |
1428 | 0 | (UINT)self->streamInfo.aacSampleRate, self->streamInfo.aot); |
1429 | 0 | if (self->qmfDomain.globalConf.nBandsAnalysis_requested > 0) { |
1430 | 0 | self->qmfDomain.globalConf.nQmfTimeSlots_requested = |
1431 | 0 | self->streamInfo.aacSamplesPerFrame / |
1432 | 0 | self->qmfDomain.globalConf.nBandsAnalysis_requested; |
1433 | 0 | } else { |
1434 | 0 | self->qmfDomain.globalConf.nQmfTimeSlots_requested = 0; |
1435 | 0 | } |
1436 | 0 | } |
1437 | |
|
1438 | 0 | switch (FDK_QmfDomain_Configure(&self->qmfDomain)) { |
1439 | 0 | default: |
1440 | 0 | case QMF_DOMAIN_INIT_ERROR: |
1441 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; |
1442 | 0 | goto bail; |
1443 | 0 | case QMF_DOMAIN_OUT_OF_MEMORY: |
1444 | 0 | ErrorStatus = AAC_DEC_OUT_OF_MEMORY; |
1445 | 0 | goto bail; |
1446 | 0 | case QMF_DOMAIN_OK: |
1447 | 0 | break; |
1448 | 0 | } |
1449 | | |
1450 | | /* sbr decoder */ |
1451 | | |
1452 | 0 | if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) || |
1453 | 0 | self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState > |
1454 | 0 | ConcealState_FadeIn) { |
1455 | 0 | self->frameOK = 0; /* if an error has occured do concealment in the SBR |
1456 | | decoder too */ |
1457 | 0 | } |
1458 | |
|
1459 | 0 | if (self->sbrEnabled && (!(self->flags[0] & AC_USAC_SCFGI3))) { |
1460 | 0 | SBR_ERROR sbrError = SBRDEC_OK; |
1461 | 0 | int chIdx, numCoreChannel = self->streamInfo.numChannels; |
1462 | | |
1463 | | /* set params */ |
1464 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, |
1465 | 0 | self->sbrParams.bsDelay); |
1466 | 0 | sbrDecoder_SetParam( |
1467 | 0 | self->hSbrDecoder, SBR_FLUSH_DATA, |
1468 | 0 | (flags & AACDEC_FLUSH) | |
1469 | 0 | ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH |
1470 | 0 | : 0)); |
1471 | |
|
1472 | 0 | if (self->streamInfo.aot == AOT_ER_AAC_ELD) { |
1473 | | /* Configure QMF */ |
1474 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_LD_QMF_TIME_ALIGN, |
1475 | 0 | (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0); |
1476 | 0 | } |
1477 | |
|
1478 | 0 | { |
1479 | 0 | PCMDMX_ERROR dmxErr; |
1480 | 0 | INT maxOutCh = 0; |
1481 | |
|
1482 | 0 | dmxErr = pcmDmx_GetParam(self->hPcmUtils, |
1483 | 0 | MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh); |
1484 | 0 | if ((dmxErr == PCMDMX_OK) && (maxOutCh == 1)) { |
1485 | | /* Disable PS processing if we have to create a mono output signal. |
1486 | | */ |
1487 | 0 | self->psPossible = 0; |
1488 | 0 | } |
1489 | 0 | } |
1490 | |
|
1491 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, |
1492 | 0 | (self->mpsEnableCurr) ? 2 : 0); |
1493 | |
|
1494 | 0 | PCM_AAC *input; |
1495 | 0 | input = (PCM_AAC *)self->workBufferCore2; |
1496 | 0 | FDKmemcpy(input, pTimeData3, |
1497 | 0 | sizeof(PCM_AAC) * (self->streamInfo.numChannels) * |
1498 | 0 | (self->streamInfo.frameSize)); |
1499 | | |
1500 | | /* apply SBR processing */ |
1501 | 0 | sbrError = sbrDecoder_Apply( |
1502 | 0 | self->hSbrDecoder, input, pTimeData3, timeData3Size, |
1503 | 0 | &self->streamInfo.numChannels, &self->streamInfo.sampleRate, |
1504 | 0 | &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible, |
1505 | 0 | self->aacOutDataHeadroom, &timeDataHeadroom); |
1506 | |
|
1507 | 0 | if (sbrError == SBRDEC_OK) { |
1508 | | /* Update data in streaminfo structure. Assume that the SBR upsampling |
1509 | | factor is either 1, 2, 8/3 or 4. Maximum upsampling factor is 4 |
1510 | | (CELP+SBR or USAC 4:1 SBR) */ |
1511 | 0 | self->flags[0] |= AC_SBR_PRESENT; |
1512 | 0 | if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) { |
1513 | 0 | if (self->streamInfo.aacSampleRate >> 2 == |
1514 | 0 | self->streamInfo.sampleRate) { |
1515 | 0 | self->streamInfo.frameSize = |
1516 | 0 | self->streamInfo.aacSamplesPerFrame >> 2; |
1517 | 0 | self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 2; |
1518 | 0 | } else if (self->streamInfo.aacSampleRate >> 1 == |
1519 | 0 | self->streamInfo.sampleRate) { |
1520 | 0 | self->streamInfo.frameSize = |
1521 | 0 | self->streamInfo.aacSamplesPerFrame >> 1; |
1522 | 0 | self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 1; |
1523 | 0 | } else if (self->streamInfo.aacSampleRate << 1 == |
1524 | 0 | self->streamInfo.sampleRate) { |
1525 | 0 | self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame |
1526 | 0 | << 1; |
1527 | 0 | self->streamInfo.outputDelay = self->streamInfo.outputDelay << 1; |
1528 | 0 | } else if (self->streamInfo.aacSampleRate << 2 == |
1529 | 0 | self->streamInfo.sampleRate) { |
1530 | 0 | self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame |
1531 | 0 | << 2; |
1532 | 0 | self->streamInfo.outputDelay = self->streamInfo.outputDelay << 2; |
1533 | 0 | } else if (self->streamInfo.frameSize == 768) { |
1534 | 0 | self->streamInfo.frameSize = |
1535 | 0 | (self->streamInfo.aacSamplesPerFrame << 3) / 3; |
1536 | 0 | self->streamInfo.outputDelay = |
1537 | 0 | (self->streamInfo.outputDelay << 3) / 3; |
1538 | 0 | } else { |
1539 | 0 | ErrorStatus = AAC_DEC_SET_PARAM_FAIL; |
1540 | 0 | goto bail; |
1541 | 0 | } |
1542 | 0 | } else { |
1543 | 0 | self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame; |
1544 | 0 | } |
1545 | 0 | self->streamInfo.outputDelay += |
1546 | 0 | sbrDecoder_GetDelay(self->hSbrDecoder); |
1547 | |
|
1548 | 0 | if (self->psPossible) { |
1549 | 0 | self->flags[0] |= AC_PS_PRESENT; |
1550 | 0 | } |
1551 | 0 | for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; |
1552 | 0 | chIdx += 1) { |
1553 | 0 | self->channelType[chIdx] = ACT_FRONT; |
1554 | 0 | self->channelIndices[chIdx] = chIdx; |
1555 | 0 | } |
1556 | 0 | } |
1557 | 0 | if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) { |
1558 | 0 | ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; |
1559 | 0 | goto bail; |
1560 | 0 | } |
1561 | 0 | } |
1562 | | |
1563 | 0 | if (self->mpsEnableCurr) { |
1564 | 0 | int err, sac_interface, nChannels, frameSize; |
1565 | |
|
1566 | 0 | nChannels = self->streamInfo.numChannels; |
1567 | 0 | frameSize = self->streamInfo.frameSize; |
1568 | 0 | sac_interface = SAC_INTERFACE_TIME; |
1569 | |
|
1570 | 0 | if (self->sbrEnabled && self->hSbrDecoder) |
1571 | 0 | sac_interface = SAC_INTERFACE_QMF; |
1572 | 0 | if (self->streamInfo.aot == AOT_USAC) { |
1573 | 0 | if (self->flags[0] & AC_USAC_SCFGI3) { |
1574 | 0 | sac_interface = SAC_INTERFACE_TIME; |
1575 | 0 | } |
1576 | 0 | } |
1577 | 0 | err = mpegSurroundDecoder_SetParam( |
1578 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, |
1579 | 0 | SACDEC_INTERFACE, sac_interface); |
1580 | |
|
1581 | 0 | if (err == 0) { |
1582 | 0 | err = mpegSurroundDecoder_Apply( |
1583 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, |
1584 | 0 | (PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size, |
1585 | 0 | self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize, |
1586 | 0 | self->streamInfo.sampleRate, self->streamInfo.aot, |
1587 | 0 | self->channelType, self->channelIndices, &self->mapDescr, |
1588 | 0 | self->aacOutDataHeadroom, &timeDataHeadroom); |
1589 | 0 | } |
1590 | |
|
1591 | 0 | if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) { |
1592 | 0 | ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; |
1593 | 0 | goto bail; |
1594 | 0 | } |
1595 | 0 | if (err == 0) { |
1596 | | /* Update output parameter */ |
1597 | 0 | self->streamInfo.numChannels = nChannels; |
1598 | 0 | self->streamInfo.frameSize = frameSize; |
1599 | 0 | self->streamInfo.outputDelay += mpegSurroundDecoder_GetDelay( |
1600 | 0 | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder); |
1601 | | /* Save current parameter for possible concealment of next frame */ |
1602 | 0 | self->mpsOutChannelsLast = nChannels; |
1603 | 0 | self->mpsFrameSizeLast = frameSize; |
1604 | 0 | } else if ((self->mpsOutChannelsLast > 0) && |
1605 | 0 | (self->mpsFrameSizeLast > 0)) { |
1606 | | /* Restore parameters of last frame ... */ |
1607 | 0 | self->streamInfo.numChannels = self->mpsOutChannelsLast; |
1608 | 0 | self->streamInfo.frameSize = self->mpsFrameSizeLast; |
1609 | | /* ... and clear output buffer so that potentially corrupted data does |
1610 | | * not reach the framework. */ |
1611 | 0 | FDKmemclear(pTimeData3, self->mpsOutChannelsLast * |
1612 | 0 | self->mpsFrameSizeLast * sizeof(PCM_AAC)); |
1613 | | /* Additionally proclaim that this frame had errors during decoding. |
1614 | | */ |
1615 | 0 | ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; |
1616 | 0 | } else { |
1617 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; /* no output */ |
1618 | 0 | } |
1619 | 0 | } |
1620 | | |
1621 | | /* SBR decoder for Unified Stereo Config (stereoConfigIndex == 3) */ |
1622 | | |
1623 | 0 | if (self->sbrEnabled && (self->flags[0] & AC_USAC_SCFGI3)) { |
1624 | 0 | SBR_ERROR sbrError = SBRDEC_OK; |
1625 | | |
1626 | | /* set params */ |
1627 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, |
1628 | 0 | self->sbrParams.bsDelay); |
1629 | 0 | sbrDecoder_SetParam( |
1630 | 0 | self->hSbrDecoder, SBR_FLUSH_DATA, |
1631 | 0 | (flags & AACDEC_FLUSH) | |
1632 | 0 | ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH |
1633 | 0 | : 0)); |
1634 | |
|
1635 | 0 | sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1); |
1636 | | |
1637 | | /* apply SBR processing */ |
1638 | 0 | sbrError = sbrDecoder_Apply( |
1639 | 0 | self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size, |
1640 | 0 | &self->streamInfo.numChannels, &self->streamInfo.sampleRate, |
1641 | 0 | &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible, |
1642 | 0 | self->aacOutDataHeadroom, &timeDataHeadroom); |
1643 | |
|
1644 | 0 | if (sbrError == SBRDEC_OK) { |
1645 | | /* Update data in streaminfo structure. Assume that the SBR upsampling |
1646 | | * factor is either 1,2 or 4 */ |
1647 | 0 | self->flags[0] |= AC_SBR_PRESENT; |
1648 | 0 | if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) { |
1649 | 0 | if (self->streamInfo.frameSize == 768) { |
1650 | 0 | self->streamInfo.frameSize = |
1651 | 0 | (self->streamInfo.aacSamplesPerFrame * 8) / 3; |
1652 | 0 | } else if (self->streamInfo.aacSampleRate << 2 == |
1653 | 0 | self->streamInfo.sampleRate) { |
1654 | 0 | self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame |
1655 | 0 | << 2; |
1656 | 0 | } else { |
1657 | 0 | self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame |
1658 | 0 | << 1; |
1659 | 0 | } |
1660 | 0 | } |
1661 | |
|
1662 | 0 | self->flags[0] &= ~AC_PS_PRESENT; |
1663 | 0 | } |
1664 | 0 | if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) { |
1665 | 0 | ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; |
1666 | 0 | goto bail; |
1667 | 0 | } |
1668 | 0 | } |
1669 | | |
1670 | 0 | { |
1671 | 0 | if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) { |
1672 | 0 | for (int i = ((self->streamInfo.frameSize * |
1673 | 0 | self->streamInfo.numChannels) - |
1674 | 0 | 1); |
1675 | 0 | i >= 0; i--) { |
1676 | 0 | pTimeData2[i] = |
1677 | 0 | (PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom); |
1678 | 0 | } |
1679 | 0 | } |
1680 | 0 | } |
1681 | |
|
1682 | 0 | { |
1683 | 0 | if ((FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) && |
1684 | 0 | (self->flags[0] & AC_USAC)) { |
1685 | | /* Apply DRC gains*/ |
1686 | 0 | int ch, drcDelay = 0; |
1687 | 0 | int needsDeinterleaving = 0; |
1688 | 0 | FIXP_DBL *drcWorkBuffer = NULL; |
1689 | 0 | FIXP_DBL channelGain[(8)]; |
1690 | 0 | int reverseInChannelMap[(8)]; |
1691 | 0 | int reverseOutChannelMap[(8)]; |
1692 | 0 | FDKmemclear(channelGain, sizeof(channelGain)); |
1693 | 0 | for (ch = 0; ch < (8); ch++) { |
1694 | 0 | reverseInChannelMap[ch] = ch; |
1695 | 0 | reverseOutChannelMap[ch] = ch; |
1696 | 0 | } |
1697 | | |
1698 | | /* Update sampleRate and frameSize. This may be necessary in case of |
1699 | | * implicit SBR signaling */ |
1700 | 0 | FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_SAMPLE_RATE, |
1701 | 0 | self->streamInfo.sampleRate); |
1702 | 0 | FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_FRAME_SIZE, |
1703 | 0 | self->streamInfo.frameSize); |
1704 | | |
1705 | | /* If SBR and/or MPS is active, the DRC gains are aligned to the QMF |
1706 | | domain signal before the QMF synthesis. Therefore the DRC gains |
1707 | | need to be delayed by the QMF synthesis delay. */ |
1708 | 0 | if (self->sbrEnabled) drcDelay = 257; |
1709 | 0 | if (self->mpsEnableCurr) drcDelay = 257; |
1710 | | /* Take into account concealment delay */ |
1711 | 0 | drcDelay += CConcealment_GetDelay(&self->concealCommonData) * |
1712 | 0 | self->streamInfo.frameSize; |
1713 | | |
1714 | | /* The output of SBR and MPS is interleaved. Deinterleaving may be |
1715 | | * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved |
1716 | | * audio only. */ |
1717 | 0 | if ((self->streamInfo.numChannels > 1) && |
1718 | 0 | (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) { |
1719 | | /* interleaving/deinterleaving is performed on upper part of |
1720 | | * pTimeData2. Check if this buffer is large enough. */ |
1721 | 0 | if (timeData2Size < (INT)(2 * self->streamInfo.numChannels * |
1722 | 0 | self->streamInfo.frameSize)) { |
1723 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; |
1724 | 0 | goto bail; |
1725 | 0 | } |
1726 | 0 | needsDeinterleaving = 1; |
1727 | 0 | drcWorkBuffer = |
1728 | 0 | (FIXP_DBL *)pTimeData2 + |
1729 | 0 | self->streamInfo.numChannels * self->streamInfo.frameSize; |
1730 | 0 | FDK_deinterleave( |
1731 | 0 | pTimeData2, drcWorkBuffer, self->streamInfo.numChannels, |
1732 | 0 | self->streamInfo.frameSize, self->streamInfo.frameSize); |
1733 | 0 | } else { |
1734 | 0 | drcWorkBuffer = pTimeData2; |
1735 | 0 | } |
1736 | | |
1737 | | /* prepare Loudness Normalisation gain */ |
1738 | 0 | FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_TARGET_LOUDNESS, |
1739 | 0 | (INT)-self->defaultTargetLoudness * |
1740 | 0 | FL2FXCONST_DBL(1.0f / (float)(1 << 9))); |
1741 | 0 | FDK_drcDec_SetChannelGains(self->hUniDrcDecoder, |
1742 | 0 | self->streamInfo.numChannels, |
1743 | 0 | self->streamInfo.frameSize, channelGain, |
1744 | 0 | drcWorkBuffer, self->streamInfo.frameSize); |
1745 | 0 | FDK_drcDec_Preprocess(self->hUniDrcDecoder); |
1746 | | |
1747 | | /* apply DRC1 gain sequence */ |
1748 | 0 | FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1, |
1749 | 0 | 0, 0, self->streamInfo.numChannels, |
1750 | 0 | drcWorkBuffer, self->streamInfo.frameSize); |
1751 | | /* apply downmix */ |
1752 | 0 | FDK_drcDec_ApplyDownmix( |
1753 | 0 | self->hUniDrcDecoder, reverseInChannelMap, reverseOutChannelMap, |
1754 | 0 | drcWorkBuffer, |
1755 | 0 | &self->streamInfo.numChannels); /* self->streamInfo.numChannels |
1756 | | may change here */ |
1757 | | /* apply DRC2/3 gain sequence */ |
1758 | 0 | FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, |
1759 | 0 | DRC_DEC_DRC2_DRC3, 0, 0, |
1760 | 0 | self->streamInfo.numChannels, drcWorkBuffer, |
1761 | 0 | self->streamInfo.frameSize); |
1762 | |
|
1763 | 0 | if (needsDeinterleaving) { |
1764 | 0 | FDK_interleave( |
1765 | 0 | drcWorkBuffer, pTimeData2, self->streamInfo.numChannels, |
1766 | 0 | self->streamInfo.frameSize, self->streamInfo.frameSize); |
1767 | 0 | } |
1768 | 0 | } |
1769 | 0 | } |
1770 | 0 | if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) { |
1771 | | /* return output loudness information for MPEG-D DRC */ |
1772 | 0 | LONG outputLoudness = |
1773 | 0 | FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS); |
1774 | 0 | if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) { |
1775 | | /* no valid MPEG-D DRC loudness value contained */ |
1776 | 0 | self->streamInfo.outputLoudness = -1; |
1777 | 0 | } else { |
1778 | 0 | if (outputLoudness > 0) { |
1779 | | /* positive output loudness values (very unusual) are limited to 0 |
1780 | | * dB */ |
1781 | 0 | self->streamInfo.outputLoudness = 0; |
1782 | 0 | } else { |
1783 | 0 | self->streamInfo.outputLoudness = |
1784 | 0 | -(INT)outputLoudness >> |
1785 | 0 | 22; /* negate and scale from e = 7 to e = (31-2) */ |
1786 | 0 | } |
1787 | 0 | } |
1788 | 0 | } else { |
1789 | | /* return output loudness information for MPEG-4 DRC */ |
1790 | 0 | if (self->streamInfo.drcProgRefLev < |
1791 | 0 | 0) { /* no MPEG-4 DRC loudness metadata contained */ |
1792 | 0 | self->streamInfo.outputLoudness = -1; |
1793 | 0 | } else { |
1794 | 0 | if (self->defaultTargetLoudness < |
1795 | 0 | 0) { /* loudness normalization is off */ |
1796 | 0 | self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev; |
1797 | 0 | } else { |
1798 | 0 | self->streamInfo.outputLoudness = self->defaultTargetLoudness; |
1799 | 0 | } |
1800 | 0 | } |
1801 | 0 | } |
1802 | |
|
1803 | 0 | if (self->streamInfo.extAot != AOT_AAC_SLS) { |
1804 | 0 | interleaved = 0; |
1805 | 0 | interleaved |= (self->sbrEnabled) ? 1 : 0; |
1806 | 0 | interleaved |= (self->mpsEnableCurr) ? 1 : 0; |
1807 | 0 | PCMDMX_ERROR dmxErr = PCMDMX_OK; |
1808 | 0 | if ((flags & AACDEC_INTR) && (accessUnit == 0)) { |
1809 | | /* delete data from the past (e.g. mixdown coeficients) */ |
1810 | 0 | pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA); |
1811 | 0 | } |
1812 | 0 | if (flags & (AACDEC_CLRHIST)) { |
1813 | 0 | if (!(self->flags[0] & AC_USAC)) { |
1814 | | /* delete data from the past (e.g. mixdown coeficients) */ |
1815 | 0 | pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA); |
1816 | 0 | } |
1817 | 0 | } |
1818 | | |
1819 | | /* do PCM post processing */ |
1820 | 0 | dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size, |
1821 | 0 | self->streamInfo.frameSize, |
1822 | 0 | &self->streamInfo.numChannels, interleaved, |
1823 | 0 | self->channelType, self->channelIndices, |
1824 | 0 | &self->mapDescr, &pcmLimiterScale); |
1825 | 0 | if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) { |
1826 | 0 | ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; |
1827 | 0 | goto bail; |
1828 | 0 | } |
1829 | 0 | if ((ErrorStatus == AAC_DEC_OK) && (dmxErr == PCMDMX_INVALID_MODE)) { |
1830 | | /* Announce the framework that the current combination of channel |
1831 | | * configuration and downmix settings are not know to produce a |
1832 | | * predictable behavior and thus maybe produce strange output. */ |
1833 | 0 | ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; |
1834 | 0 | } |
1835 | 0 | } |
1836 | | |
1837 | 0 | if (self->flags[0] & AC_USAC) { |
1838 | 0 | if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON && |
1839 | 0 | !(flags & AACDEC_CONCEAL)) { |
1840 | 0 | CAacDecoder_PrepareCrossFade(pTimeData2, self->pTimeDataFlush, |
1841 | 0 | self->streamInfo.numChannels, |
1842 | 0 | self->streamInfo.frameSize, interleaved); |
1843 | 0 | } |
1844 | | |
1845 | | /* prepare crossfade buffer for fade in */ |
1846 | 0 | if (!applyCrossfade && |
1847 | 0 | (self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) && |
1848 | 0 | !(flags & AACDEC_CONCEAL)) { |
1849 | 0 | for (int ch = 0; ch < self->streamInfo.numChannels; ch++) { |
1850 | 0 | for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) { |
1851 | 0 | self->pTimeDataFlush[ch][i] = (PCM_DEC)0; |
1852 | 0 | } |
1853 | 0 | } |
1854 | 0 | applyCrossfade = 1; |
1855 | 0 | } |
1856 | |
|
1857 | 0 | if (applyCrossfade && |
1858 | 0 | (self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) && |
1859 | 0 | !(accessUnit < numPrerollAU) && |
1860 | 0 | (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) { |
1861 | 0 | CAacDecoder_ApplyCrossFade(pTimeData2, self->pTimeDataFlush, |
1862 | 0 | self->streamInfo.numChannels, |
1863 | 0 | self->streamInfo.frameSize, interleaved); |
1864 | 0 | self->applyCrossfade = |
1865 | 0 | AACDEC_CROSSFADE_BITMASK_OFF; /* disable cross-fade between frames |
1866 | | at nect config change */ |
1867 | 0 | } |
1868 | 0 | } |
1869 | | |
1870 | | /* Signal interruption to take effect in next frame. */ |
1871 | 0 | if ((flags & AACDEC_FLUSH || self->flushStatus) && |
1872 | 0 | !(flags & AACDEC_CONCEAL)) { |
1873 | 0 | aacDecoder_SignalInterruption(self); |
1874 | 0 | } |
1875 | | |
1876 | | /* Update externally visible copy of flags */ |
1877 | 0 | self->streamInfo.flags = self->flags[0]; |
1878 | |
|
1879 | 0 | } /* USAC DASH IPF flushing possible end */ |
1880 | 0 | if (accessUnit < numPrerollAU) { |
1881 | 0 | FDKpushBack(hBsAu, auStartAnchor - (INT)FDKgetValidBits(hBsAu)); |
1882 | 0 | } else { |
1883 | 0 | if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) || |
1884 | 0 | (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) || |
1885 | 0 | (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) { |
1886 | 0 | self->buildUpCnt--; |
1887 | |
|
1888 | 0 | if (self->buildUpCnt < 0) { |
1889 | 0 | self->buildUpStatus = 0; |
1890 | 0 | } |
1891 | 0 | } |
1892 | |
|
1893 | 0 | if (self->flags[0] & AC_USAC) { |
1894 | 0 | if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON && |
1895 | 0 | !(flags & AACDEC_CONCEAL)) { |
1896 | 0 | self->streamInfo.frameSize = 0; |
1897 | 0 | } |
1898 | 0 | } |
1899 | 0 | } |
1900 | |
|
1901 | 0 | if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) { |
1902 | 0 | accessUnit++; |
1903 | 0 | } |
1904 | 0 | } while ((accessUnit < numAccessUnits) || |
1905 | 0 | ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) && |
1906 | 0 | !(flags & AACDEC_CONCEAL))); |
1907 | | |
1908 | 0 | if (self->streamInfo.extAot != AOT_AAC_SLS) { |
1909 | 0 | pcmLimiterScale += PCM_OUT_HEADROOM; |
1910 | |
|
1911 | 0 | if (flags & AACDEC_CLRHIST) { |
1912 | 0 | if (!(self->flags[0] & AC_USAC)) { |
1913 | | /* Reset DRC data */ |
1914 | 0 | aacDecoder_drcReset(self->hDrcInfo); |
1915 | | /* Delete the delayed signal. */ |
1916 | 0 | pcmLimiter_Reset(self->hLimiter); |
1917 | 0 | } |
1918 | 0 | } |
1919 | | |
1920 | | /* Set applyExtGain if DRC processing is enabled and if progRefLevelPresent |
1921 | | is present for the first time. Consequences: The headroom of the output |
1922 | | signal can be set to AACDEC_DRC_GAIN_SCALING only for audio formats which |
1923 | | support legacy DRC Level Normalization. For all other audio formats the |
1924 | | headroom of the output signal is set to PCM_OUT_HEADROOM. */ |
1925 | 0 | if (self->hDrcInfo->enable && (self->hDrcInfo->progRefLevelPresent == 1)) { |
1926 | 0 | self->hDrcInfo->applyExtGain |= 1; |
1927 | 0 | } |
1928 | | |
1929 | | /* Check whether time data buffer is large enough. */ |
1930 | 0 | if (timeDataSize < |
1931 | 0 | (self->streamInfo.numChannels * self->streamInfo.frameSize)) { |
1932 | 0 | ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; |
1933 | 0 | goto bail; |
1934 | 0 | } |
1935 | | |
1936 | 0 | if (self->limiterEnableCurr) { |
1937 | | /* use workBufferCore2 buffer for interleaving */ |
1938 | 0 | PCM_LIM *pInterleaveBuffer; |
1939 | 0 | int blockLength = self->streamInfo.frameSize; |
1940 | | |
1941 | | /* Set actual signal parameters */ |
1942 | 0 | pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels); |
1943 | 0 | pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate); |
1944 | |
|
1945 | 0 | if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || |
1946 | 0 | (self->mpsEnableCurr)) { |
1947 | 0 | pInterleaveBuffer = (PCM_LIM *)pTimeData2; |
1948 | 0 | } else { |
1949 | 0 | pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2; |
1950 | | |
1951 | | /* applyLimiter requests for interleaved data */ |
1952 | | /* Interleave ouput buffer */ |
1953 | 0 | FDK_interleave(pTimeData2, pInterleaveBuffer, |
1954 | 0 | self->streamInfo.numChannels, blockLength, |
1955 | 0 | self->streamInfo.frameSize); |
1956 | 0 | } |
1957 | |
|
1958 | 0 | FIXP_DBL *pGainPerSample = NULL; |
1959 | |
|
1960 | 0 | if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { |
1961 | 0 | pGainPerSample = self->workBufferCore1; |
1962 | |
|
1963 | 0 | if ((INT)GetRequiredMemWorkBufferCore1() < |
1964 | 0 | (INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) { |
1965 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; |
1966 | 0 | goto bail; |
1967 | 0 | } |
1968 | | |
1969 | 0 | pcmLimiterScale = applyDrcLevelNormalization( |
1970 | 0 | self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain, |
1971 | 0 | pGainPerSample, pcmLimiterScale, self->extGainDelay, |
1972 | 0 | self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1); |
1973 | 0 | } |
1974 | | |
1975 | 0 | pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData, |
1976 | 0 | pGainPerSample, pcmLimiterScale, |
1977 | 0 | self->streamInfo.frameSize); |
1978 | |
|
1979 | 0 | { |
1980 | | /* Announce the additional limiter output delay */ |
1981 | 0 | self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter); |
1982 | 0 | } |
1983 | 0 | } else { |
1984 | 0 | if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { |
1985 | 0 | pcmLimiterScale = applyDrcLevelNormalization( |
1986 | 0 | self->hDrcInfo, pTimeData2, self->extGain, NULL, pcmLimiterScale, |
1987 | 0 | self->extGainDelay, self->streamInfo.frameSize, |
1988 | 0 | self->streamInfo.numChannels, |
1989 | 0 | (interleaved || (self->streamInfo.numChannels == 1)) |
1990 | 0 | ? 1 |
1991 | 0 | : self->streamInfo.frameSize, |
1992 | 0 | 0); |
1993 | 0 | } |
1994 | | |
1995 | | /* If numChannels = 1 we do not need interleaving. The same applies if SBR |
1996 | | or MPS are used, since their output is interleaved already (resampled or |
1997 | | not) */ |
1998 | 0 | if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || |
1999 | 0 | (self->mpsEnableCurr)) { |
2000 | 0 | scaleValuesSaturate( |
2001 | 0 | pTimeData, pTimeData2, |
2002 | 0 | self->streamInfo.frameSize * self->streamInfo.numChannels, |
2003 | 0 | pcmLimiterScale); |
2004 | |
|
2005 | 0 | } else { |
2006 | 0 | scaleValuesSaturate( |
2007 | 0 | (INT_PCM *)self->workBufferCore2, pTimeData2, |
2008 | 0 | self->streamInfo.frameSize * self->streamInfo.numChannels, |
2009 | 0 | pcmLimiterScale); |
2010 | | /* Interleave ouput buffer */ |
2011 | 0 | FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData, |
2012 | 0 | self->streamInfo.numChannels, self->streamInfo.frameSize, |
2013 | 0 | self->streamInfo.frameSize); |
2014 | 0 | } |
2015 | 0 | } |
2016 | 0 | } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/ |
2017 | | |
2018 | 0 | bail: |
2019 | | |
2020 | | /* error in renderer part occurred, ErrorStatus was set to invalid output */ |
2021 | 0 | if (fEndAuNotAdjusted && !IS_OUTPUT_VALID(ErrorStatus) && |
2022 | 0 | (accessUnit < numPrerollAU)) { |
2023 | 0 | transportDec_EndAccessUnit(self->hInput); |
2024 | 0 | } |
2025 | | |
2026 | | /* Update Statistics */ |
2027 | 0 | aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, |
2028 | 0 | ErrorStatus); |
2029 | 0 | if (((self->streamInfo.numChannels <= 0) || |
2030 | 0 | (self->streamInfo.frameSize <= 0) || |
2031 | 0 | (self->streamInfo.sampleRate <= 0)) && |
2032 | 0 | IS_OUTPUT_VALID(ErrorStatus)) { |
2033 | | /* Ensure consistency of IS_OUTPUT_VALID() macro. */ |
2034 | 0 | ErrorStatus = AAC_DEC_UNKNOWN; |
2035 | 0 | } |
2036 | |
|
2037 | 0 | if (!IS_OUTPUT_VALID(ErrorStatus)) { |
2038 | 0 | FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData)); |
2039 | 0 | } |
2040 | |
|
2041 | 0 | return ErrorStatus; |
2042 | 0 | } |
2043 | | |
2044 | 6.87k | LINKSPEC_CPP void aacDecoder_Close(HANDLE_AACDECODER self) { |
2045 | 6.87k | if (self == NULL) return; |
2046 | | |
2047 | 6.87k | if (self->hLimiter != NULL) { |
2048 | 6.87k | pcmLimiter_Destroy(self->hLimiter); |
2049 | 6.87k | } |
2050 | | |
2051 | 6.87k | if (self->hPcmUtils != NULL) { |
2052 | 6.87k | pcmDmx_Close(&self->hPcmUtils); |
2053 | 6.87k | } |
2054 | | |
2055 | 6.87k | FDK_drcDec_Close(&self->hUniDrcDecoder); |
2056 | | |
2057 | 6.87k | if (self->pMpegSurroundDecoder != NULL) { |
2058 | 6.87k | mpegSurroundDecoder_Close( |
2059 | 6.87k | (CMpegSurroundDecoder *)self->pMpegSurroundDecoder); |
2060 | 6.87k | } |
2061 | | |
2062 | 6.87k | if (self->hSbrDecoder != NULL) { |
2063 | 6.87k | sbrDecoder_Close(&self->hSbrDecoder); |
2064 | 6.87k | } |
2065 | | |
2066 | 6.87k | if (self->hInput != NULL) { |
2067 | 6.87k | transportDec_Close(&self->hInput); |
2068 | 6.87k | } |
2069 | | |
2070 | 6.87k | CAacDecoder_Close(self); |
2071 | 6.87k | } |
2072 | | |
2073 | 0 | LINKSPEC_CPP CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self) { |
2074 | 0 | return CAacDecoder_GetStreamInfo(self); |
2075 | 0 | } |
2076 | | |
2077 | 0 | LINKSPEC_CPP INT aacDecoder_GetLibInfo(LIB_INFO *info) { |
2078 | 0 | int i; |
2079 | |
|
2080 | 0 | if (info == NULL) { |
2081 | 0 | return -1; |
2082 | 0 | } |
2083 | | |
2084 | 0 | sbrDecoder_GetLibInfo(info); |
2085 | 0 | mpegSurroundDecoder_GetLibInfo(info); |
2086 | 0 | transportDec_GetLibInfo(info); |
2087 | 0 | FDK_toolsGetLibInfo(info); |
2088 | 0 | pcmDmx_GetLibInfo(info); |
2089 | 0 | pcmLimiter_GetLibInfo(info); |
2090 | 0 | FDK_drcDec_GetLibInfo(info); |
2091 | | |
2092 | | /* search for next free tab */ |
2093 | 0 | for (i = 0; i < FDK_MODULE_LAST; i++) { |
2094 | 0 | if (info[i].module_id == FDK_NONE) break; |
2095 | 0 | } |
2096 | 0 | if (i == FDK_MODULE_LAST) { |
2097 | 0 | return -1; |
2098 | 0 | } |
2099 | 0 | info += i; |
2100 | |
|
2101 | 0 | info->module_id = FDK_AACDEC; |
2102 | | /* build own library info */ |
2103 | 0 | info->version = |
2104 | 0 | LIB_VERSION(AACDECODER_LIB_VL0, AACDECODER_LIB_VL1, AACDECODER_LIB_VL2); |
2105 | 0 | LIB_VERSION_STRING(info); |
2106 | 0 | info->build_date = AACDECODER_LIB_BUILD_DATE; |
2107 | 0 | info->build_time = AACDECODER_LIB_BUILD_TIME; |
2108 | 0 | info->title = AACDECODER_LIB_TITLE; |
2109 | | |
2110 | | /* Set flags */ |
2111 | 0 | info->flags = 0 | CAPF_AAC_LC | CAPF_ER_AAC_LC | CAPF_ER_AAC_SCAL | |
2112 | 0 | CAPF_AAC_VCB11 | CAPF_AAC_HCR | CAPF_AAC_RVLC | CAPF_ER_AAC_LD | |
2113 | 0 | CAPF_ER_AAC_ELD | CAPF_AAC_CONCEALMENT | CAPF_AAC_DRC | |
2114 | 0 | CAPF_AAC_MPEG4 | CAPF_AAC_DRM_BSFORMAT | CAPF_AAC_1024 | |
2115 | 0 | CAPF_AAC_960 | CAPF_AAC_512 | CAPF_AAC_480 | |
2116 | 0 | CAPF_AAC_ELD_DOWNSCALE |
2117 | |
|
2118 | 0 | | CAPF_AAC_USAC | CAPF_ER_AAC_ELDV2 | CAPF_AAC_UNIDRC; |
2119 | | /* End of flags */ |
2120 | |
|
2121 | 0 | return 0; |
2122 | 0 | } |