1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /**************************** 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 SUPPRESS_BUILD_DATE_INFO
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 numChannels,const INT stereoConfigIndex,const INT coreSbrFrameLengthIndex,const INT configBytes,const UCHAR configMode,UCHAR * configChanged)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 const INT configBytes, const UCHAR configMode, UCHAR *configChanged) {
393 SACDEC_ERROR err;
394 TRANSPORTDEC_ERROR errTp;
395 HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
396
397 err = mpegSurroundDecoder_Config(
398 (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
399 samplingRate, frameSize, numChannels, stereoConfigIndex,
400 coreSbrFrameLengthIndex, configBytes, configMode, configChanged);
401
402 switch (err) {
403 case MPS_UNSUPPORTED_CONFIG:
404 /* MPS found but invalid or not decodable by this instance */
405 /* We switch off MPS and keep going */
406 hAacDecoder->mpsEnableCurr = 0;
407 hAacDecoder->mpsApplicable = 0;
408 errTp = TRANSPORTDEC_OK;
409 break;
410 case MPS_PARSE_ERROR:
411 /* MPS found but invalid or not decodable by this instance */
412 hAacDecoder->mpsEnableCurr = 0;
413 hAacDecoder->mpsApplicable = 0;
414 if ((coreCodec == AOT_USAC) || (coreCodec == AOT_DRM_USAC) ||
415 IS_LOWDELAY(coreCodec)) {
416 errTp = TRANSPORTDEC_PARSE_ERROR;
417 } else {
418 errTp = TRANSPORTDEC_OK;
419 }
420 break;
421 case MPS_OK:
422 hAacDecoder->mpsApplicable = 1;
423 errTp = TRANSPORTDEC_OK;
424 break;
425 default:
426 /* especially Parsing error is critical for transport layer */
427 hAacDecoder->mpsApplicable = 0;
428 errTp = TRANSPORTDEC_UNKOWN_ERROR;
429 }
430
431 return (INT)errTp;
432 }
433
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)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 const AUDIO_OBJECT_TYPE aot) {
440 DRC_DEC_ERROR err = DRC_DEC_OK;
441 TRANSPORTDEC_ERROR errTp;
442 HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
443 DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
444 UCHAR dummyBuffer[4] = {0};
445 FDK_BITSTREAM dummyBs;
446 HANDLE_FDK_BITSTREAM hReadBs;
447
448 if (subStreamIndex != 0) {
449 return TRANSPORTDEC_OK;
450 }
451
452 if (hBs == NULL) {
453 /* use dummy zero payload to clear memory */
454 hReadBs = &dummyBs;
455 FDKinitBitStream(hReadBs, dummyBuffer, 4, 24);
456 } else {
457 hReadBs = hBs;
458 }
459
460 if (aot == AOT_USAC) {
461 drcDecCodecMode = DRC_DEC_MPEG_D_USAC;
462 }
463
464 err = FDK_drcDec_SetCodecMode(hAacDecoder->hUniDrcDecoder, drcDecCodecMode);
465 if (err) return (INT)TRANSPORTDEC_UNKOWN_ERROR;
466
467 if (payloadType == 0) /* uniDrcConfig */
468 {
469 err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hReadBs);
470 } else /* loudnessInfoSet */
471 {
472 err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hReadBs);
473 hAacDecoder->loudnessInfoSetPosition[1] = payloadStart;
474 hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength;
475 }
476
477 if (err == DRC_DEC_OK)
478 errTp = TRANSPORTDEC_OK;
479 else
480 errTp = TRANSPORTDEC_UNKOWN_ERROR;
481
482 return (INT)errTp;
483 }
484
aacDecoder_AncDataInit(HANDLE_AACDECODER self,UCHAR * buffer,int size)485 LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self,
486 UCHAR *buffer, int size) {
487 CAncData *ancData = &self->ancData;
488
489 return CAacDecoder_AncDataInit(ancData, buffer, size);
490 }
491
aacDecoder_AncDataGet(HANDLE_AACDECODER self,int index,UCHAR ** ptr,int * size)492 LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self,
493 int index, UCHAR **ptr,
494 int *size) {
495 CAncData *ancData = &self->ancData;
496
497 return CAacDecoder_AncDataGet(ancData, index, ptr, size);
498 }
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 */
isSupportedMpsConfig(AUDIO_OBJECT_TYPE aot,unsigned int numInChannels,unsigned int fMpsPresent)502 static int isSupportedMpsConfig(AUDIO_OBJECT_TYPE aot,
503 unsigned int numInChannels,
504 unsigned int fMpsPresent) {
505 LIB_INFO libInfo[FDK_MODULE_LAST];
506 UINT mpsCaps;
507 int isSupportedCfg = 1;
508
509 FDKinitLibInfo(libInfo);
510
511 mpegSurroundDecoder_GetLibInfo(libInfo);
512
513 mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);
514
515 if (!(mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot)) {
516 /* We got an LD AOT but MPS decoder does not support LD. */
517 isSupportedCfg = 0;
518 }
519 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 isSupportedCfg = 0;
523 }
524 if (!(mpsCaps & CAPF_MPS_USAC) && IS_USAC(aot)) {
525 /* We got an USAC AOT but MPS decoder does not support USAC. */
526 isSupportedCfg = 0;
527 }
528 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 isSupportedCfg = 0;
531 }
532 /* Check whether the MPS modul supports the given number of input channels: */
533 switch (numInChannels) {
534 case 1:
535 if (!(mpsCaps & CAPF_MPS_1CH_IN)) {
536 /* We got a one channel input to MPS decoder but it does not support it.
537 */
538 isSupportedCfg = 0;
539 }
540 break;
541 case 2:
542 if (!(mpsCaps & CAPF_MPS_2CH_IN)) {
543 /* We got a two channel input to MPS decoder but it does not support it.
544 */
545 isSupportedCfg = 0;
546 }
547 break;
548 case 5:
549 case 6:
550 if (!(mpsCaps & CAPF_MPS_6CH_IN)) {
551 /* We got a six channel input to MPS decoder but it does not support it.
552 */
553 isSupportedCfg = 0;
554 }
555 break;
556 default:
557 isSupportedCfg = 0;
558 }
559
560 return (isSupportedCfg);
561 }
562
setConcealMethod(const HANDLE_AACDECODER self,const INT method)563 static AAC_DECODER_ERROR setConcealMethod(
564 const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
565 const INT method) {
566 AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
567 CConcealParams *pConcealData = NULL;
568 int method_revert = 0;
569 HANDLE_SBRDECODER hSbrDec = NULL;
570 HANDLE_AAC_DRC hDrcInfo = NULL;
571 HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
572 CConcealmentMethod backupMethod = ConcealMethodNone;
573 int backupDelay = 0;
574 int bsDelay = 0;
575
576 /* check decoder handle */
577 if (self != NULL) {
578 pConcealData = &self->concealCommonData;
579 hSbrDec = self->hSbrDecoder;
580 hDrcInfo = self->hDrcInfo;
581 hPcmDmx = self->hPcmUtils;
582 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 method_revert = 1;
587 }
588 if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
589 /* Interpolation concealment is not implemented for USAC/RSVD50 */
590 errorStatus = AAC_DEC_SET_PARAM_FAIL;
591 goto bail;
592 }
593 }
594
595 /* Get current method/delay */
596 backupMethod = CConcealment_GetMethod(pConcealData);
597 backupDelay = CConcealment_GetDelay(pConcealData);
598
599 /* Be sure to set AAC and SBR concealment method simultaneously! */
600 errorStatus = CConcealment_SetParams(
601 pConcealData,
602 (method_revert == 0) ? (int)method : (int)1, // concealMethod
603 AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeOutSlope
604 AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeInSlope
605 AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealMuteRelease
606 AACDEC_CONCEAL_PARAM_NOT_SPECIFIED // concealComfNoiseLevel
607 );
608 if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
609 goto bail;
610 }
611
612 /* Get new delay */
613 bsDelay = CConcealment_GetDelay(pConcealData);
614
615 {
616 SBR_ERROR sbrErr = SBRDEC_OK;
617
618 /* set SBR bitstream delay */
619 sbrErr = sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, bsDelay);
620
621 switch (sbrErr) {
622 case SBRDEC_OK:
623 case SBRDEC_NOT_INITIALIZED:
624 if (self != NULL) {
625 /* save the param value and set later
626 (when SBR has been initialized) */
627 self->sbrParams.bsDelay = bsDelay;
628 }
629 break;
630 default:
631 errorStatus = AAC_DEC_SET_PARAM_FAIL;
632 goto bail;
633 }
634 }
635
636 errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay);
637 if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
638 goto bail;
639 }
640
641 if (errorStatus == AAC_DEC_OK) {
642 PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay);
643 switch (err) {
644 case PCMDMX_INVALID_HANDLE:
645 errorStatus = AAC_DEC_INVALID_HANDLE;
646 break;
647 case PCMDMX_OK:
648 break;
649 default:
650 errorStatus = AAC_DEC_SET_PARAM_FAIL;
651 goto bail;
652 }
653 }
654
655 bail:
656 if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
657 /* Revert to the initial state */
658 CConcealment_SetParams(
659 pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
660 AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
661 AACDEC_CONCEAL_PARAM_NOT_SPECIFIED);
662 /* Revert SBR bitstream delay */
663 sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay);
664 /* Revert DRC bitstream delay */
665 aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay);
666 /* Revert PCM mixdown bitstream delay */
667 pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay);
668 }
669
670 return errorStatus;
671 }
672
aacDecoder_SetParam(const HANDLE_AACDECODER self,const AACDEC_PARAM param,const INT value)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 {
678 AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
679 HANDLE_TRANSPORTDEC hTpDec = NULL;
680 TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
681 HANDLE_AAC_DRC hDrcInfo = NULL;
682 HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
683 PCMDMX_ERROR dmxErr = PCMDMX_OK;
684 TDLimiterPtr hPcmTdl = NULL;
685 DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;
686
687 /* check decoder handle */
688 if (self != NULL) {
689 hTpDec = self->hInput;
690 hDrcInfo = self->hDrcInfo;
691 hPcmDmx = self->hPcmUtils;
692 hPcmTdl = self->hLimiter;
693 } else {
694 errorStatus = AAC_DEC_INVALID_HANDLE;
695 goto bail;
696 }
697
698 /* configure the subsystems */
699 switch (param) {
700 case AAC_PCM_MIN_OUTPUT_CHANNELS:
701 if (value < -1 || value > (8)) {
702 return AAC_DEC_SET_PARAM_FAIL;
703 }
704 dmxErr = pcmDmx_SetParam(hPcmDmx, MIN_NUMBER_OF_OUTPUT_CHANNELS, value);
705 break;
706
707 case AAC_PCM_MAX_OUTPUT_CHANNELS:
708 if (value < -1 || value > (8)) {
709 return AAC_DEC_SET_PARAM_FAIL;
710 }
711 dmxErr = pcmDmx_SetParam(hPcmDmx, MAX_NUMBER_OF_OUTPUT_CHANNELS, value);
712
713 if (dmxErr != PCMDMX_OK) {
714 goto bail;
715 }
716 errorStatus =
717 aacDecoder_drcSetParam(hDrcInfo, MAX_OUTPUT_CHANNELS, value);
718 if (value > 0) {
719 uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
720 DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED,
721 (FIXP_DBL)value);
722 }
723 break;
724
725 case AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE:
726 dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_DUAL_CHANNEL_MODE, value);
727 break;
728
729 case AAC_PCM_LIMITER_ENABLE:
730 if (value < -2 || value > 1) {
731 return AAC_DEC_SET_PARAM_FAIL;
732 }
733 self->limiterEnableUser = value;
734 break;
735
736 case AAC_PCM_LIMITER_ATTACK_TIME:
737 if (value <= 0) { /* module function converts value to unsigned */
738 return AAC_DEC_SET_PARAM_FAIL;
739 }
740 switch (pcmLimiter_SetAttack(hPcmTdl, value)) {
741 case TDLIMIT_OK:
742 break;
743 case TDLIMIT_INVALID_HANDLE:
744 return AAC_DEC_INVALID_HANDLE;
745 case TDLIMIT_INVALID_PARAMETER:
746 default:
747 return AAC_DEC_SET_PARAM_FAIL;
748 }
749 break;
750
751 case AAC_PCM_LIMITER_RELEAS_TIME:
752 if (value <= 0) { /* module function converts value to unsigned */
753 return AAC_DEC_SET_PARAM_FAIL;
754 }
755 switch (pcmLimiter_SetRelease(hPcmTdl, value)) {
756 case TDLIMIT_OK:
757 break;
758 case TDLIMIT_INVALID_HANDLE:
759 return AAC_DEC_INVALID_HANDLE;
760 case TDLIMIT_INVALID_PARAMETER:
761 default:
762 return AAC_DEC_SET_PARAM_FAIL;
763 }
764 break;
765
766 case AAC_METADATA_PROFILE: {
767 DMX_PROFILE_TYPE dmxProfile;
768 INT mdExpiry = -1; /* in ms (-1: don't change) */
769
770 switch ((AAC_MD_PROFILE)value) {
771 case AAC_MD_PROFILE_MPEG_STANDARD:
772 dmxProfile = DMX_PRFL_STANDARD;
773 break;
774 case AAC_MD_PROFILE_MPEG_LEGACY:
775 dmxProfile = DMX_PRFL_MATRIX_MIX;
776 break;
777 case AAC_MD_PROFILE_MPEG_LEGACY_PRIO:
778 dmxProfile = DMX_PRFL_FORCE_MATRIX_MIX;
779 break;
780 case AAC_MD_PROFILE_ARIB_JAPAN:
781 dmxProfile = DMX_PRFL_ARIB_JAPAN;
782 mdExpiry = 550; /* ms */
783 break;
784 default:
785 return AAC_DEC_SET_PARAM_FAIL;
786 }
787 dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_PROFILE_SETTING, (INT)dmxProfile);
788 if (dmxErr != PCMDMX_OK) {
789 goto bail;
790 }
791 if ((self != NULL) && (mdExpiry >= 0)) {
792 self->metadataExpiry = mdExpiry;
793 /* Determine the corresponding number of frames and configure all
794 * related modules. */
795 aacDecoder_setMetadataExpiry(self, mdExpiry);
796 }
797 } break;
798
799 case AAC_METADATA_EXPIRY_TIME:
800 if (value < 0) {
801 return AAC_DEC_SET_PARAM_FAIL;
802 }
803 if (self != NULL) {
804 self->metadataExpiry = value;
805 /* Determine the corresponding number of frames and configure all
806 * related modules. */
807 aacDecoder_setMetadataExpiry(self, value);
808 }
809 break;
810
811 case AAC_PCM_OUTPUT_CHANNEL_MAPPING:
812 if (value < 0 || value > 1) {
813 return AAC_DEC_SET_PARAM_FAIL;
814 }
815 /* CAUTION: The given value must be inverted to match the logic! */
816 FDK_chMapDescr_setPassThrough(&self->mapDescr, !value);
817 break;
818
819 case AAC_QMF_LOWPOWER:
820 if (value < -1 || value > 1) {
821 return AAC_DEC_SET_PARAM_FAIL;
822 }
823
824 /**
825 * Set QMF mode (might be overriden)
826 * 0:HQ (complex)
827 * 1:LP (partially complex)
828 */
829 self->qmfModeUser = (QMF_MODE)value;
830 break;
831
832 case AAC_DRC_ATTENUATION_FACTOR:
833 /* DRC compression factor (where 0 is no and 127 is max compression) */
834 if ((value < 0) || (value > 127)) {
835 return AAC_DEC_SET_PARAM_FAIL;
836 }
837 errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value);
838 uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_COMPRESS,
839 value * (FL2FXCONST_DBL(0.5f / 127.0f)));
840 break;
841
842 case AAC_DRC_BOOST_FACTOR:
843 /* DRC boost factor (where 0 is no and 127 is max boost) */
844 if ((value < 0) || (value > 127)) {
845 return AAC_DEC_SET_PARAM_FAIL;
846 }
847 errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value);
848 uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_BOOST,
849 value * (FL2FXCONST_DBL(0.5f / 127.0f)));
850 break;
851
852 case AAC_DRC_REFERENCE_LEVEL:
853 if ((value >= 0) &&
854 ((value < 40) || (value > 127))) /* allowed range: -10 to -31.75 dB */
855 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 errorStatus = aacDecoder_drcSetParam(hDrcInfo, TARGET_REF_LEVEL, value);
861 uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
862 DRC_DEC_LOUDNESS_NORMALIZATION_ON,
863 (FIXP_DBL)(value >= 0));
864 /* set target loudness also for MPEG-D DRC */
865 self->defaultTargetLoudness = (SCHAR)value;
866 break;
867
868 case AAC_DRC_HEAVY_COMPRESSION:
869 /* Don't need to overwrite cut/boost values */
870 errorStatus =
871 aacDecoder_drcSetParam(hDrcInfo, APPLY_HEAVY_COMPRESSION, value);
872 break;
873
874 case AAC_DRC_DEFAULT_PRESENTATION_MODE:
875 /* DRC default presentation mode */
876 errorStatus =
877 aacDecoder_drcSetParam(hDrcInfo, DEFAULT_PRESENTATION_MODE, value);
878 break;
879
880 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 errorStatus =
885 aacDecoder_drcSetParam(hDrcInfo, ENCODER_TARGET_LEVEL, value);
886 break;
887
888 case AAC_UNIDRC_SET_EFFECT:
889 if ((value < -1) || (value > 6)) return AAC_DEC_SET_PARAM_FAIL;
890 uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_EFFECT_TYPE,
891 (FIXP_DBL)value);
892 break;
893 case AAC_UNIDRC_ALBUM_MODE:
894 uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_ALBUM_MODE,
895 (FIXP_DBL)value);
896 break;
897
898 case AAC_TPDEC_CLEAR_BUFFER:
899 errTp = transportDec_SetParam(hTpDec, TPDEC_PARAM_RESET, 1);
900 self->streamInfo.numLostAccessUnits = 0;
901 self->streamInfo.numBadBytes = 0;
902 self->streamInfo.numTotalBytes = 0;
903 /* aacDecoder_SignalInterruption(self); */
904 break;
905 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 errorStatus = setConcealMethod(self, value);
912 if (errorStatus == AAC_DEC_OK) {
913 self->concealMethodUser = (CConcealmentMethod)value;
914 }
915 break;
916
917 default:
918 return AAC_DEC_SET_PARAM_FAIL;
919 } /* switch(param) */
920
921 bail:
922
923 if (errorStatus == AAC_DEC_OK) {
924 /* Check error code returned by DMX module library: */
925 switch (dmxErr) {
926 case PCMDMX_OK:
927 break;
928 case PCMDMX_INVALID_HANDLE:
929 errorStatus = AAC_DEC_INVALID_HANDLE;
930 break;
931 default:
932 errorStatus = AAC_DEC_SET_PARAM_FAIL;
933 }
934 }
935
936 if (errTp != TRANSPORTDEC_OK && errorStatus == AAC_DEC_OK) {
937 errorStatus = AAC_DEC_SET_PARAM_FAIL;
938 }
939
940 if (errorStatus == AAC_DEC_OK) {
941 /* Check error code returned by MPEG-D DRC decoder library: */
942 switch (uniDrcErr) {
943 case 0:
944 break;
945 case -9998:
946 errorStatus = AAC_DEC_INVALID_HANDLE;
947 break;
948 default:
949 errorStatus = AAC_DEC_SET_PARAM_FAIL;
950 break;
951 }
952 }
953
954 return (errorStatus);
955 }
aacDecoder_Open(TRANSPORT_TYPE transportFmt,UINT nrOfLayers)956 LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt,
957 UINT nrOfLayers) {
958 AAC_DECODER_INSTANCE *aacDec = NULL;
959 HANDLE_TRANSPORTDEC pIn;
960 int err = 0;
961 int stereoConfigIndex = -1;
962
963 UINT nrOfLayers_min = fMin(nrOfLayers, (UINT)1);
964
965 /* Allocate transport layer struct. */
966 pIn = transportDec_Open(transportFmt, TP_FLAG_MPEG4, nrOfLayers_min);
967 if (pIn == NULL) {
968 return NULL;
969 }
970
971 /* Allocate AAC decoder core struct. */
972 aacDec = CAacDecoder_Open(transportFmt);
973
974 if (aacDec == NULL) {
975 transportDec_Close(&pIn);
976 goto bail;
977 }
978 aacDec->hInput = pIn;
979
980 aacDec->nrOfLayers = nrOfLayers_min;
981
982 /* Setup channel mapping descriptor. */
983 FDK_chMapDescr_init(&aacDec->mapDescr, NULL, 0, 0);
984
985 /* Register Config Update callback. */
986 transportDec_RegisterAscCallback(pIn, aacDecoder_ConfigCallback,
987 (void *)aacDec);
988
989 /* Register Free Memory callback. */
990 transportDec_RegisterFreeMemCallback(pIn, aacDecoder_FreeMemCallback,
991 (void *)aacDec);
992
993 /* Register config switch control callback. */
994 transportDec_RegisterCtrlCFGChangeCallback(
995 pIn, aacDecoder_CtrlCFGChangeCallback, (void *)aacDec);
996
997 FDKmemclear(&aacDec->qmfDomain, sizeof(FDK_QMF_DOMAIN));
998 /* open SBR decoder */
999 if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) {
1000 err = -1;
1001 goto bail;
1002 }
1003 aacDec->qmfModeUser = NOT_DEFINED;
1004 transportDec_RegisterSbrCallback(aacDec->hInput, aacDecoder_SbrCallback,
1005 (void *)aacDec->hSbrDecoder);
1006
1007 if (mpegSurroundDecoder_Open(
1008 (CMpegSurroundDecoder **)&aacDec->pMpegSurroundDecoder,
1009 stereoConfigIndex, &aacDec->qmfDomain)) {
1010 err = -1;
1011 goto bail;
1012 }
1013 /* Set MPEG Surround defaults */
1014 aacDec->mpsEnableUser = 0;
1015 aacDec->mpsEnableCurr = 0;
1016 aacDec->mpsApplicable = 0;
1017 aacDec->mpsOutputMode = (SCHAR)SACDEC_OUT_MODE_NORMAL;
1018 transportDec_RegisterSscCallback(pIn, aacDecoder_SscCallback, (void *)aacDec);
1019
1020 {
1021 if (FDK_drcDec_Open(&(aacDec->hUniDrcDecoder), DRC_DEC_ALL) != 0) {
1022 err = -1;
1023 goto bail;
1024 }
1025 }
1026
1027 transportDec_RegisterUniDrcConfigCallback(pIn, aacDecoder_UniDrcCallback,
1028 (void *)aacDec,
1029 aacDec->loudnessInfoSetPosition);
1030 aacDec->defaultTargetLoudness = (SCHAR)96;
1031
1032 pcmDmx_Open(&aacDec->hPcmUtils);
1033 if (aacDec->hPcmUtils == NULL) {
1034 err = -1;
1035 goto bail;
1036 }
1037
1038 aacDec->hLimiter =
1039 pcmLimiter_Create(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS,
1040 (FIXP_DBL)MAXVAL_DBL, (8), 96000);
1041 if (NULL == aacDec->hLimiter) {
1042 err = -1;
1043 goto bail;
1044 }
1045 aacDec->limiterEnableUser = (UCHAR)-1;
1046 aacDec->limiterEnableCurr = 0;
1047
1048 /* Assure that all modules have same delay */
1049 if (setConcealMethod(aacDec,
1050 CConcealment_GetMethod(&aacDec->concealCommonData))) {
1051 err = -1;
1052 goto bail;
1053 }
1054
1055 bail:
1056 if (err == -1) {
1057 aacDecoder_Close(aacDec);
1058 aacDec = NULL;
1059 }
1060 return aacDec;
1061 }
1062
aacDecoder_Fill(HANDLE_AACDECODER self,UCHAR * pBuffer[],const UINT bufferSize[],UINT * pBytesValid)1063 LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
1064 UCHAR *pBuffer[],
1065 const UINT bufferSize[],
1066 UINT *pBytesValid) {
1067 TRANSPORTDEC_ERROR tpErr;
1068 /* loop counter for layers; if not TT_MP4_RAWPACKETS used as index for only
1069 available layer */
1070 INT layer = 0;
1071 INT nrOfLayers = self->nrOfLayers;
1072
1073 {
1074 for (layer = 0; layer < nrOfLayers; layer++) {
1075 {
1076 tpErr = transportDec_FillData(self->hInput, pBuffer[layer],
1077 bufferSize[layer], &pBytesValid[layer],
1078 layer);
1079 if (tpErr != TRANSPORTDEC_OK) {
1080 return AAC_DEC_UNKNOWN; /* Must be an internal error */
1081 }
1082 }
1083 }
1084 }
1085
1086 return AAC_DEC_OK;
1087 }
1088
aacDecoder_SignalInterruption(HANDLE_AACDECODER self)1089 static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
1090 CAacDecoder_SignalInterruption(self);
1091
1092 if (self->hSbrDecoder != NULL) {
1093 sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 1);
1094 }
1095 if (self->mpsEnableUser) {
1096 mpegSurroundDecoder_SetParam(
1097 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
1098 SACDEC_BS_INTERRUPTION, 1);
1099 }
1100 }
1101
aacDecoder_UpdateBitStreamCounters(CStreamInfo * pSi,HANDLE_FDK_BITSTREAM hBs,INT nBits,AAC_DECODER_ERROR ErrorStatus)1102 static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi,
1103 HANDLE_FDK_BITSTREAM hBs,
1104 INT nBits,
1105 AAC_DECODER_ERROR ErrorStatus) {
1106 /* calculate bit difference (amount of bits moved forward) */
1107 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 if (pSi->frameSize > 0) {
1118 /* bitRate = nBits * sampleRate / frameSize */
1119 int ratio_e = 0;
1120 FIXP_DBL ratio_m = fDivNorm(pSi->sampleRate, pSi->frameSize, &ratio_e);
1121 pSi->bitRate = (INT)fMultNorm(nBits, DFRACT_BITS - 1, ratio_m, ratio_e,
1122 DFRACT_BITS - 1);
1123 }
1124
1125 /* bit/byte counters */
1126 {
1127 INT nBytes;
1128
1129 nBytes = nBits >> 3;
1130 pSi->numTotalBytes += nBytes;
1131 if (IS_OUTPUT_VALID(ErrorStatus)) {
1132 pSi->numTotalAccessUnits++;
1133 }
1134 if (IS_DECODE_ERROR(ErrorStatus)) {
1135 pSi->numBadBytes += nBytes;
1136 pSi->numBadAccessUnits++;
1137 }
1138 }
1139 }
1140
aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self)1141 static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
1142 INT n;
1143
1144 transportDec_GetMissingAccessUnitCount(&n, self->hInput);
1145
1146 return n;
1147 }
1148
aacDecoder_DecodeFrame(HANDLE_AACDECODER self,INT_PCM * pTimeData,const INT timeDataSize,const UINT flags)1149 LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
1150 INT_PCM *pTimeData,
1151 const INT timeDataSize,
1152 const UINT flags) {
1153 AAC_DECODER_ERROR ErrorStatus;
1154 INT layer;
1155 INT nBits;
1156 INT timeData2Size;
1157 INT timeData3Size;
1158 INT timeDataHeadroom;
1159 HANDLE_FDK_BITSTREAM hBs;
1160 int fTpInterruption = 0; /* Transport originated interruption detection. */
1161 int fTpConceal = 0; /* Transport originated concealment. */
1162 UINT accessUnit = 0;
1163 UINT numAccessUnits = 1;
1164 UINT numPrerollAU = 0;
1165 int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
1166 int applyCrossfade = 1; /* flag indicates if flushing was possible */
1167 PCM_DEC *pTimeData2;
1168 PCM_AAC *pTimeData3;
1169 INT pcmLimiterScale = 0;
1170 INT interleaved = 0;
1171
1172 if (self == NULL) {
1173 return AAC_DEC_INVALID_HANDLE;
1174 }
1175
1176 if (flags & AACDEC_INTR) {
1177 self->streamInfo.numLostAccessUnits = 0;
1178 }
1179 hBs = transportDec_GetBitstream(self->hInput, 0);
1180
1181 /* Get current bits position for bitrate calculation. */
1182 nBits = FDKgetValidBits(hBs);
1183
1184 if (flags & AACDEC_CLRHIST) {
1185 if (self->flags[0] & AC_USAC) {
1186 /* 1) store AudioSpecificConfig always in AudioSpecificConfig_Parse() */
1187 /* 2) free memory of dynamic allocated data */
1188 CSAudioSpecificConfig asc;
1189 transportDec_GetAsc(self->hInput, 0, &asc);
1190 aacDecoder_FreeMemCallback(self, &asc);
1191 self->streamInfo.numChannels = 0;
1192 /* 3) restore AudioSpecificConfig */
1193 if (asc.configBits <= (TP_USAC_MAX_CONFIG_LEN << 3)) {
1194 transportDec_OutOfBandConfig(self->hInput, asc.config,
1195 (asc.configBits + 7) >> 3, 0);
1196 }
1197 }
1198 }
1199
1200 if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) ||
1201 (self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
1202 (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) ||
1203 (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND))) {
1204 TRANSPORTDEC_ERROR err;
1205
1206 for (layer = 0; layer < self->nrOfLayers; layer++) {
1207 err = transportDec_ReadAccessUnit(self->hInput, layer);
1208 if (err != TRANSPORTDEC_OK) {
1209 switch (err) {
1210 case TRANSPORTDEC_NOT_ENOUGH_BITS:
1211 ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
1212 goto bail;
1213 case TRANSPORTDEC_SYNC_ERROR:
1214 self->streamInfo.numLostAccessUnits =
1215 aacDecoder_EstimateNumberOfLostFrames(self);
1216 fTpInterruption = 1;
1217 break;
1218 case TRANSPORTDEC_NEED_TO_RESTART:
1219 ErrorStatus = AAC_DEC_NEED_TO_RESTART;
1220 goto bail;
1221 case TRANSPORTDEC_CRC_ERROR:
1222 fTpConceal = 1;
1223 break;
1224 case TRANSPORTDEC_UNSUPPORTED_FORMAT:
1225 ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
1226 goto bail;
1227 default:
1228 ErrorStatus = AAC_DEC_UNKNOWN;
1229 goto bail;
1230 }
1231 }
1232 }
1233 } else {
1234 if (self->streamInfo.numLostAccessUnits > 0) {
1235 self->streamInfo.numLostAccessUnits--;
1236 }
1237 }
1238
1239 self->frameOK = 1;
1240
1241 UINT prerollAUOffset[AACDEC_MAX_NUM_PREROLL_AU];
1242 UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU];
1243 for (int i = 0; i < AACDEC_MAX_NUM_PREROLL_AU + 1; i++)
1244 self->prerollAULength[i] = 0;
1245
1246 INT auStartAnchor;
1247 HANDLE_FDK_BITSTREAM hBsAu;
1248
1249 /* Process preroll frames and current frame */
1250 do {
1251 if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
1252 (self->flushStatus != AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON) &&
1253 (accessUnit == 0) &&
1254 (self->hasAudioPreRoll ||
1255 (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) &&
1256 !fTpInterruption &&
1257 !fTpConceal /* Bit stream pointer needs to be at the beginning of a
1258 (valid) AU. */
1259 ) {
1260 ErrorStatus = CAacDecoder_PreRollExtensionPayloadParse(
1261 self, &numPrerollAU, prerollAUOffset, prerollAULength);
1262
1263 if (ErrorStatus != AAC_DEC_OK) {
1264 switch (ErrorStatus) {
1265 case AAC_DEC_NOT_ENOUGH_BITS:
1266 goto bail;
1267 case AAC_DEC_PARSE_ERROR:
1268 self->frameOK = 0;
1269 break;
1270 default:
1271 break;
1272 }
1273 }
1274
1275 numAccessUnits += numPrerollAU;
1276 }
1277
1278 hBsAu = transportDec_GetBitstream(self->hInput, 0);
1279 auStartAnchor = (INT)FDKgetValidBits(hBsAu);
1280
1281 self->accessUnit = accessUnit;
1282 if (accessUnit < numPrerollAU) {
1283 FDKpushFor(hBsAu, prerollAUOffset[accessUnit]);
1284 }
1285
1286 /* Signal bit stream interruption to other modules if required. */
1287 if (fTpInterruption || ((flags & AACDEC_INTR) && (accessUnit == 0))) {
1288 aacDecoder_SignalInterruption(self);
1289 if (!((flags & AACDEC_INTR) && (accessUnit == 0))) {
1290 ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
1291 goto bail;
1292 }
1293 }
1294
1295 /* Clearing core data will be done in CAacDecoder_DecodeFrame() below.
1296 Tell other modules to clear states if required. */
1297 if (flags & AACDEC_CLRHIST) {
1298 if (!(self->flags[0] & AC_USAC)) {
1299 sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, 1);
1300 mpegSurroundDecoder_SetParam(
1301 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
1302 SACDEC_CLEAR_HISTORY, 1);
1303 if (FDK_QmfDomain_ClearPersistentMemory(&self->qmfDomain) != 0) {
1304 ErrorStatus = AAC_DEC_UNKNOWN;
1305 goto bail;
1306 }
1307 }
1308 }
1309
1310 /* Empty bit buffer in case of flush request. */
1311 if (flags & AACDEC_FLUSH && !(flags & AACDEC_CONCEAL)) {
1312 if (!self->flushStatus) {
1313 transportDec_SetParam(self->hInput, TPDEC_PARAM_RESET, 1);
1314 self->streamInfo.numLostAccessUnits = 0;
1315 self->streamInfo.numBadBytes = 0;
1316 self->streamInfo.numTotalBytes = 0;
1317 }
1318 }
1319 /* Reset the output delay field. The modules will add their figures one
1320 * after another. */
1321 self->streamInfo.outputDelay = 0;
1322
1323 if (self->limiterEnableUser == (UCHAR)-2) {
1324 /* Enable limiter only for RSVD60. */
1325 self->limiterEnableCurr = (self->flags[0] & AC_RSV603DA) ? 1 : 0;
1326 } else if (self->limiterEnableUser == (UCHAR)-1) {
1327 /* Enable limiter for all non-lowdelay AOT's. */
1328 self->limiterEnableCurr = (self->flags[0] & (AC_LD | AC_ELD)) ? 0 : 1;
1329 } else {
1330 /* Use limiter configuration as requested. */
1331 self->limiterEnableCurr = self->limiterEnableUser;
1332 }
1333
1334 /* reset DRC level normalization gain on a per frame basis */
1335 self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE;
1336
1337 pTimeData2 = self->pTimeData2;
1338 timeData2Size = self->timeData2Size / sizeof(PCM_DEC);
1339 pTimeData3 = (PCM_AAC *)self->pTimeData2;
1340 timeData3Size = self->timeData2Size / sizeof(PCM_AAC);
1341
1342 ErrorStatus = CAacDecoder_DecodeFrame(
1343 self,
1344 flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
1345 ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
1346 : 0),
1347 pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0);
1348
1349 timeDataHeadroom = self->aacOutDataHeadroom;
1350
1351 /* if flushing for USAC DASH IPF was not possible go on with decoding
1352 * preroll */
1353 if ((self->flags[0] & AC_USAC) &&
1354 (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
1355 !(flags & AACDEC_CONCEAL) && (ErrorStatus != AAC_DEC_OK)) {
1356 applyCrossfade = 0;
1357 } else /* USAC DASH IPF flushing possible begin */
1358 {
1359 if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || fTpConceal ||
1360 self->flushStatus) &&
1361 (!(IS_OUTPUT_VALID(ErrorStatus)) || !(accessUnit < numPrerollAU))) {
1362 TRANSPORTDEC_ERROR tpErr;
1363 tpErr = transportDec_EndAccessUnit(self->hInput);
1364 if (tpErr != TRANSPORTDEC_OK) {
1365 self->frameOK = 0;
1366 }
1367 } else { /* while preroll processing later possibly an error in the
1368 renderer part occurrs */
1369 if (IS_OUTPUT_VALID(ErrorStatus)) {
1370 fEndAuNotAdjusted = 1;
1371 }
1372 }
1373
1374 /* If the current pTimeData2 does not contain a valid signal, there
1375 * nothing else we can do, so bail. */
1376 if (!IS_OUTPUT_VALID(ErrorStatus)) {
1377 goto bail;
1378 }
1379
1380 {
1381 self->streamInfo.sampleRate = self->streamInfo.aacSampleRate;
1382 self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
1383 }
1384
1385 self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
1386
1387 {
1388 FDK_Delay_Apply(
1389 &self->usacResidualDelay,
1390 pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
1391 self->streamInfo.frameSize, 0);
1392 }
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 if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD))) {
1397 self->mpsEnableCurr =
1398 (self->mpsEnableUser &&
1399 isSupportedMpsConfig(self->streamInfo.aot,
1400 self->streamInfo.numChannels,
1401 (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0));
1402 }
1403
1404 if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
1405 self->mpsEnableCurr) {
1406 /* if not done yet, allocate full MPEG Surround decoder instance */
1407 if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
1408 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
1409 SAC_INSTANCE_NOT_FULL_AVAILABLE) {
1410 if (mpegSurroundDecoder_Open(
1411 (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
1412 &self->qmfDomain)) {
1413 return AAC_DEC_OUT_OF_MEMORY;
1414 }
1415 }
1416 }
1417
1418 CAacDecoder_SyncQmfMode(self);
1419
1420 if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
1421 self->mpsEnableCurr) {
1422 SAC_INPUT_CONFIG sac_interface = (self->sbrEnabled && self->hSbrDecoder)
1423 ? SAC_INTERFACE_QMF
1424 : SAC_INTERFACE_TIME;
1425 /* needs to be done before first SBR apply. */
1426 mpegSurroundDecoder_ConfigureQmfDomain(
1427 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
1428 (UINT)self->streamInfo.aacSampleRate, self->streamInfo.aot);
1429 if (self->qmfDomain.globalConf.nBandsAnalysis_requested > 0) {
1430 self->qmfDomain.globalConf.nQmfTimeSlots_requested =
1431 self->streamInfo.aacSamplesPerFrame /
1432 self->qmfDomain.globalConf.nBandsAnalysis_requested;
1433 } else {
1434 self->qmfDomain.globalConf.nQmfTimeSlots_requested = 0;
1435 }
1436 }
1437
1438 switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
1439 default:
1440 case QMF_DOMAIN_INIT_ERROR:
1441 ErrorStatus = AAC_DEC_UNKNOWN;
1442 goto bail;
1443 case QMF_DOMAIN_OUT_OF_MEMORY:
1444 ErrorStatus = AAC_DEC_OUT_OF_MEMORY;
1445 goto bail;
1446 case QMF_DOMAIN_OK:
1447 break;
1448 }
1449
1450 /* sbr decoder */
1451
1452 if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) ||
1453 self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState >
1454 ConcealState_FadeIn) {
1455 self->frameOK = 0; /* if an error has occured do concealment in the SBR
1456 decoder too */
1457 }
1458
1459 if (self->sbrEnabled && (!(self->flags[0] & AC_USAC_SCFGI3))) {
1460 SBR_ERROR sbrError = SBRDEC_OK;
1461 int chIdx, numCoreChannel = self->streamInfo.numChannels;
1462
1463 /* set params */
1464 sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
1465 self->sbrParams.bsDelay);
1466 sbrDecoder_SetParam(
1467 self->hSbrDecoder, SBR_FLUSH_DATA,
1468 (flags & AACDEC_FLUSH) |
1469 ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
1470 : 0));
1471
1472 if (self->streamInfo.aot == AOT_ER_AAC_ELD) {
1473 /* Configure QMF */
1474 sbrDecoder_SetParam(self->hSbrDecoder, SBR_LD_QMF_TIME_ALIGN,
1475 (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0);
1476 }
1477
1478 {
1479 PCMDMX_ERROR dmxErr;
1480 INT maxOutCh = 0;
1481
1482 dmxErr = pcmDmx_GetParam(self->hPcmUtils,
1483 MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh);
1484 if ((dmxErr == PCMDMX_OK) && (maxOutCh == 1)) {
1485 /* Disable PS processing if we have to create a mono output signal.
1486 */
1487 self->psPossible = 0;
1488 }
1489 }
1490
1491 sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
1492 (self->mpsEnableCurr) ? 2 : 0);
1493
1494 PCM_AAC *input;
1495 input = (PCM_AAC *)self->workBufferCore2;
1496 FDKmemcpy(input, pTimeData3,
1497 sizeof(PCM_AAC) * (self->streamInfo.numChannels) *
1498 (self->streamInfo.frameSize));
1499
1500 /* apply SBR processing */
1501 sbrError = sbrDecoder_Apply(
1502 self->hSbrDecoder, input, pTimeData3, timeData3Size,
1503 &self->streamInfo.numChannels, &self->streamInfo.sampleRate,
1504 &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
1505 self->aacOutDataHeadroom, &timeDataHeadroom);
1506
1507 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 self->flags[0] |= AC_SBR_PRESENT;
1512 if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
1513 if (self->streamInfo.aacSampleRate >> 2 ==
1514 self->streamInfo.sampleRate) {
1515 self->streamInfo.frameSize =
1516 self->streamInfo.aacSamplesPerFrame >> 2;
1517 self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 2;
1518 } else if (self->streamInfo.aacSampleRate >> 1 ==
1519 self->streamInfo.sampleRate) {
1520 self->streamInfo.frameSize =
1521 self->streamInfo.aacSamplesPerFrame >> 1;
1522 self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 1;
1523 } else if (self->streamInfo.aacSampleRate << 1 ==
1524 self->streamInfo.sampleRate) {
1525 self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
1526 << 1;
1527 self->streamInfo.outputDelay = self->streamInfo.outputDelay << 1;
1528 } else if (self->streamInfo.aacSampleRate << 2 ==
1529 self->streamInfo.sampleRate) {
1530 self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
1531 << 2;
1532 self->streamInfo.outputDelay = self->streamInfo.outputDelay << 2;
1533 } else if (self->streamInfo.frameSize == 768) {
1534 self->streamInfo.frameSize =
1535 (self->streamInfo.aacSamplesPerFrame << 3) / 3;
1536 self->streamInfo.outputDelay =
1537 (self->streamInfo.outputDelay << 3) / 3;
1538 } else {
1539 ErrorStatus = AAC_DEC_SET_PARAM_FAIL;
1540 goto bail;
1541 }
1542 } else {
1543 self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
1544 }
1545 self->streamInfo.outputDelay +=
1546 sbrDecoder_GetDelay(self->hSbrDecoder);
1547
1548 if (self->psPossible) {
1549 self->flags[0] |= AC_PS_PRESENT;
1550 }
1551 for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels;
1552 chIdx += 1) {
1553 self->channelType[chIdx] = ACT_FRONT;
1554 self->channelIndices[chIdx] = chIdx;
1555 }
1556 }
1557 if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
1558 ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
1559 goto bail;
1560 }
1561 }
1562
1563 if (self->mpsEnableCurr) {
1564 int err, sac_interface, nChannels, frameSize;
1565
1566 nChannels = self->streamInfo.numChannels;
1567 frameSize = self->streamInfo.frameSize;
1568 sac_interface = SAC_INTERFACE_TIME;
1569
1570 if (self->sbrEnabled && self->hSbrDecoder)
1571 sac_interface = SAC_INTERFACE_QMF;
1572 if (self->streamInfo.aot == AOT_USAC) {
1573 if (self->flags[0] & AC_USAC_SCFGI3) {
1574 sac_interface = SAC_INTERFACE_TIME;
1575 }
1576 }
1577 err = mpegSurroundDecoder_SetParam(
1578 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
1579 SACDEC_INTERFACE, sac_interface);
1580
1581 if (err == 0) {
1582 err = mpegSurroundDecoder_Apply(
1583 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
1584 (PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size,
1585 self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
1586 self->streamInfo.sampleRate, self->streamInfo.aot,
1587 self->channelType, self->channelIndices, &self->mapDescr,
1588 self->aacOutDataHeadroom, &timeDataHeadroom);
1589 }
1590
1591 if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) {
1592 ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
1593 goto bail;
1594 }
1595 if (err == 0) {
1596 /* Update output parameter */
1597 self->streamInfo.numChannels = nChannels;
1598 self->streamInfo.frameSize = frameSize;
1599 self->streamInfo.outputDelay += mpegSurroundDecoder_GetDelay(
1600 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
1601 /* Save current parameter for possible concealment of next frame */
1602 self->mpsOutChannelsLast = nChannels;
1603 self->mpsFrameSizeLast = frameSize;
1604 } else if ((self->mpsOutChannelsLast > 0) &&
1605 (self->mpsFrameSizeLast > 0)) {
1606 /* Restore parameters of last frame ... */
1607 self->streamInfo.numChannels = self->mpsOutChannelsLast;
1608 self->streamInfo.frameSize = self->mpsFrameSizeLast;
1609 /* ... and clear output buffer so that potentially corrupted data does
1610 * not reach the framework. */
1611 FDKmemclear(pTimeData3, self->mpsOutChannelsLast *
1612 self->mpsFrameSizeLast * sizeof(PCM_AAC));
1613 /* Additionally proclaim that this frame had errors during decoding.
1614 */
1615 ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
1616 } else {
1617 ErrorStatus = AAC_DEC_UNKNOWN; /* no output */
1618 }
1619 }
1620
1621 /* SBR decoder for Unified Stereo Config (stereoConfigIndex == 3) */
1622
1623 if (self->sbrEnabled && (self->flags[0] & AC_USAC_SCFGI3)) {
1624 SBR_ERROR sbrError = SBRDEC_OK;
1625
1626 /* set params */
1627 sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
1628 self->sbrParams.bsDelay);
1629 sbrDecoder_SetParam(
1630 self->hSbrDecoder, SBR_FLUSH_DATA,
1631 (flags & AACDEC_FLUSH) |
1632 ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
1633 : 0));
1634
1635 sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
1636
1637 /* apply SBR processing */
1638 sbrError = sbrDecoder_Apply(
1639 self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size,
1640 &self->streamInfo.numChannels, &self->streamInfo.sampleRate,
1641 &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
1642 self->aacOutDataHeadroom, &timeDataHeadroom);
1643
1644 if (sbrError == SBRDEC_OK) {
1645 /* Update data in streaminfo structure. Assume that the SBR upsampling
1646 * factor is either 1,2 or 4 */
1647 self->flags[0] |= AC_SBR_PRESENT;
1648 if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
1649 if (self->streamInfo.frameSize == 768) {
1650 self->streamInfo.frameSize =
1651 (self->streamInfo.aacSamplesPerFrame * 8) / 3;
1652 } else if (self->streamInfo.aacSampleRate << 2 ==
1653 self->streamInfo.sampleRate) {
1654 self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
1655 << 2;
1656 } else {
1657 self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
1658 << 1;
1659 }
1660 }
1661
1662 self->flags[0] &= ~AC_PS_PRESENT;
1663 }
1664 if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
1665 ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
1666 goto bail;
1667 }
1668 }
1669
1670 {
1671 if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) {
1672 for (int i = ((self->streamInfo.frameSize *
1673 self->streamInfo.numChannels) -
1674 1);
1675 i >= 0; i--) {
1676 pTimeData2[i] =
1677 (PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom);
1678 }
1679 }
1680 }
1681
1682 {
1683 if ((FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) &&
1684 !(self->flags[0] & AC_RSV603DA)) {
1685 /* Apply DRC gains*/
1686 int ch, drcDelay = 0;
1687 int needsDeinterleaving = 0;
1688 FIXP_DBL *drcWorkBuffer = NULL;
1689 FIXP_DBL channelGain[(8)];
1690 int reverseInChannelMap[(8)];
1691 int reverseOutChannelMap[(8)];
1692 int numDrcOutChannels = FDK_drcDec_GetParam(
1693 self->hUniDrcDecoder, DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED);
1694 FDKmemclear(channelGain, sizeof(channelGain));
1695 for (ch = 0; ch < (8); ch++) {
1696 reverseInChannelMap[ch] = ch;
1697 reverseOutChannelMap[ch] = ch;
1698 }
1699
1700 /* Update sampleRate and frameSize. This may be necessary in case of
1701 * implicit SBR signaling */
1702 FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_SAMPLE_RATE,
1703 self->streamInfo.sampleRate);
1704 FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_FRAME_SIZE,
1705 self->streamInfo.frameSize);
1706
1707 /* If SBR and/or MPS is active, the DRC gains are aligned to the QMF
1708 domain signal before the QMF synthesis. Therefore the DRC gains
1709 need to be delayed by the QMF synthesis delay. */
1710 if (self->sbrEnabled) drcDelay = 257;
1711 if (self->mpsEnableCurr) drcDelay = 257;
1712 /* Take into account concealment delay */
1713 drcDelay += CConcealment_GetDelay(&self->concealCommonData) *
1714 self->streamInfo.frameSize;
1715
1716 for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
1717 UCHAR mapValue = FDK_chMapDescr_getMapValue(
1718 &self->mapDescr, (UCHAR)ch, self->chMapIndex);
1719 if (mapValue < (8)) reverseInChannelMap[mapValue] = ch;
1720 }
1721 for (ch = 0; ch < (int)numDrcOutChannels; ch++) {
1722 UCHAR mapValue = FDK_chMapDescr_getMapValue(
1723 &self->mapDescr, (UCHAR)ch, numDrcOutChannels);
1724 if (mapValue < (8)) reverseOutChannelMap[mapValue] = ch;
1725 }
1726
1727 /* The output of SBR and MPS is interleaved. Deinterleaving may be
1728 * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved
1729 * audio only. */
1730 if ((self->streamInfo.numChannels > 1) &&
1731 (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
1732 /* interleaving/deinterleaving is performed on upper part of
1733 * pTimeData2. Check if this buffer is large enough. */
1734 if (timeData2Size < (INT)(2 * self->streamInfo.numChannels *
1735 self->streamInfo.frameSize)) {
1736 ErrorStatus = AAC_DEC_UNKNOWN;
1737 goto bail;
1738 }
1739 needsDeinterleaving = 1;
1740 drcWorkBuffer =
1741 (FIXP_DBL *)pTimeData2 +
1742 self->streamInfo.numChannels * self->streamInfo.frameSize;
1743 FDK_deinterleave(
1744 pTimeData2, drcWorkBuffer, self->streamInfo.numChannels,
1745 self->streamInfo.frameSize, self->streamInfo.frameSize);
1746 } else {
1747 drcWorkBuffer = pTimeData2;
1748 }
1749
1750 /* prepare Loudness Normalisation gain */
1751 FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_TARGET_LOUDNESS,
1752 (INT)-self->defaultTargetLoudness *
1753 FL2FXCONST_DBL(1.0f / (float)(1 << 9)));
1754 FDK_drcDec_SetChannelGains(self->hUniDrcDecoder,
1755 self->streamInfo.numChannels,
1756 self->streamInfo.frameSize, channelGain,
1757 drcWorkBuffer, self->streamInfo.frameSize);
1758 FDK_drcDec_Preprocess(self->hUniDrcDecoder);
1759
1760 /* apply DRC1 gain sequence */
1761 for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
1762 FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1,
1763 ch, reverseInChannelMap[ch] - ch, 1,
1764 drcWorkBuffer, self->streamInfo.frameSize);
1765 }
1766 /* apply downmix */
1767 FDK_drcDec_ApplyDownmix(
1768 self->hUniDrcDecoder, reverseInChannelMap, reverseOutChannelMap,
1769 drcWorkBuffer,
1770 &self->streamInfo.numChannels); /* self->streamInfo.numChannels
1771 may change here */
1772 /* apply DRC2/3 gain sequence */
1773 for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
1774 FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay,
1775 DRC_DEC_DRC2_DRC3, ch,
1776 reverseOutChannelMap[ch] - ch, 1,
1777 drcWorkBuffer, self->streamInfo.frameSize);
1778 }
1779
1780 if (needsDeinterleaving) {
1781 FDK_interleave(
1782 drcWorkBuffer, pTimeData2, self->streamInfo.numChannels,
1783 self->streamInfo.frameSize, self->streamInfo.frameSize);
1784 }
1785 }
1786 }
1787 if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) {
1788 /* return output loudness information for MPEG-D DRC */
1789 LONG outputLoudness =
1790 FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS);
1791 if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) {
1792 /* no valid MPEG-D DRC loudness value contained */
1793 self->streamInfo.outputLoudness = -1;
1794 } else {
1795 if (outputLoudness > 0) {
1796 /* positive output loudness values (very unusual) are limited to 0
1797 * dB */
1798 self->streamInfo.outputLoudness = 0;
1799 } else {
1800 self->streamInfo.outputLoudness =
1801 -(INT)outputLoudness >>
1802 22; /* negate and scale from e = 7 to e = (31-2) */
1803 }
1804 }
1805 } else {
1806 /* return output loudness information for MPEG-4 DRC */
1807 if (self->streamInfo.drcProgRefLev <
1808 0) { /* no MPEG-4 DRC loudness metadata contained */
1809 self->streamInfo.outputLoudness = -1;
1810 } else {
1811 if (self->defaultTargetLoudness <
1812 0) { /* loudness normalization is off */
1813 self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev;
1814 } else {
1815 self->streamInfo.outputLoudness = self->defaultTargetLoudness;
1816 }
1817 }
1818 }
1819
1820 if (self->streamInfo.extAot != AOT_AAC_SLS) {
1821 interleaved = 0;
1822 interleaved |= (self->sbrEnabled) ? 1 : 0;
1823 interleaved |= (self->mpsEnableCurr) ? 1 : 0;
1824 PCMDMX_ERROR dmxErr = PCMDMX_OK;
1825 if ((flags & AACDEC_INTR) && (accessUnit == 0)) {
1826 /* delete data from the past (e.g. mixdown coeficients) */
1827 pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
1828 }
1829 if (flags & (AACDEC_CLRHIST)) {
1830 if (!(self->flags[0] & AC_USAC)) {
1831 /* delete data from the past (e.g. mixdown coeficients) */
1832 pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
1833 }
1834 }
1835
1836 /* do PCM post processing */
1837 dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size,
1838 self->streamInfo.frameSize,
1839 &self->streamInfo.numChannels, interleaved,
1840 self->channelType, self->channelIndices,
1841 &self->mapDescr, &pcmLimiterScale);
1842 if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
1843 ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
1844 goto bail;
1845 }
1846 if ((ErrorStatus == AAC_DEC_OK) && (dmxErr == PCMDMX_INVALID_MODE)) {
1847 /* Announce the framework that the current combination of channel
1848 * configuration and downmix settings are not know to produce a
1849 * predictable behavior and thus maybe produce strange output. */
1850 ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
1851 }
1852 }
1853
1854 if (self->flags[0] & AC_USAC) {
1855 if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
1856 !(flags & AACDEC_CONCEAL)) {
1857 CAacDecoder_PrepareCrossFade(pTimeData2, self->pTimeDataFlush,
1858 self->streamInfo.numChannels,
1859 self->streamInfo.frameSize, interleaved);
1860 }
1861
1862 /* prepare crossfade buffer for fade in */
1863 if (!applyCrossfade &&
1864 (self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) &&
1865 !(flags & AACDEC_CONCEAL)) {
1866 for (int ch = 0; ch < self->streamInfo.numChannels; ch++) {
1867 for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
1868 self->pTimeDataFlush[ch][i] = (PCM_DEC)0;
1869 }
1870 }
1871 applyCrossfade = 1;
1872 }
1873
1874 if (applyCrossfade &&
1875 (self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) &&
1876 !(accessUnit < numPrerollAU) &&
1877 (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
1878 CAacDecoder_ApplyCrossFade(pTimeData2, self->pTimeDataFlush,
1879 self->streamInfo.numChannels,
1880 self->streamInfo.frameSize, interleaved);
1881 self->applyCrossfade =
1882 AACDEC_CROSSFADE_BITMASK_OFF; /* disable cross-fade between frames
1883 at nect config change */
1884 }
1885 }
1886
1887 /* Signal interruption to take effect in next frame. */
1888 if ((flags & AACDEC_FLUSH || self->flushStatus) &&
1889 !(flags & AACDEC_CONCEAL)) {
1890 aacDecoder_SignalInterruption(self);
1891 }
1892
1893 /* Update externally visible copy of flags */
1894 self->streamInfo.flags = self->flags[0];
1895
1896 } /* USAC DASH IPF flushing possible end */
1897 if (accessUnit < numPrerollAU) {
1898 FDKpushBack(hBsAu, auStartAnchor - (INT)FDKgetValidBits(hBsAu));
1899 } else {
1900 if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
1901 (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
1902 (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
1903 self->buildUpCnt--;
1904
1905 if (self->buildUpCnt < 0) {
1906 self->buildUpStatus = 0;
1907 }
1908 }
1909
1910 if (self->flags[0] & AC_USAC) {
1911 if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
1912 !(flags & AACDEC_CONCEAL)) {
1913 self->streamInfo.frameSize = 0;
1914 }
1915 }
1916 }
1917
1918 if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) {
1919 accessUnit++;
1920 }
1921 } while ((accessUnit < numAccessUnits) ||
1922 ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
1923 !(flags & AACDEC_CONCEAL)));
1924
1925 if (self->streamInfo.extAot != AOT_AAC_SLS) {
1926 pcmLimiterScale += PCM_OUT_HEADROOM;
1927
1928 if (flags & AACDEC_CLRHIST) {
1929 if (!(self->flags[0] & AC_USAC)) {
1930 /* Reset DRC data */
1931 aacDecoder_drcReset(self->hDrcInfo);
1932 /* Delete the delayed signal. */
1933 pcmLimiter_Reset(self->hLimiter);
1934 }
1935 }
1936
1937 /* Set applyExtGain if DRC processing is enabled and if progRefLevelPresent
1938 is present for the first time. Consequences: The headroom of the output
1939 signal can be set to AACDEC_DRC_GAIN_SCALING only for audio formats which
1940 support legacy DRC Level Normalization. For all other audio formats the
1941 headroom of the output signal is set to PCM_OUT_HEADROOM. */
1942 if (self->hDrcInfo->enable && (self->hDrcInfo->progRefLevelPresent == 1)) {
1943 self->hDrcInfo->applyExtGain |= 1;
1944 }
1945
1946 /* Check whether time data buffer is large enough. */
1947 if (timeDataSize <
1948 (self->streamInfo.numChannels * self->streamInfo.frameSize)) {
1949 ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
1950 goto bail;
1951 }
1952
1953 if (self->limiterEnableCurr) {
1954 /* use workBufferCore2 buffer for interleaving */
1955 PCM_LIM *pInterleaveBuffer;
1956 int blockLength = self->streamInfo.frameSize;
1957
1958 /* Set actual signal parameters */
1959 pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
1960 pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
1961
1962 if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
1963 (self->mpsEnableCurr)) {
1964 pInterleaveBuffer = (PCM_LIM *)pTimeData2;
1965 } else {
1966 pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2;
1967
1968 /* applyLimiter requests for interleaved data */
1969 /* Interleave ouput buffer */
1970 FDK_interleave(pTimeData2, pInterleaveBuffer,
1971 self->streamInfo.numChannels, blockLength,
1972 self->streamInfo.frameSize);
1973 }
1974
1975 FIXP_DBL *pGainPerSample = NULL;
1976
1977 if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
1978 pGainPerSample = self->workBufferCore1;
1979
1980 if ((INT)GetRequiredMemWorkBufferCore1() <
1981 (INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) {
1982 ErrorStatus = AAC_DEC_UNKNOWN;
1983 goto bail;
1984 }
1985
1986 pcmLimiterScale = applyDrcLevelNormalization(
1987 self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain,
1988 pGainPerSample, pcmLimiterScale, self->extGainDelay,
1989 self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1);
1990 }
1991
1992 pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
1993 pGainPerSample, pcmLimiterScale,
1994 self->streamInfo.frameSize);
1995
1996 {
1997 /* Announce the additional limiter output delay */
1998 self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
1999 }
2000 } else {
2001 if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
2002 pcmLimiterScale = applyDrcLevelNormalization(
2003 self->hDrcInfo, pTimeData2, self->extGain, NULL, pcmLimiterScale,
2004 self->extGainDelay, self->streamInfo.frameSize,
2005 self->streamInfo.numChannels,
2006 (interleaved || (self->streamInfo.numChannels == 1))
2007 ? 1
2008 : self->streamInfo.frameSize,
2009 0);
2010 }
2011
2012 /* If numChannels = 1 we do not need interleaving. The same applies if SBR
2013 or MPS are used, since their output is interleaved already (resampled or
2014 not) */
2015 if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
2016 (self->mpsEnableCurr)) {
2017 scaleValuesSaturate(
2018 pTimeData, pTimeData2,
2019 self->streamInfo.frameSize * self->streamInfo.numChannels,
2020 pcmLimiterScale);
2021
2022 } else {
2023 scaleValuesSaturate(
2024 (INT_PCM *)self->workBufferCore2, pTimeData2,
2025 self->streamInfo.frameSize * self->streamInfo.numChannels,
2026 pcmLimiterScale);
2027 /* Interleave ouput buffer */
2028 FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
2029 self->streamInfo.numChannels, self->streamInfo.frameSize,
2030 self->streamInfo.frameSize);
2031 }
2032 }
2033 } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/
2034
2035 bail:
2036
2037 /* error in renderer part occurred, ErrorStatus was set to invalid output */
2038 if (fEndAuNotAdjusted && !IS_OUTPUT_VALID(ErrorStatus) &&
2039 (accessUnit < numPrerollAU)) {
2040 transportDec_EndAccessUnit(self->hInput);
2041 }
2042
2043 /* Update Statistics */
2044 aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits,
2045 ErrorStatus);
2046 if (((self->streamInfo.numChannels <= 0) ||
2047 (self->streamInfo.frameSize <= 0) ||
2048 (self->streamInfo.sampleRate <= 0)) &&
2049 IS_OUTPUT_VALID(ErrorStatus)) {
2050 /* Ensure consistency of IS_OUTPUT_VALID() macro. */
2051 ErrorStatus = AAC_DEC_UNKNOWN;
2052 }
2053
2054 if (!IS_OUTPUT_VALID(ErrorStatus)) {
2055 FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData));
2056 }
2057
2058 return ErrorStatus;
2059 }
2060
aacDecoder_Close(HANDLE_AACDECODER self)2061 LINKSPEC_CPP void aacDecoder_Close(HANDLE_AACDECODER self) {
2062 if (self == NULL) return;
2063
2064 if (self->hLimiter != NULL) {
2065 pcmLimiter_Destroy(self->hLimiter);
2066 }
2067
2068 if (self->hPcmUtils != NULL) {
2069 pcmDmx_Close(&self->hPcmUtils);
2070 }
2071
2072 FDK_drcDec_Close(&self->hUniDrcDecoder);
2073
2074 if (self->pMpegSurroundDecoder != NULL) {
2075 mpegSurroundDecoder_Close(
2076 (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
2077 }
2078
2079 if (self->hSbrDecoder != NULL) {
2080 sbrDecoder_Close(&self->hSbrDecoder);
2081 }
2082
2083 if (self->hInput != NULL) {
2084 transportDec_Close(&self->hInput);
2085 }
2086
2087 CAacDecoder_Close(self);
2088 }
2089
aacDecoder_GetStreamInfo(HANDLE_AACDECODER self)2090 LINKSPEC_CPP CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
2091 return CAacDecoder_GetStreamInfo(self);
2092 }
2093
aacDecoder_GetLibInfo(LIB_INFO * info)2094 LINKSPEC_CPP INT aacDecoder_GetLibInfo(LIB_INFO *info) {
2095 int i;
2096
2097 if (info == NULL) {
2098 return -1;
2099 }
2100
2101 sbrDecoder_GetLibInfo(info);
2102 mpegSurroundDecoder_GetLibInfo(info);
2103 transportDec_GetLibInfo(info);
2104 FDK_toolsGetLibInfo(info);
2105 pcmDmx_GetLibInfo(info);
2106 pcmLimiter_GetLibInfo(info);
2107 FDK_drcDec_GetLibInfo(info);
2108
2109 /* search for next free tab */
2110 for (i = 0; i < FDK_MODULE_LAST; i++) {
2111 if (info[i].module_id == FDK_NONE) break;
2112 }
2113 if (i == FDK_MODULE_LAST) {
2114 return -1;
2115 }
2116 info += i;
2117
2118 info->module_id = FDK_AACDEC;
2119 /* build own library info */
2120 info->version =
2121 LIB_VERSION(AACDECODER_LIB_VL0, AACDECODER_LIB_VL1, AACDECODER_LIB_VL2);
2122 LIB_VERSION_STRING(info);
2123 info->build_date = AACDECODER_LIB_BUILD_DATE;
2124 info->build_time = AACDECODER_LIB_BUILD_TIME;
2125 info->title = AACDECODER_LIB_TITLE;
2126
2127 /* Set flags */
2128 info->flags = 0 | CAPF_AAC_LC | CAPF_ER_AAC_LC | CAPF_ER_AAC_SCAL |
2129 CAPF_AAC_VCB11 | CAPF_AAC_HCR | CAPF_AAC_RVLC | CAPF_ER_AAC_LD |
2130 CAPF_ER_AAC_ELD | CAPF_AAC_CONCEALMENT | CAPF_AAC_DRC |
2131 CAPF_AAC_MPEG4 | CAPF_AAC_DRM_BSFORMAT | CAPF_AAC_1024 |
2132 CAPF_AAC_960 | CAPF_AAC_512 | CAPF_AAC_480 |
2133 CAPF_AAC_ELD_DOWNSCALE
2134
2135 | CAPF_AAC_USAC | CAPF_ER_AAC_ELDV2 | CAPF_AAC_UNIDRC;
2136 /* End of flags */
2137
2138 return 0;
2139 }
2140