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