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