• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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