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): Josef Hoepfl
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 /*!
104*e5436536SAndroid Build Coastguard Worker \page default General Overview of the AAC Decoder Implementation
105*e5436536SAndroid Build Coastguard Worker
106*e5436536SAndroid Build Coastguard Worker The main entry point to decode a AAC frame is CAacDecoder_DecodeFrame(). It
107*e5436536SAndroid Build Coastguard Worker handles the different transport multiplexes and bitstream formats supported by
108*e5436536SAndroid Build Coastguard Worker this implementation. It extracts the AAC_raw_data_blocks from these bitstreams
109*e5436536SAndroid Build Coastguard Worker to further process then in the actual decoding stages.
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker Note: Click on a function of file in the above image to see details about the
112*e5436536SAndroid Build Coastguard Worker function. Also note, that this is just an overview of the most important
113*e5436536SAndroid Build Coastguard Worker functions and not a complete call graph.
114*e5436536SAndroid Build Coastguard Worker
115*e5436536SAndroid Build Coastguard Worker <h2>1 Bitstream deformatter</h2>
116*e5436536SAndroid Build Coastguard Worker The basic bit stream parser function CChannelElement_Read() is called. It uses
117*e5436536SAndroid Build Coastguard Worker other subcalls in order to parse and unpack the bitstreams. Note, that this
118*e5436536SAndroid Build Coastguard Worker includes huffmann decoding of the coded spectral data. This operation can be
119*e5436536SAndroid Build Coastguard Worker computational significant specifically at higher bitrates. Optimization is
120*e5436536SAndroid Build Coastguard Worker likely in CBlock_ReadSpectralData().
121*e5436536SAndroid Build Coastguard Worker
122*e5436536SAndroid Build Coastguard Worker The bitstream deformatter also includes many bitfield operations. Profiling on
123*e5436536SAndroid Build Coastguard Worker the target will determine required optimizations.
124*e5436536SAndroid Build Coastguard Worker
125*e5436536SAndroid Build Coastguard Worker <h2>2 Actual decoding to retain the time domain output</h2>
126*e5436536SAndroid Build Coastguard Worker The basic bitstream deformatter function CChannelElement_Decode() for CPE
127*e5436536SAndroid Build Coastguard Worker elements and SCE elements are called. Except for the stereo processing (2.1)
128*e5436536SAndroid Build Coastguard Worker which is only used for CPE elements, the function calls for CPE or SCE are
129*e5436536SAndroid Build Coastguard Worker similar, except that CPE always processes to independent channels while SCE
130*e5436536SAndroid Build Coastguard Worker only processes one channel.
131*e5436536SAndroid Build Coastguard Worker
132*e5436536SAndroid Build Coastguard Worker Often there is the distinction between long blocks and short blocks. However,
133*e5436536SAndroid Build Coastguard Worker computational expensive functions that ususally require optimization are being
134*e5436536SAndroid Build Coastguard Worker shared by these two groups,
135*e5436536SAndroid Build Coastguard Worker
136*e5436536SAndroid Build Coastguard Worker <h3>2.1 Stereo processing for CPE elements</h3>
137*e5436536SAndroid Build Coastguard Worker CChannelPairElement_Decode() first calles the joint stereo tools in
138*e5436536SAndroid Build Coastguard Worker stereo.cpp when required.
139*e5436536SAndroid Build Coastguard Worker
140*e5436536SAndroid Build Coastguard Worker <h3>2.2 Scaling of spectral data</h3>
141*e5436536SAndroid Build Coastguard Worker CBlock_ScaleSpectralData().
142*e5436536SAndroid Build Coastguard Worker
143*e5436536SAndroid Build Coastguard Worker <h3>2.3 Apply additional coding tools</h3>
144*e5436536SAndroid Build Coastguard Worker ApplyTools() calles the PNS tools in case of MPEG-4 bitstreams, and TNS
145*e5436536SAndroid Build Coastguard Worker filtering CTns_Apply() for MPEG-2 and MPEG-4 bitstreams. The function
146*e5436536SAndroid Build Coastguard Worker TnsFilterIIR() which is called by CTns_Apply() (2.3.1) might require some
147*e5436536SAndroid Build Coastguard Worker optimization.
148*e5436536SAndroid Build Coastguard Worker
149*e5436536SAndroid Build Coastguard Worker <h2>3 Frequency-To-Time conversion</h3>
150*e5436536SAndroid Build Coastguard Worker The filterbank is called using CBlock_FrequencyToTime() using the MDCT module
151*e5436536SAndroid Build Coastguard Worker from the FDK Tools
152*e5436536SAndroid Build Coastguard Worker
153*e5436536SAndroid Build Coastguard Worker */
154*e5436536SAndroid Build Coastguard Worker
155*e5436536SAndroid Build Coastguard Worker #include "aacdecoder.h"
156*e5436536SAndroid Build Coastguard Worker
157*e5436536SAndroid Build Coastguard Worker #include "aac_rom.h"
158*e5436536SAndroid Build Coastguard Worker #include "aac_ram.h"
159*e5436536SAndroid Build Coastguard Worker #include "channel.h"
160*e5436536SAndroid Build Coastguard Worker #include "FDK_audio.h"
161*e5436536SAndroid Build Coastguard Worker
162*e5436536SAndroid Build Coastguard Worker #include "aacdec_pns.h"
163*e5436536SAndroid Build Coastguard Worker
164*e5436536SAndroid Build Coastguard Worker #include "sbrdecoder.h"
165*e5436536SAndroid Build Coastguard Worker
166*e5436536SAndroid Build Coastguard Worker #include "sac_dec_lib.h"
167*e5436536SAndroid Build Coastguard Worker
168*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr.h"
169*e5436536SAndroid Build Coastguard Worker #include "rvlc.h"
170*e5436536SAndroid Build Coastguard Worker
171*e5436536SAndroid Build Coastguard Worker #include "usacdec_lpd.h"
172*e5436536SAndroid Build Coastguard Worker
173*e5436536SAndroid Build Coastguard Worker #include "ac_arith_coder.h"
174*e5436536SAndroid Build Coastguard Worker
175*e5436536SAndroid Build Coastguard Worker #include "tpdec_lib.h"
176*e5436536SAndroid Build Coastguard Worker
177*e5436536SAndroid Build Coastguard Worker #include "conceal.h"
178*e5436536SAndroid Build Coastguard Worker
179*e5436536SAndroid Build Coastguard Worker #include "FDK_crc.h"
180*e5436536SAndroid Build Coastguard Worker #define PS_IS_EXPLICITLY_DISABLED(aot, flags) \
181*e5436536SAndroid Build Coastguard Worker (((aot) == AOT_DRM_AAC) && !(flags & AC_PS_PRESENT))
182*e5436536SAndroid Build Coastguard Worker
183*e5436536SAndroid Build Coastguard Worker #define IS_STEREO_SBR(el_id, stereoConfigIndex) \
184*e5436536SAndroid Build Coastguard Worker (((el_id) == ID_USAC_CPE && (stereoConfigIndex) == 0) || \
185*e5436536SAndroid Build Coastguard Worker ((el_id) == ID_USAC_CPE && (stereoConfigIndex) == 3))
186*e5436536SAndroid Build Coastguard Worker
CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self)187*e5436536SAndroid Build Coastguard Worker void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self) {
188*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(
189*e5436536SAndroid Build Coastguard Worker !((self->flags[0] & AC_MPS_PRESENT) && (self->flags[0] & AC_PS_PRESENT)));
190*e5436536SAndroid Build Coastguard Worker
191*e5436536SAndroid Build Coastguard Worker /* Assign user requested mode */
192*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr = self->qmfModeUser;
193*e5436536SAndroid Build Coastguard Worker
194*e5436536SAndroid Build Coastguard Worker if (IS_USAC(self->streamInfo.aot)) {
195*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr = MODE_HQ;
196*e5436536SAndroid Build Coastguard Worker }
197*e5436536SAndroid Build Coastguard Worker
198*e5436536SAndroid Build Coastguard Worker if (self->qmfModeCurr == NOT_DEFINED) {
199*e5436536SAndroid Build Coastguard Worker if ((IS_LOWDELAY(self->streamInfo.aot) &&
200*e5436536SAndroid Build Coastguard Worker (self->flags[0] & AC_MPS_PRESENT)) ||
201*e5436536SAndroid Build Coastguard Worker ((self->streamInfo.aacNumChannels == 1) &&
202*e5436536SAndroid Build Coastguard Worker ((CAN_DO_PS(self->streamInfo.aot) &&
203*e5436536SAndroid Build Coastguard Worker !(self->flags[0] & AC_MPS_PRESENT)) ||
204*e5436536SAndroid Build Coastguard Worker (IS_USAC(self->streamInfo.aot))))) {
205*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr = MODE_HQ;
206*e5436536SAndroid Build Coastguard Worker } else {
207*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr = MODE_LP;
208*e5436536SAndroid Build Coastguard Worker }
209*e5436536SAndroid Build Coastguard Worker }
210*e5436536SAndroid Build Coastguard Worker
211*e5436536SAndroid Build Coastguard Worker if (self->mpsEnableCurr) {
212*e5436536SAndroid Build Coastguard Worker if (IS_LOWDELAY(self->streamInfo.aot) &&
213*e5436536SAndroid Build Coastguard Worker (self->qmfModeCurr == MODE_LP)) { /* Overrule user requested QMF mode */
214*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr = MODE_HQ;
215*e5436536SAndroid Build Coastguard Worker }
216*e5436536SAndroid Build Coastguard Worker /* Set and check if MPS decoder allows the current mode */
217*e5436536SAndroid Build Coastguard Worker switch (mpegSurroundDecoder_SetParam(
218*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
219*e5436536SAndroid Build Coastguard Worker SACDEC_PARTIALLY_COMPLEX, self->qmfModeCurr == MODE_LP)) {
220*e5436536SAndroid Build Coastguard Worker case MPS_OK:
221*e5436536SAndroid Build Coastguard Worker break;
222*e5436536SAndroid Build Coastguard Worker case MPS_INVALID_PARAMETER: { /* Only one mode supported. Find out which
223*e5436536SAndroid Build Coastguard Worker one: */
224*e5436536SAndroid Build Coastguard Worker LIB_INFO libInfo[FDK_MODULE_LAST];
225*e5436536SAndroid Build Coastguard Worker UINT mpsCaps;
226*e5436536SAndroid Build Coastguard Worker
227*e5436536SAndroid Build Coastguard Worker FDKinitLibInfo(libInfo);
228*e5436536SAndroid Build Coastguard Worker mpegSurroundDecoder_GetLibInfo(libInfo);
229*e5436536SAndroid Build Coastguard Worker mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);
230*e5436536SAndroid Build Coastguard Worker
231*e5436536SAndroid Build Coastguard Worker if (((mpsCaps & CAPF_MPS_LP) && (self->qmfModeCurr == MODE_LP)) ||
232*e5436536SAndroid Build Coastguard Worker ((mpsCaps & CAPF_MPS_HQ) &&
233*e5436536SAndroid Build Coastguard Worker (self->qmfModeCurr ==
234*e5436536SAndroid Build Coastguard Worker MODE_HQ))) { /* MPS decoder does support the requested mode. */
235*e5436536SAndroid Build Coastguard Worker break;
236*e5436536SAndroid Build Coastguard Worker }
237*e5436536SAndroid Build Coastguard Worker }
238*e5436536SAndroid Build Coastguard Worker FDK_FALLTHROUGH;
239*e5436536SAndroid Build Coastguard Worker default:
240*e5436536SAndroid Build Coastguard Worker if (self->qmfModeUser == NOT_DEFINED) {
241*e5436536SAndroid Build Coastguard Worker /* Revert in case mpegSurroundDecoder_SetParam() fails. */
242*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr =
243*e5436536SAndroid Build Coastguard Worker (self->qmfModeCurr == MODE_LP) ? MODE_HQ : MODE_LP;
244*e5436536SAndroid Build Coastguard Worker } else {
245*e5436536SAndroid Build Coastguard Worker /* in case specific mode was requested we disable MPS and playout the
246*e5436536SAndroid Build Coastguard Worker * downmix */
247*e5436536SAndroid Build Coastguard Worker self->mpsEnableCurr = 0;
248*e5436536SAndroid Build Coastguard Worker }
249*e5436536SAndroid Build Coastguard Worker }
250*e5436536SAndroid Build Coastguard Worker }
251*e5436536SAndroid Build Coastguard Worker
252*e5436536SAndroid Build Coastguard Worker /* Set SBR to current QMF mode. Error does not matter. */
253*e5436536SAndroid Build Coastguard Worker sbrDecoder_SetParam(self->hSbrDecoder, SBR_QMF_MODE,
254*e5436536SAndroid Build Coastguard Worker (self->qmfModeCurr == MODE_LP));
255*e5436536SAndroid Build Coastguard Worker self->psPossible =
256*e5436536SAndroid Build Coastguard Worker ((CAN_DO_PS(self->streamInfo.aot) &&
257*e5436536SAndroid Build Coastguard Worker !PS_IS_EXPLICITLY_DISABLED(self->streamInfo.aot, self->flags[0]) &&
258*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacNumChannels == 1 &&
259*e5436536SAndroid Build Coastguard Worker !(self->flags[0] & AC_MPS_PRESENT))) &&
260*e5436536SAndroid Build Coastguard Worker self->qmfModeCurr == MODE_HQ;
261*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(!((self->flags[0] & AC_MPS_PRESENT) && self->psPossible));
262*e5436536SAndroid Build Coastguard Worker }
263*e5436536SAndroid Build Coastguard Worker
CAacDecoder_SignalInterruption(HANDLE_AACDECODER self)264*e5436536SAndroid Build Coastguard Worker void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
265*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
266*e5436536SAndroid Build Coastguard Worker int i;
267*e5436536SAndroid Build Coastguard Worker
268*e5436536SAndroid Build Coastguard Worker for (i = 0; i < fMin(self->aacChannels, (8)); i++) {
269*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo
270*e5436536SAndroid Build Coastguard Worker [i]) { /* number of active channels can be smaller */
271*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[i]->hArCo->m_numberLinesPrev = 0;
272*e5436536SAndroid Build Coastguard Worker }
273*e5436536SAndroid Build Coastguard Worker }
274*e5436536SAndroid Build Coastguard Worker }
275*e5436536SAndroid Build Coastguard Worker }
276*e5436536SAndroid Build Coastguard Worker
277*e5436536SAndroid Build Coastguard Worker /*!
278*e5436536SAndroid Build Coastguard Worker \brief Calculates the number of element channels
279*e5436536SAndroid Build Coastguard Worker
280*e5436536SAndroid Build Coastguard Worker \type channel type
281*e5436536SAndroid Build Coastguard Worker \usacStereoConfigIndex usac stereo config index
282*e5436536SAndroid Build Coastguard Worker
283*e5436536SAndroid Build Coastguard Worker \return element channels
284*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_GetELChannels(MP4_ELEMENT_ID type,UCHAR usacStereoConfigIndex)285*e5436536SAndroid Build Coastguard Worker static int CAacDecoder_GetELChannels(MP4_ELEMENT_ID type,
286*e5436536SAndroid Build Coastguard Worker UCHAR usacStereoConfigIndex) {
287*e5436536SAndroid Build Coastguard Worker int el_channels = 0;
288*e5436536SAndroid Build Coastguard Worker
289*e5436536SAndroid Build Coastguard Worker switch (type) {
290*e5436536SAndroid Build Coastguard Worker case ID_USAC_CPE:
291*e5436536SAndroid Build Coastguard Worker if (usacStereoConfigIndex == 1) {
292*e5436536SAndroid Build Coastguard Worker el_channels = 1;
293*e5436536SAndroid Build Coastguard Worker } else {
294*e5436536SAndroid Build Coastguard Worker el_channels = 2;
295*e5436536SAndroid Build Coastguard Worker }
296*e5436536SAndroid Build Coastguard Worker break;
297*e5436536SAndroid Build Coastguard Worker case ID_CPE:
298*e5436536SAndroid Build Coastguard Worker el_channels = 2;
299*e5436536SAndroid Build Coastguard Worker break;
300*e5436536SAndroid Build Coastguard Worker case ID_USAC_SCE:
301*e5436536SAndroid Build Coastguard Worker case ID_USAC_LFE:
302*e5436536SAndroid Build Coastguard Worker case ID_SCE:
303*e5436536SAndroid Build Coastguard Worker case ID_LFE:
304*e5436536SAndroid Build Coastguard Worker el_channels = 1;
305*e5436536SAndroid Build Coastguard Worker break;
306*e5436536SAndroid Build Coastguard Worker default:
307*e5436536SAndroid Build Coastguard Worker el_channels = 0;
308*e5436536SAndroid Build Coastguard Worker break;
309*e5436536SAndroid Build Coastguard Worker }
310*e5436536SAndroid Build Coastguard Worker
311*e5436536SAndroid Build Coastguard Worker return el_channels;
312*e5436536SAndroid Build Coastguard Worker }
313*e5436536SAndroid Build Coastguard Worker
314*e5436536SAndroid Build Coastguard Worker /*!
315*e5436536SAndroid Build Coastguard Worker \brief Reset ancillary data struct. Call before parsing a new frame.
316*e5436536SAndroid Build Coastguard Worker
317*e5436536SAndroid Build Coastguard Worker \ancData Pointer to ancillary data structure
318*e5436536SAndroid Build Coastguard Worker
319*e5436536SAndroid Build Coastguard Worker \return Error code
320*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_AncDataReset(CAncData * ancData)321*e5436536SAndroid Build Coastguard Worker static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData) {
322*e5436536SAndroid Build Coastguard Worker int i;
323*e5436536SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
324*e5436536SAndroid Build Coastguard Worker ancData->offset[i] = 0;
325*e5436536SAndroid Build Coastguard Worker }
326*e5436536SAndroid Build Coastguard Worker ancData->nrElements = 0;
327*e5436536SAndroid Build Coastguard Worker
328*e5436536SAndroid Build Coastguard Worker return AAC_DEC_OK;
329*e5436536SAndroid Build Coastguard Worker }
330*e5436536SAndroid Build Coastguard Worker
331*e5436536SAndroid Build Coastguard Worker /*!
332*e5436536SAndroid Build Coastguard Worker \brief Initialize ancillary buffer
333*e5436536SAndroid Build Coastguard Worker
334*e5436536SAndroid Build Coastguard Worker \ancData Pointer to ancillary data structure
335*e5436536SAndroid Build Coastguard Worker \buffer Pointer to (external) anc data buffer
336*e5436536SAndroid Build Coastguard Worker \size Size of the buffer pointed on by buffer in bytes
337*e5436536SAndroid Build Coastguard Worker
338*e5436536SAndroid Build Coastguard Worker \return Error code
339*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_AncDataInit(CAncData * ancData,unsigned char * buffer,int size)340*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData,
341*e5436536SAndroid Build Coastguard Worker unsigned char *buffer, int size) {
342*e5436536SAndroid Build Coastguard Worker if (size >= 0) {
343*e5436536SAndroid Build Coastguard Worker ancData->buffer = buffer;
344*e5436536SAndroid Build Coastguard Worker ancData->bufferSize = size;
345*e5436536SAndroid Build Coastguard Worker
346*e5436536SAndroid Build Coastguard Worker CAacDecoder_AncDataReset(ancData);
347*e5436536SAndroid Build Coastguard Worker
348*e5436536SAndroid Build Coastguard Worker return AAC_DEC_OK;
349*e5436536SAndroid Build Coastguard Worker }
350*e5436536SAndroid Build Coastguard Worker
351*e5436536SAndroid Build Coastguard Worker return AAC_DEC_ANC_DATA_ERROR;
352*e5436536SAndroid Build Coastguard Worker }
353*e5436536SAndroid Build Coastguard Worker
354*e5436536SAndroid Build Coastguard Worker /*!
355*e5436536SAndroid Build Coastguard Worker \brief Get one ancillary data element
356*e5436536SAndroid Build Coastguard Worker
357*e5436536SAndroid Build Coastguard Worker \ancData Pointer to ancillary data structure
358*e5436536SAndroid Build Coastguard Worker \index Index of the anc data element to get
359*e5436536SAndroid Build Coastguard Worker \ptr Pointer to a buffer receiving a pointer to the requested anc data element
360*e5436536SAndroid Build Coastguard Worker \size Pointer to a buffer receiving the length of the requested anc data
361*e5436536SAndroid Build Coastguard Worker element in bytes
362*e5436536SAndroid Build Coastguard Worker
363*e5436536SAndroid Build Coastguard Worker \return Error code
364*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_AncDataGet(CAncData * ancData,int index,unsigned char ** ptr,int * size)365*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index,
366*e5436536SAndroid Build Coastguard Worker unsigned char **ptr, int *size) {
367*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR error = AAC_DEC_OK;
368*e5436536SAndroid Build Coastguard Worker
369*e5436536SAndroid Build Coastguard Worker *ptr = NULL;
370*e5436536SAndroid Build Coastguard Worker *size = 0;
371*e5436536SAndroid Build Coastguard Worker
372*e5436536SAndroid Build Coastguard Worker if (index >= 0 && index < 8 - 1 && index < ancData->nrElements) {
373*e5436536SAndroid Build Coastguard Worker *ptr = &ancData->buffer[ancData->offset[index]];
374*e5436536SAndroid Build Coastguard Worker *size = ancData->offset[index + 1] - ancData->offset[index];
375*e5436536SAndroid Build Coastguard Worker }
376*e5436536SAndroid Build Coastguard Worker
377*e5436536SAndroid Build Coastguard Worker return error;
378*e5436536SAndroid Build Coastguard Worker }
379*e5436536SAndroid Build Coastguard Worker
380*e5436536SAndroid Build Coastguard Worker /*!
381*e5436536SAndroid Build Coastguard Worker \brief Parse ancillary data
382*e5436536SAndroid Build Coastguard Worker
383*e5436536SAndroid Build Coastguard Worker \ancData Pointer to ancillary data structure
384*e5436536SAndroid Build Coastguard Worker \hBs Handle to FDK bitstream
385*e5436536SAndroid Build Coastguard Worker \ancBytes Length of ancillary data to read from the bitstream
386*e5436536SAndroid Build Coastguard Worker
387*e5436536SAndroid Build Coastguard Worker \return Error code
388*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_AncDataParse(CAncData * ancData,HANDLE_FDK_BITSTREAM hBs,const int ancBytes)389*e5436536SAndroid Build Coastguard Worker static AAC_DECODER_ERROR CAacDecoder_AncDataParse(CAncData *ancData,
390*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs,
391*e5436536SAndroid Build Coastguard Worker const int ancBytes) {
392*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR error = AAC_DEC_OK;
393*e5436536SAndroid Build Coastguard Worker int readBytes = 0;
394*e5436536SAndroid Build Coastguard Worker
395*e5436536SAndroid Build Coastguard Worker if (ancData->buffer != NULL) {
396*e5436536SAndroid Build Coastguard Worker if (ancBytes > 0) {
397*e5436536SAndroid Build Coastguard Worker /* write ancillary data to external buffer */
398*e5436536SAndroid Build Coastguard Worker int offset = ancData->offset[ancData->nrElements];
399*e5436536SAndroid Build Coastguard Worker
400*e5436536SAndroid Build Coastguard Worker if ((offset + ancBytes) > ancData->bufferSize) {
401*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_TOO_SMALL_ANC_BUFFER;
402*e5436536SAndroid Build Coastguard Worker } else if (ancData->nrElements >= 8 - 1) {
403*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_TOO_MANY_ANC_ELEMENTS;
404*e5436536SAndroid Build Coastguard Worker } else {
405*e5436536SAndroid Build Coastguard Worker int i;
406*e5436536SAndroid Build Coastguard Worker
407*e5436536SAndroid Build Coastguard Worker for (i = 0; i < ancBytes; i++) {
408*e5436536SAndroid Build Coastguard Worker ancData->buffer[i + offset] = FDKreadBits(hBs, 8);
409*e5436536SAndroid Build Coastguard Worker readBytes++;
410*e5436536SAndroid Build Coastguard Worker }
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker ancData->nrElements++;
413*e5436536SAndroid Build Coastguard Worker ancData->offset[ancData->nrElements] =
414*e5436536SAndroid Build Coastguard Worker ancBytes + ancData->offset[ancData->nrElements - 1];
415*e5436536SAndroid Build Coastguard Worker }
416*e5436536SAndroid Build Coastguard Worker }
417*e5436536SAndroid Build Coastguard Worker }
418*e5436536SAndroid Build Coastguard Worker
419*e5436536SAndroid Build Coastguard Worker readBytes = ancBytes - readBytes;
420*e5436536SAndroid Build Coastguard Worker
421*e5436536SAndroid Build Coastguard Worker if (readBytes > 0) {
422*e5436536SAndroid Build Coastguard Worker /* skip data */
423*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, readBytes << 3);
424*e5436536SAndroid Build Coastguard Worker }
425*e5436536SAndroid Build Coastguard Worker
426*e5436536SAndroid Build Coastguard Worker return error;
427*e5436536SAndroid Build Coastguard Worker }
428*e5436536SAndroid Build Coastguard Worker
429*e5436536SAndroid Build Coastguard Worker /*!
430*e5436536SAndroid Build Coastguard Worker \brief Read Stream Data Element
431*e5436536SAndroid Build Coastguard Worker
432*e5436536SAndroid Build Coastguard Worker \bs Bitstream Handle
433*e5436536SAndroid Build Coastguard Worker
434*e5436536SAndroid Build Coastguard Worker \return Error code
435*e5436536SAndroid Build Coastguard Worker */
CDataStreamElement_Read(HANDLE_AACDECODER self,HANDLE_FDK_BITSTREAM bs,UCHAR * elementInstanceTag,UINT alignmentAnchor)436*e5436536SAndroid Build Coastguard Worker static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self,
437*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM bs,
438*e5436536SAndroid Build Coastguard Worker UCHAR *elementInstanceTag,
439*e5436536SAndroid Build Coastguard Worker UINT alignmentAnchor) {
440*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR error = AAC_DEC_OK;
441*e5436536SAndroid Build Coastguard Worker UINT dseBits;
442*e5436536SAndroid Build Coastguard Worker INT dataStart;
443*e5436536SAndroid Build Coastguard Worker int dataByteAlignFlag, count;
444*e5436536SAndroid Build Coastguard Worker
445*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self != NULL);
446*e5436536SAndroid Build Coastguard Worker
447*e5436536SAndroid Build Coastguard Worker int crcReg = transportDec_CrcStartReg(self->hInput, 0);
448*e5436536SAndroid Build Coastguard Worker
449*e5436536SAndroid Build Coastguard Worker /* Element Instance Tag */
450*e5436536SAndroid Build Coastguard Worker *elementInstanceTag = FDKreadBits(bs, 4);
451*e5436536SAndroid Build Coastguard Worker /* Data Byte Align Flag */
452*e5436536SAndroid Build Coastguard Worker dataByteAlignFlag = FDKreadBits(bs, 1);
453*e5436536SAndroid Build Coastguard Worker
454*e5436536SAndroid Build Coastguard Worker count = FDKreadBits(bs, 8);
455*e5436536SAndroid Build Coastguard Worker
456*e5436536SAndroid Build Coastguard Worker if (count == 255) {
457*e5436536SAndroid Build Coastguard Worker count += FDKreadBits(bs, 8); /* EscCount */
458*e5436536SAndroid Build Coastguard Worker }
459*e5436536SAndroid Build Coastguard Worker dseBits = count * 8;
460*e5436536SAndroid Build Coastguard Worker
461*e5436536SAndroid Build Coastguard Worker if (dataByteAlignFlag) {
462*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(bs, alignmentAnchor);
463*e5436536SAndroid Build Coastguard Worker }
464*e5436536SAndroid Build Coastguard Worker
465*e5436536SAndroid Build Coastguard Worker dataStart = (INT)FDKgetValidBits(bs);
466*e5436536SAndroid Build Coastguard Worker
467*e5436536SAndroid Build Coastguard Worker error = CAacDecoder_AncDataParse(&self->ancData, bs, count);
468*e5436536SAndroid Build Coastguard Worker transportDec_CrcEndReg(self->hInput, crcReg);
469*e5436536SAndroid Build Coastguard Worker
470*e5436536SAndroid Build Coastguard Worker {
471*e5436536SAndroid Build Coastguard Worker /* Move to the beginning of the data chunk */
472*e5436536SAndroid Build Coastguard Worker FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs));
473*e5436536SAndroid Build Coastguard Worker
474*e5436536SAndroid Build Coastguard Worker /* Read Anc data if available */
475*e5436536SAndroid Build Coastguard Worker aacDecoder_drcMarkPayload(self->hDrcInfo, bs, DVB_DRC_ANC_DATA);
476*e5436536SAndroid Build Coastguard Worker }
477*e5436536SAndroid Build Coastguard Worker
478*e5436536SAndroid Build Coastguard Worker {
479*e5436536SAndroid Build Coastguard Worker PCMDMX_ERROR dmxErr = PCMDMX_OK;
480*e5436536SAndroid Build Coastguard Worker
481*e5436536SAndroid Build Coastguard Worker /* Move to the beginning of the data chunk */
482*e5436536SAndroid Build Coastguard Worker FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs));
483*e5436536SAndroid Build Coastguard Worker
484*e5436536SAndroid Build Coastguard Worker /* Read DMX meta-data */
485*e5436536SAndroid Build Coastguard Worker dmxErr = pcmDmx_Parse(self->hPcmUtils, bs, dseBits, 0 /* not mpeg2 */);
486*e5436536SAndroid Build Coastguard Worker if (error == AAC_DEC_OK && dmxErr != PCMDMX_OK) {
487*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_UNKNOWN;
488*e5436536SAndroid Build Coastguard Worker }
489*e5436536SAndroid Build Coastguard Worker }
490*e5436536SAndroid Build Coastguard Worker
491*e5436536SAndroid Build Coastguard Worker /* Move to the very end of the element. */
492*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - dataStart + (INT)dseBits);
493*e5436536SAndroid Build Coastguard Worker
494*e5436536SAndroid Build Coastguard Worker return error;
495*e5436536SAndroid Build Coastguard Worker }
496*e5436536SAndroid Build Coastguard Worker
findElementInstanceTag(INT elementTag,MP4_ELEMENT_ID elementId,CAacDecoderChannelInfo ** pAacDecoderChannelInfo,INT nChannels,MP4_ELEMENT_ID * pElementIdTab,INT nElements)497*e5436536SAndroid Build Coastguard Worker static INT findElementInstanceTag(
498*e5436536SAndroid Build Coastguard Worker INT elementTag, MP4_ELEMENT_ID elementId,
499*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo **pAacDecoderChannelInfo, INT nChannels,
500*e5436536SAndroid Build Coastguard Worker MP4_ELEMENT_ID *pElementIdTab, INT nElements) {
501*e5436536SAndroid Build Coastguard Worker int el, chCnt = 0;
502*e5436536SAndroid Build Coastguard Worker
503*e5436536SAndroid Build Coastguard Worker for (el = 0; el < nElements; el++) {
504*e5436536SAndroid Build Coastguard Worker switch (pElementIdTab[el]) {
505*e5436536SAndroid Build Coastguard Worker case ID_CPE:
506*e5436536SAndroid Build Coastguard Worker case ID_SCE:
507*e5436536SAndroid Build Coastguard Worker case ID_LFE:
508*e5436536SAndroid Build Coastguard Worker if ((elementTag == pAacDecoderChannelInfo[chCnt]->ElementInstanceTag) &&
509*e5436536SAndroid Build Coastguard Worker (elementId == pElementIdTab[el])) {
510*e5436536SAndroid Build Coastguard Worker return 1; /* element instance tag found */
511*e5436536SAndroid Build Coastguard Worker }
512*e5436536SAndroid Build Coastguard Worker chCnt += (pElementIdTab[el] == ID_CPE) ? 2 : 1;
513*e5436536SAndroid Build Coastguard Worker break;
514*e5436536SAndroid Build Coastguard Worker default:
515*e5436536SAndroid Build Coastguard Worker break;
516*e5436536SAndroid Build Coastguard Worker }
517*e5436536SAndroid Build Coastguard Worker if (chCnt >= nChannels) break;
518*e5436536SAndroid Build Coastguard Worker if (pElementIdTab[el] == ID_END) break;
519*e5436536SAndroid Build Coastguard Worker }
520*e5436536SAndroid Build Coastguard Worker
521*e5436536SAndroid Build Coastguard Worker return 0; /* element instance tag not found */
522*e5436536SAndroid Build Coastguard Worker }
523*e5436536SAndroid Build Coastguard Worker
validateElementInstanceTags(CProgramConfig * pce,CAacDecoderChannelInfo ** pAacDecoderChannelInfo,INT nChannels,MP4_ELEMENT_ID * pElementIdTab,INT nElements)524*e5436536SAndroid Build Coastguard Worker static INT validateElementInstanceTags(
525*e5436536SAndroid Build Coastguard Worker CProgramConfig *pce, CAacDecoderChannelInfo **pAacDecoderChannelInfo,
526*e5436536SAndroid Build Coastguard Worker INT nChannels, MP4_ELEMENT_ID *pElementIdTab, INT nElements) {
527*e5436536SAndroid Build Coastguard Worker if (nChannels >= pce->NumChannels) {
528*e5436536SAndroid Build Coastguard Worker for (int el = 0; el < pce->NumFrontChannelElements; el++) {
529*e5436536SAndroid Build Coastguard Worker if (!findElementInstanceTag(pce->FrontElementTagSelect[el],
530*e5436536SAndroid Build Coastguard Worker pce->FrontElementIsCpe[el] ? ID_CPE : ID_SCE,
531*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo, nChannels,
532*e5436536SAndroid Build Coastguard Worker pElementIdTab, nElements)) {
533*e5436536SAndroid Build Coastguard Worker return 0; /* element instance tag not in raw_data_block() */
534*e5436536SAndroid Build Coastguard Worker }
535*e5436536SAndroid Build Coastguard Worker }
536*e5436536SAndroid Build Coastguard Worker for (int el = 0; el < pce->NumSideChannelElements; el++) {
537*e5436536SAndroid Build Coastguard Worker if (!findElementInstanceTag(pce->SideElementTagSelect[el],
538*e5436536SAndroid Build Coastguard Worker pce->SideElementIsCpe[el] ? ID_CPE : ID_SCE,
539*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo, nChannels,
540*e5436536SAndroid Build Coastguard Worker pElementIdTab, nElements)) {
541*e5436536SAndroid Build Coastguard Worker return 0; /* element instance tag not in raw_data_block() */
542*e5436536SAndroid Build Coastguard Worker }
543*e5436536SAndroid Build Coastguard Worker }
544*e5436536SAndroid Build Coastguard Worker for (int el = 0; el < pce->NumBackChannelElements; el++) {
545*e5436536SAndroid Build Coastguard Worker if (!findElementInstanceTag(pce->BackElementTagSelect[el],
546*e5436536SAndroid Build Coastguard Worker pce->BackElementIsCpe[el] ? ID_CPE : ID_SCE,
547*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo, nChannels,
548*e5436536SAndroid Build Coastguard Worker pElementIdTab, nElements)) {
549*e5436536SAndroid Build Coastguard Worker return 0; /* element instance tag not in raw_data_block() */
550*e5436536SAndroid Build Coastguard Worker }
551*e5436536SAndroid Build Coastguard Worker }
552*e5436536SAndroid Build Coastguard Worker for (int el = 0; el < pce->NumLfeChannelElements; el++) {
553*e5436536SAndroid Build Coastguard Worker if (!findElementInstanceTag(pce->LfeElementTagSelect[el], ID_LFE,
554*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo, nChannels,
555*e5436536SAndroid Build Coastguard Worker pElementIdTab, nElements)) {
556*e5436536SAndroid Build Coastguard Worker return 0; /* element instance tag not in raw_data_block() */
557*e5436536SAndroid Build Coastguard Worker }
558*e5436536SAndroid Build Coastguard Worker }
559*e5436536SAndroid Build Coastguard Worker } else {
560*e5436536SAndroid Build Coastguard Worker return 0; /* too less decoded audio channels */
561*e5436536SAndroid Build Coastguard Worker }
562*e5436536SAndroid Build Coastguard Worker
563*e5436536SAndroid Build Coastguard Worker return 1; /* all element instance tags found in raw_data_block() */
564*e5436536SAndroid Build Coastguard Worker }
565*e5436536SAndroid Build Coastguard Worker
566*e5436536SAndroid Build Coastguard Worker /*!
567*e5436536SAndroid Build Coastguard Worker \brief Read Program Config Element
568*e5436536SAndroid Build Coastguard Worker
569*e5436536SAndroid Build Coastguard Worker \bs Bitstream Handle
570*e5436536SAndroid Build Coastguard Worker \pTp Transport decoder handle for CRC handling
571*e5436536SAndroid Build Coastguard Worker \pce Pointer to PCE buffer
572*e5436536SAndroid Build Coastguard Worker \channelConfig Current channel configuration
573*e5436536SAndroid Build Coastguard Worker \alignAnchor Anchor for byte alignment
574*e5436536SAndroid Build Coastguard Worker
575*e5436536SAndroid Build Coastguard Worker \return PCE status (-1: fail, 0: no new PCE, 1: PCE updated, 2: PCE updated
576*e5436536SAndroid Build Coastguard Worker need re-config).
577*e5436536SAndroid Build Coastguard Worker */
CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs,HANDLE_TRANSPORTDEC pTp,CProgramConfig * pce,const UINT channelConfig,const UINT alignAnchor)578*e5436536SAndroid Build Coastguard Worker static int CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs,
579*e5436536SAndroid Build Coastguard Worker HANDLE_TRANSPORTDEC pTp,
580*e5436536SAndroid Build Coastguard Worker CProgramConfig *pce,
581*e5436536SAndroid Build Coastguard Worker const UINT channelConfig,
582*e5436536SAndroid Build Coastguard Worker const UINT alignAnchor) {
583*e5436536SAndroid Build Coastguard Worker int pceStatus = 0;
584*e5436536SAndroid Build Coastguard Worker int crcReg;
585*e5436536SAndroid Build Coastguard Worker
586*e5436536SAndroid Build Coastguard Worker /* read PCE to temporal buffer first */
587*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
588*e5436536SAndroid Build Coastguard Worker
589*e5436536SAndroid Build Coastguard Worker CProgramConfig_Init(tmpPce);
590*e5436536SAndroid Build Coastguard Worker
591*e5436536SAndroid Build Coastguard Worker crcReg = transportDec_CrcStartReg(pTp, 0);
592*e5436536SAndroid Build Coastguard Worker
593*e5436536SAndroid Build Coastguard Worker CProgramConfig_Read(tmpPce, bs, alignAnchor);
594*e5436536SAndroid Build Coastguard Worker
595*e5436536SAndroid Build Coastguard Worker transportDec_CrcEndReg(pTp, crcReg);
596*e5436536SAndroid Build Coastguard Worker
597*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_IsValid(tmpPce) && (tmpPce->Profile == 1)) {
598*e5436536SAndroid Build Coastguard Worker if (!CProgramConfig_IsValid(pce) && (channelConfig > 0)) {
599*e5436536SAndroid Build Coastguard Worker /* Create a standard channel config PCE to compare with */
600*e5436536SAndroid Build Coastguard Worker CProgramConfig_GetDefault(pce, channelConfig);
601*e5436536SAndroid Build Coastguard Worker }
602*e5436536SAndroid Build Coastguard Worker
603*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_IsValid(pce)) {
604*e5436536SAndroid Build Coastguard Worker /* Compare the new and the old PCE (tags ignored) */
605*e5436536SAndroid Build Coastguard Worker switch (CProgramConfig_Compare(pce, tmpPce)) {
606*e5436536SAndroid Build Coastguard Worker case 1: /* Channel configuration not changed. Just new metadata. */
607*e5436536SAndroid Build Coastguard Worker FDKmemcpy(pce, tmpPce,
608*e5436536SAndroid Build Coastguard Worker sizeof(CProgramConfig)); /* Store the complete PCE */
609*e5436536SAndroid Build Coastguard Worker pceStatus = 1; /* New PCE but no change of config */
610*e5436536SAndroid Build Coastguard Worker break;
611*e5436536SAndroid Build Coastguard Worker case 2: /* The number of channels are identical but not the config */
612*e5436536SAndroid Build Coastguard Worker case -1: /* The channel configuration is completely different */
613*e5436536SAndroid Build Coastguard Worker pceStatus = -1; /* Not supported! */
614*e5436536SAndroid Build Coastguard Worker break;
615*e5436536SAndroid Build Coastguard Worker case 0: /* Nothing to do because PCE matches the old one exactly. */
616*e5436536SAndroid Build Coastguard Worker default:
617*e5436536SAndroid Build Coastguard Worker /* pceStatus = 0; */
618*e5436536SAndroid Build Coastguard Worker break;
619*e5436536SAndroid Build Coastguard Worker }
620*e5436536SAndroid Build Coastguard Worker }
621*e5436536SAndroid Build Coastguard Worker }
622*e5436536SAndroid Build Coastguard Worker
623*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
624*e5436536SAndroid Build Coastguard Worker
625*e5436536SAndroid Build Coastguard Worker return pceStatus;
626*e5436536SAndroid Build Coastguard Worker }
627*e5436536SAndroid Build Coastguard Worker
628*e5436536SAndroid Build Coastguard Worker /*!
629*e5436536SAndroid Build Coastguard Worker \brief Prepares crossfade for USAC DASH IPF config change
630*e5436536SAndroid Build Coastguard Worker
631*e5436536SAndroid Build Coastguard Worker \pTimeData Pointer to time data
632*e5436536SAndroid Build Coastguard Worker \pTimeDataFlush Pointer to flushed time data
633*e5436536SAndroid Build Coastguard Worker \numChannels Number of channels
634*e5436536SAndroid Build Coastguard Worker \frameSize Size of frame
635*e5436536SAndroid Build Coastguard Worker \interleaved Indicates if time data is interleaved
636*e5436536SAndroid Build Coastguard Worker
637*e5436536SAndroid Build Coastguard Worker \return Error code
638*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_PrepareCrossFade(const PCM_DEC * pTimeData,PCM_DEC ** pTimeDataFlush,const INT numChannels,const INT frameSize,const INT interleaved)639*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
640*e5436536SAndroid Build Coastguard Worker const PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels,
641*e5436536SAndroid Build Coastguard Worker const INT frameSize, const INT interleaved) {
642*e5436536SAndroid Build Coastguard Worker int i, ch, s1, s2;
643*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR ErrorStatus;
644*e5436536SAndroid Build Coastguard Worker
645*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_OK;
646*e5436536SAndroid Build Coastguard Worker
647*e5436536SAndroid Build Coastguard Worker if (interleaved) {
648*e5436536SAndroid Build Coastguard Worker s1 = 1;
649*e5436536SAndroid Build Coastguard Worker s2 = numChannels;
650*e5436536SAndroid Build Coastguard Worker } else {
651*e5436536SAndroid Build Coastguard Worker s1 = frameSize;
652*e5436536SAndroid Build Coastguard Worker s2 = 1;
653*e5436536SAndroid Build Coastguard Worker }
654*e5436536SAndroid Build Coastguard Worker
655*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < numChannels; ch++) {
656*e5436536SAndroid Build Coastguard Worker const PCM_DEC *pIn = &pTimeData[ch * s1];
657*e5436536SAndroid Build Coastguard Worker for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
658*e5436536SAndroid Build Coastguard Worker pTimeDataFlush[ch][i] = *pIn;
659*e5436536SAndroid Build Coastguard Worker pIn += s2;
660*e5436536SAndroid Build Coastguard Worker }
661*e5436536SAndroid Build Coastguard Worker }
662*e5436536SAndroid Build Coastguard Worker
663*e5436536SAndroid Build Coastguard Worker return ErrorStatus;
664*e5436536SAndroid Build Coastguard Worker }
665*e5436536SAndroid Build Coastguard Worker
666*e5436536SAndroid Build Coastguard Worker /*!
667*e5436536SAndroid Build Coastguard Worker \brief Applies crossfade for USAC DASH IPF config change
668*e5436536SAndroid Build Coastguard Worker
669*e5436536SAndroid Build Coastguard Worker \pTimeData Pointer to time data
670*e5436536SAndroid Build Coastguard Worker \pTimeDataFlush Pointer to flushed time data
671*e5436536SAndroid Build Coastguard Worker \numChannels Number of channels
672*e5436536SAndroid Build Coastguard Worker \frameSize Size of frame
673*e5436536SAndroid Build Coastguard Worker \interleaved Indicates if time data is interleaved
674*e5436536SAndroid Build Coastguard Worker
675*e5436536SAndroid Build Coastguard Worker \return Error code
676*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_ApplyCrossFade(PCM_DEC * pTimeData,PCM_DEC ** pTimeDataFlush,const INT numChannels,const INT frameSize,const INT interleaved)677*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
678*e5436536SAndroid Build Coastguard Worker PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels,
679*e5436536SAndroid Build Coastguard Worker const INT frameSize, const INT interleaved) {
680*e5436536SAndroid Build Coastguard Worker int i, ch, s1, s2;
681*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR ErrorStatus;
682*e5436536SAndroid Build Coastguard Worker
683*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_OK;
684*e5436536SAndroid Build Coastguard Worker
685*e5436536SAndroid Build Coastguard Worker if (interleaved) {
686*e5436536SAndroid Build Coastguard Worker s1 = 1;
687*e5436536SAndroid Build Coastguard Worker s2 = numChannels;
688*e5436536SAndroid Build Coastguard Worker } else {
689*e5436536SAndroid Build Coastguard Worker s1 = frameSize;
690*e5436536SAndroid Build Coastguard Worker s2 = 1;
691*e5436536SAndroid Build Coastguard Worker }
692*e5436536SAndroid Build Coastguard Worker
693*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < numChannels; ch++) {
694*e5436536SAndroid Build Coastguard Worker PCM_DEC *pIn = &pTimeData[ch * s1];
695*e5436536SAndroid Build Coastguard Worker for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
696*e5436536SAndroid Build Coastguard Worker FIXP_SGL alpha = (FIXP_SGL)i
697*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - TIME_DATA_FLUSH_SIZE_SF);
698*e5436536SAndroid Build Coastguard Worker FIXP_DBL time = PCM_DEC2FIXP_DBL(*pIn);
699*e5436536SAndroid Build Coastguard Worker FIXP_DBL timeFlush = PCM_DEC2FIXP_DBL(pTimeDataFlush[ch][i]);
700*e5436536SAndroid Build Coastguard Worker
701*e5436536SAndroid Build Coastguard Worker *pIn = FIXP_DBL2PCM_DEC(timeFlush - fMult(timeFlush, alpha) +
702*e5436536SAndroid Build Coastguard Worker fMult(time, alpha));
703*e5436536SAndroid Build Coastguard Worker pIn += s2;
704*e5436536SAndroid Build Coastguard Worker }
705*e5436536SAndroid Build Coastguard Worker }
706*e5436536SAndroid Build Coastguard Worker
707*e5436536SAndroid Build Coastguard Worker return ErrorStatus;
708*e5436536SAndroid Build Coastguard Worker }
709*e5436536SAndroid Build Coastguard Worker
710*e5436536SAndroid Build Coastguard Worker /*!
711*e5436536SAndroid Build Coastguard Worker \brief Parse PreRoll Extension Payload
712*e5436536SAndroid Build Coastguard Worker
713*e5436536SAndroid Build Coastguard Worker \self Handle of AAC decoder
714*e5436536SAndroid Build Coastguard Worker \numPrerollAU Number of preRoll AUs
715*e5436536SAndroid Build Coastguard Worker \prerollAUOffset Offset to each preRoll AU
716*e5436536SAndroid Build Coastguard Worker \prerollAULength Length of each preRoll AU
717*e5436536SAndroid Build Coastguard Worker
718*e5436536SAndroid Build Coastguard Worker \return Error code
719*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_PreRollExtensionPayloadParse(HANDLE_AACDECODER self,UINT * numPrerollAU,UINT * prerollAUOffset,UINT * prerollAULength)720*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse(
721*e5436536SAndroid Build Coastguard Worker HANDLE_AACDECODER self, UINT *numPrerollAU, UINT *prerollAUOffset,
722*e5436536SAndroid Build Coastguard Worker UINT *prerollAULength) {
723*e5436536SAndroid Build Coastguard Worker FDK_BITSTREAM bs;
724*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs;
725*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR ErrorStatus;
726*e5436536SAndroid Build Coastguard Worker
727*e5436536SAndroid Build Coastguard Worker INT auStartAnchor;
728*e5436536SAndroid Build Coastguard Worker UINT independencyFlag;
729*e5436536SAndroid Build Coastguard Worker UINT extPayloadPresentFlag;
730*e5436536SAndroid Build Coastguard Worker UINT useDefaultLengthFlag;
731*e5436536SAndroid Build Coastguard Worker UINT configLength = 0;
732*e5436536SAndroid Build Coastguard Worker UINT preRollPossible = 1;
733*e5436536SAndroid Build Coastguard Worker UINT i;
734*e5436536SAndroid Build Coastguard Worker UCHAR configChanged = 0;
735*e5436536SAndroid Build Coastguard Worker UCHAR config[TP_USAC_MAX_CONFIG_LEN] = {0};
736*e5436536SAndroid Build Coastguard Worker UCHAR
737*e5436536SAndroid Build Coastguard Worker implicitExplicitCfgDiff = 0; /* in case implicit and explicit config is
738*e5436536SAndroid Build Coastguard Worker equal preroll AU's should be processed
739*e5436536SAndroid Build Coastguard Worker after decoder reset */
740*e5436536SAndroid Build Coastguard Worker
741*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_OK;
742*e5436536SAndroid Build Coastguard Worker
743*e5436536SAndroid Build Coastguard Worker hBs = transportDec_GetBitstream(self->hInput, 0);
744*e5436536SAndroid Build Coastguard Worker bs = *hBs;
745*e5436536SAndroid Build Coastguard Worker
746*e5436536SAndroid Build Coastguard Worker auStartAnchor = (INT)FDKgetValidBits(hBs);
747*e5436536SAndroid Build Coastguard Worker if (auStartAnchor <= 0) {
748*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
749*e5436536SAndroid Build Coastguard Worker goto bail;
750*e5436536SAndroid Build Coastguard Worker }
751*e5436536SAndroid Build Coastguard Worker
752*e5436536SAndroid Build Coastguard Worker /* Independency flag */
753*e5436536SAndroid Build Coastguard Worker FDKreadBit(hBs);
754*e5436536SAndroid Build Coastguard Worker
755*e5436536SAndroid Build Coastguard Worker /* Payload present flag of extension ID_EXT_ELE_AUDIOPREROLL must be one */
756*e5436536SAndroid Build Coastguard Worker extPayloadPresentFlag = FDKreadBits(hBs, 1);
757*e5436536SAndroid Build Coastguard Worker if (!extPayloadPresentFlag) {
758*e5436536SAndroid Build Coastguard Worker preRollPossible = 0;
759*e5436536SAndroid Build Coastguard Worker }
760*e5436536SAndroid Build Coastguard Worker
761*e5436536SAndroid Build Coastguard Worker /* Default length flag of extension ID_EXT_ELE_AUDIOPREROLL must be zero */
762*e5436536SAndroid Build Coastguard Worker useDefaultLengthFlag = FDKreadBits(hBs, 1);
763*e5436536SAndroid Build Coastguard Worker if (useDefaultLengthFlag) {
764*e5436536SAndroid Build Coastguard Worker preRollPossible = 0;
765*e5436536SAndroid Build Coastguard Worker }
766*e5436536SAndroid Build Coastguard Worker
767*e5436536SAndroid Build Coastguard Worker if (preRollPossible) { /* extPayloadPresentFlag && !useDefaultLengthFlag */
768*e5436536SAndroid Build Coastguard Worker /* Read overall ext payload length, useDefaultLengthFlag must be zero. */
769*e5436536SAndroid Build Coastguard Worker escapedValue(hBs, 8, 16, 0);
770*e5436536SAndroid Build Coastguard Worker
771*e5436536SAndroid Build Coastguard Worker /* Read RSVD60 Config size */
772*e5436536SAndroid Build Coastguard Worker configLength = escapedValue(hBs, 4, 4, 8);
773*e5436536SAndroid Build Coastguard Worker
774*e5436536SAndroid Build Coastguard Worker /* Avoid decoding pre roll frames if there was no config change and no
775*e5436536SAndroid Build Coastguard Worker * config is included in the pre roll ext payload. */
776*e5436536SAndroid Build Coastguard Worker }
777*e5436536SAndroid Build Coastguard Worker
778*e5436536SAndroid Build Coastguard Worker /* If pre roll not possible then exit. */
779*e5436536SAndroid Build Coastguard Worker if (preRollPossible == 0) {
780*e5436536SAndroid Build Coastguard Worker /* Sanity check: if flushing is switched on, preRollPossible must be 1 */
781*e5436536SAndroid Build Coastguard Worker if (self->flushStatus != AACDEC_FLUSH_OFF) {
782*e5436536SAndroid Build Coastguard Worker /* Mismatch of current payload and flushing status */
783*e5436536SAndroid Build Coastguard Worker self->flushStatus = AACDEC_FLUSH_OFF;
784*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
785*e5436536SAndroid Build Coastguard Worker }
786*e5436536SAndroid Build Coastguard Worker goto bail;
787*e5436536SAndroid Build Coastguard Worker }
788*e5436536SAndroid Build Coastguard Worker
789*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & AC_USAC) {
790*e5436536SAndroid Build Coastguard Worker if (configLength > 0) {
791*e5436536SAndroid Build Coastguard Worker /* DASH IPF USAC Config Change: Read new config and compare with current
792*e5436536SAndroid Build Coastguard Worker * config. Apply reconfiguration if config's are different. */
793*e5436536SAndroid Build Coastguard Worker for (i = 0; i < configLength; i++) {
794*e5436536SAndroid Build Coastguard Worker config[i] = FDKreadBits(hBs, 8);
795*e5436536SAndroid Build Coastguard Worker }
796*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR terr;
797*e5436536SAndroid Build Coastguard Worker terr = transportDec_InBandConfig(self->hInput, config, configLength,
798*e5436536SAndroid Build Coastguard Worker self->buildUpStatus, &configChanged, 0,
799*e5436536SAndroid Build Coastguard Worker &implicitExplicitCfgDiff);
800*e5436536SAndroid Build Coastguard Worker if (terr != TRANSPORTDEC_OK) {
801*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
802*e5436536SAndroid Build Coastguard Worker goto bail;
803*e5436536SAndroid Build Coastguard Worker }
804*e5436536SAndroid Build Coastguard Worker }
805*e5436536SAndroid Build Coastguard Worker }
806*e5436536SAndroid Build Coastguard Worker
807*e5436536SAndroid Build Coastguard Worker /* For the first frame buildUpStatus is not set and no flushing is performed
808*e5436536SAndroid Build Coastguard Worker * but preroll AU's should processed. */
809*e5436536SAndroid Build Coastguard Worker /* For USAC there is no idle state. */
810*e5436536SAndroid Build Coastguard Worker if ((self->streamInfo.numChannels == 0) && !implicitExplicitCfgDiff &&
811*e5436536SAndroid Build Coastguard Worker (self->flags[0] & AC_USAC)) {
812*e5436536SAndroid Build Coastguard Worker self->buildUpStatus = AACDEC_USAC_BUILD_UP_ON;
813*e5436536SAndroid Build Coastguard Worker /* sanity check: if buildUp status on -> flushing must be off */
814*e5436536SAndroid Build Coastguard Worker if (self->flushStatus != AACDEC_FLUSH_OFF) {
815*e5436536SAndroid Build Coastguard Worker self->flushStatus = AACDEC_FLUSH_OFF;
816*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
817*e5436536SAndroid Build Coastguard Worker goto bail;
818*e5436536SAndroid Build Coastguard Worker }
819*e5436536SAndroid Build Coastguard Worker }
820*e5436536SAndroid Build Coastguard Worker
821*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & AC_USAC) {
822*e5436536SAndroid Build Coastguard Worker /* We are interested in preroll AUs if an explicit or an implicit config
823*e5436536SAndroid Build Coastguard Worker * change is signalized in other words if the build up status is set. */
824*e5436536SAndroid Build Coastguard Worker if (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON) {
825*e5436536SAndroid Build Coastguard Worker UCHAR applyCrossfade = FDKreadBit(hBs);
826*e5436536SAndroid Build Coastguard Worker if (applyCrossfade) {
827*e5436536SAndroid Build Coastguard Worker self->applyCrossfade |= AACDEC_CROSSFADE_BITMASK_PREROLL;
828*e5436536SAndroid Build Coastguard Worker } else {
829*e5436536SAndroid Build Coastguard Worker self->applyCrossfade &= ~AACDEC_CROSSFADE_BITMASK_PREROLL;
830*e5436536SAndroid Build Coastguard Worker }
831*e5436536SAndroid Build Coastguard Worker FDKreadBit(hBs); /* reserved */
832*e5436536SAndroid Build Coastguard Worker /* Read num preroll AU's */
833*e5436536SAndroid Build Coastguard Worker *numPrerollAU = escapedValue(hBs, 2, 4, 0);
834*e5436536SAndroid Build Coastguard Worker /* check limits for USAC */
835*e5436536SAndroid Build Coastguard Worker if (*numPrerollAU > AACDEC_MAX_NUM_PREROLL_AU_USAC) {
836*e5436536SAndroid Build Coastguard Worker *numPrerollAU = 0;
837*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
838*e5436536SAndroid Build Coastguard Worker goto bail;
839*e5436536SAndroid Build Coastguard Worker }
840*e5436536SAndroid Build Coastguard Worker }
841*e5436536SAndroid Build Coastguard Worker }
842*e5436536SAndroid Build Coastguard Worker
843*e5436536SAndroid Build Coastguard Worker for (i = 0; i < *numPrerollAU; i++) {
844*e5436536SAndroid Build Coastguard Worker /* For every AU get length and offset in the bitstream */
845*e5436536SAndroid Build Coastguard Worker prerollAULength[i] = escapedValue(hBs, 16, 16, 0);
846*e5436536SAndroid Build Coastguard Worker if (prerollAULength[i] > 0) {
847*e5436536SAndroid Build Coastguard Worker prerollAUOffset[i] = auStartAnchor - (INT)FDKgetValidBits(hBs);
848*e5436536SAndroid Build Coastguard Worker independencyFlag = FDKreadBit(hBs);
849*e5436536SAndroid Build Coastguard Worker if (i == 0 && !independencyFlag) {
850*e5436536SAndroid Build Coastguard Worker *numPrerollAU = 0;
851*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
852*e5436536SAndroid Build Coastguard Worker goto bail;
853*e5436536SAndroid Build Coastguard Worker }
854*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, prerollAULength[i] * 8 - 1);
855*e5436536SAndroid Build Coastguard Worker self->prerollAULength[i] = (prerollAULength[i] * 8) + prerollAUOffset[i];
856*e5436536SAndroid Build Coastguard Worker } else {
857*e5436536SAndroid Build Coastguard Worker *numPrerollAU = 0;
858*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR; /* Something is wrong */
859*e5436536SAndroid Build Coastguard Worker goto bail;
860*e5436536SAndroid Build Coastguard Worker }
861*e5436536SAndroid Build Coastguard Worker }
862*e5436536SAndroid Build Coastguard Worker
863*e5436536SAndroid Build Coastguard Worker bail:
864*e5436536SAndroid Build Coastguard Worker
865*e5436536SAndroid Build Coastguard Worker *hBs = bs;
866*e5436536SAndroid Build Coastguard Worker
867*e5436536SAndroid Build Coastguard Worker return ErrorStatus;
868*e5436536SAndroid Build Coastguard Worker }
869*e5436536SAndroid Build Coastguard Worker
870*e5436536SAndroid Build Coastguard Worker /*!
871*e5436536SAndroid Build Coastguard Worker \brief Parse Extension Payload
872*e5436536SAndroid Build Coastguard Worker
873*e5436536SAndroid Build Coastguard Worker \self Handle of AAC decoder
874*e5436536SAndroid Build Coastguard Worker \count Pointer to bit counter.
875*e5436536SAndroid Build Coastguard Worker \previous_element ID of previous element (required by some extension payloads)
876*e5436536SAndroid Build Coastguard Worker
877*e5436536SAndroid Build Coastguard Worker \return Error code
878*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_ExtPayloadParse(HANDLE_AACDECODER self,HANDLE_FDK_BITSTREAM hBs,int * count,MP4_ELEMENT_ID previous_element,int elIndex,int fIsFillElement)879*e5436536SAndroid Build Coastguard Worker static AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse(
880*e5436536SAndroid Build Coastguard Worker HANDLE_AACDECODER self, HANDLE_FDK_BITSTREAM hBs, int *count,
881*e5436536SAndroid Build Coastguard Worker MP4_ELEMENT_ID previous_element, int elIndex, int fIsFillElement) {
882*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR error = AAC_DEC_OK;
883*e5436536SAndroid Build Coastguard Worker EXT_PAYLOAD_TYPE extension_type;
884*e5436536SAndroid Build Coastguard Worker int bytes = (*count) >> 3;
885*e5436536SAndroid Build Coastguard Worker int crcFlag = 0;
886*e5436536SAndroid Build Coastguard Worker
887*e5436536SAndroid Build Coastguard Worker if (*count < 4) {
888*e5436536SAndroid Build Coastguard Worker return AAC_DEC_PARSE_ERROR;
889*e5436536SAndroid Build Coastguard Worker } else if ((INT)FDKgetValidBits(hBs) < *count) {
890*e5436536SAndroid Build Coastguard Worker return AAC_DEC_DECODE_FRAME_ERROR;
891*e5436536SAndroid Build Coastguard Worker }
892*e5436536SAndroid Build Coastguard Worker
893*e5436536SAndroid Build Coastguard Worker extension_type =
894*e5436536SAndroid Build Coastguard Worker (EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4); /* bs_extension_type */
895*e5436536SAndroid Build Coastguard Worker *count -= 4;
896*e5436536SAndroid Build Coastguard Worker
897*e5436536SAndroid Build Coastguard Worker /* For ELD, the SBR signaling is explicit and parsed in
898*e5436536SAndroid Build Coastguard Worker aacDecoder_ParseExplicitMpsAndSbr(), therefore skip SBR if implicit
899*e5436536SAndroid Build Coastguard Worker present. */
900*e5436536SAndroid Build Coastguard Worker if ((self->flags[0] & AC_ELD) && ((extension_type == EXT_SBR_DATA_CRC) ||
901*e5436536SAndroid Build Coastguard Worker (extension_type == EXT_SBR_DATA))) {
902*e5436536SAndroid Build Coastguard Worker extension_type = EXT_FIL; /* skip sbr data */
903*e5436536SAndroid Build Coastguard Worker }
904*e5436536SAndroid Build Coastguard Worker
905*e5436536SAndroid Build Coastguard Worker switch (extension_type) {
906*e5436536SAndroid Build Coastguard Worker case EXT_DYNAMIC_RANGE: {
907*e5436536SAndroid Build Coastguard Worker INT readBits =
908*e5436536SAndroid Build Coastguard Worker aacDecoder_drcMarkPayload(self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA);
909*e5436536SAndroid Build Coastguard Worker
910*e5436536SAndroid Build Coastguard Worker if (readBits > *count) { /* Read too much. Something went wrong! */
911*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
912*e5436536SAndroid Build Coastguard Worker }
913*e5436536SAndroid Build Coastguard Worker *count -= readBits;
914*e5436536SAndroid Build Coastguard Worker } break;
915*e5436536SAndroid Build Coastguard Worker case EXT_LDSAC_DATA:
916*e5436536SAndroid Build Coastguard Worker case EXT_SAC_DATA:
917*e5436536SAndroid Build Coastguard Worker /* Read MPEG Surround Extension payload */
918*e5436536SAndroid Build Coastguard Worker {
919*e5436536SAndroid Build Coastguard Worker int err, mpsSampleRate, mpsFrameSize;
920*e5436536SAndroid Build Coastguard Worker
921*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & AC_PS_PRESENT) {
922*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
923*e5436536SAndroid Build Coastguard Worker goto bail;
924*e5436536SAndroid Build Coastguard Worker }
925*e5436536SAndroid Build Coastguard Worker
926*e5436536SAndroid Build Coastguard Worker /* Handle SBR dual rate case */
927*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.extSamplingRate != 0) {
928*e5436536SAndroid Build Coastguard Worker mpsSampleRate = self->streamInfo.extSamplingRate;
929*e5436536SAndroid Build Coastguard Worker mpsFrameSize = self->streamInfo.aacSamplesPerFrame *
930*e5436536SAndroid Build Coastguard Worker (self->streamInfo.extSamplingRate /
931*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSampleRate);
932*e5436536SAndroid Build Coastguard Worker } else {
933*e5436536SAndroid Build Coastguard Worker mpsSampleRate = self->streamInfo.aacSampleRate;
934*e5436536SAndroid Build Coastguard Worker mpsFrameSize = self->streamInfo.aacSamplesPerFrame;
935*e5436536SAndroid Build Coastguard Worker }
936*e5436536SAndroid Build Coastguard Worker /* Setting of internal MPS state; may be reset in
937*e5436536SAndroid Build Coastguard Worker CAacDecoder_SyncQmfMode if decoder is unable to decode with user
938*e5436536SAndroid Build Coastguard Worker defined qmfMode */
939*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD))) {
940*e5436536SAndroid Build Coastguard Worker self->mpsEnableCurr = self->mpsEnableUser;
941*e5436536SAndroid Build Coastguard Worker }
942*e5436536SAndroid Build Coastguard Worker if (self->mpsEnableCurr) {
943*e5436536SAndroid Build Coastguard Worker if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig) {
944*e5436536SAndroid Build Coastguard Worker /* if not done yet, allocate full MPEG Surround decoder instance */
945*e5436536SAndroid Build Coastguard Worker if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
946*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
947*e5436536SAndroid Build Coastguard Worker SAC_INSTANCE_NOT_FULL_AVAILABLE) {
948*e5436536SAndroid Build Coastguard Worker if (mpegSurroundDecoder_Open(
949*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
950*e5436536SAndroid Build Coastguard Worker &self->qmfDomain)) {
951*e5436536SAndroid Build Coastguard Worker return AAC_DEC_OUT_OF_MEMORY;
952*e5436536SAndroid Build Coastguard Worker }
953*e5436536SAndroid Build Coastguard Worker }
954*e5436536SAndroid Build Coastguard Worker }
955*e5436536SAndroid Build Coastguard Worker err = mpegSurroundDecoder_Parse(
956*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, hBs, count,
957*e5436536SAndroid Build Coastguard Worker self->streamInfo.aot, mpsSampleRate, mpsFrameSize,
958*e5436536SAndroid Build Coastguard Worker self->flags[0] & AC_INDEP);
959*e5436536SAndroid Build Coastguard Worker if (err == MPS_OK) {
960*e5436536SAndroid Build Coastguard Worker self->flags[0] |= AC_MPS_PRESENT;
961*e5436536SAndroid Build Coastguard Worker } else {
962*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
963*e5436536SAndroid Build Coastguard Worker }
964*e5436536SAndroid Build Coastguard Worker }
965*e5436536SAndroid Build Coastguard Worker /* Skip any trailing bytes */
966*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, *count);
967*e5436536SAndroid Build Coastguard Worker *count = 0;
968*e5436536SAndroid Build Coastguard Worker }
969*e5436536SAndroid Build Coastguard Worker break;
970*e5436536SAndroid Build Coastguard Worker
971*e5436536SAndroid Build Coastguard Worker case EXT_SBR_DATA_CRC:
972*e5436536SAndroid Build Coastguard Worker crcFlag = 1;
973*e5436536SAndroid Build Coastguard Worker FDK_FALLTHROUGH;
974*e5436536SAndroid Build Coastguard Worker case EXT_SBR_DATA:
975*e5436536SAndroid Build Coastguard Worker if (IS_CHANNEL_ELEMENT(previous_element)) {
976*e5436536SAndroid Build Coastguard Worker SBR_ERROR sbrError;
977*e5436536SAndroid Build Coastguard Worker UCHAR configMode = 0;
978*e5436536SAndroid Build Coastguard Worker UCHAR configChanged = 0;
979*e5436536SAndroid Build Coastguard Worker
980*e5436536SAndroid Build Coastguard Worker CAacDecoder_SyncQmfMode(self);
981*e5436536SAndroid Build Coastguard Worker
982*e5436536SAndroid Build Coastguard Worker configMode |= AC_CM_ALLOC_MEM;
983*e5436536SAndroid Build Coastguard Worker
984*e5436536SAndroid Build Coastguard Worker sbrError = sbrDecoder_InitElement(
985*e5436536SAndroid Build Coastguard Worker self->hSbrDecoder, self->streamInfo.aacSampleRate,
986*e5436536SAndroid Build Coastguard Worker self->streamInfo.extSamplingRate,
987*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot,
988*e5436536SAndroid Build Coastguard Worker previous_element, elIndex,
989*e5436536SAndroid Build Coastguard Worker 2, /* Signalize that harmonicSBR shall be ignored in the config
990*e5436536SAndroid Build Coastguard Worker change detection */
991*e5436536SAndroid Build Coastguard Worker 0, configMode, &configChanged, self->downscaleFactor);
992*e5436536SAndroid Build Coastguard Worker
993*e5436536SAndroid Build Coastguard Worker if (sbrError == SBRDEC_OK) {
994*e5436536SAndroid Build Coastguard Worker sbrError = sbrDecoder_Parse(self->hSbrDecoder, hBs,
995*e5436536SAndroid Build Coastguard Worker self->pDrmBsBuffer, self->drmBsBufferSize,
996*e5436536SAndroid Build Coastguard Worker count, *count, crcFlag, previous_element,
997*e5436536SAndroid Build Coastguard Worker elIndex, self->flags[0], self->elFlags);
998*e5436536SAndroid Build Coastguard Worker /* Enable SBR for implicit SBR signalling but only if no severe error
999*e5436536SAndroid Build Coastguard Worker * happend. */
1000*e5436536SAndroid Build Coastguard Worker if ((sbrError == SBRDEC_OK) || (sbrError == SBRDEC_PARSE_ERROR)) {
1001*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = 1;
1002*e5436536SAndroid Build Coastguard Worker }
1003*e5436536SAndroid Build Coastguard Worker } else {
1004*e5436536SAndroid Build Coastguard Worker /* Do not try to apply SBR because initializing the element failed. */
1005*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = 0;
1006*e5436536SAndroid Build Coastguard Worker }
1007*e5436536SAndroid Build Coastguard Worker /* Citation from ISO/IEC 14496-3 chapter 4.5.2.1.5.2
1008*e5436536SAndroid Build Coastguard Worker Fill elements containing an extension_payload() with an extension_type
1009*e5436536SAndroid Build Coastguard Worker of EXT_SBR_DATA or EXT_SBR_DATA_CRC shall not contain any other
1010*e5436536SAndroid Build Coastguard Worker extension_payload of any other extension_type.
1011*e5436536SAndroid Build Coastguard Worker */
1012*e5436536SAndroid Build Coastguard Worker if (fIsFillElement) {
1013*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, *count);
1014*e5436536SAndroid Build Coastguard Worker *count = 0;
1015*e5436536SAndroid Build Coastguard Worker } else {
1016*e5436536SAndroid Build Coastguard Worker /* If this is not a fill element with a known length, we are screwed
1017*e5436536SAndroid Build Coastguard Worker * and further parsing makes no sense. */
1018*e5436536SAndroid Build Coastguard Worker if (sbrError != SBRDEC_OK) {
1019*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
1020*e5436536SAndroid Build Coastguard Worker }
1021*e5436536SAndroid Build Coastguard Worker }
1022*e5436536SAndroid Build Coastguard Worker } else {
1023*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
1024*e5436536SAndroid Build Coastguard Worker }
1025*e5436536SAndroid Build Coastguard Worker break;
1026*e5436536SAndroid Build Coastguard Worker
1027*e5436536SAndroid Build Coastguard Worker case EXT_FILL_DATA: {
1028*e5436536SAndroid Build Coastguard Worker int temp;
1029*e5436536SAndroid Build Coastguard Worker
1030*e5436536SAndroid Build Coastguard Worker temp = FDKreadBits(hBs, 4);
1031*e5436536SAndroid Build Coastguard Worker bytes--;
1032*e5436536SAndroid Build Coastguard Worker if (temp != 0) {
1033*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
1034*e5436536SAndroid Build Coastguard Worker break;
1035*e5436536SAndroid Build Coastguard Worker }
1036*e5436536SAndroid Build Coastguard Worker while (bytes > 0) {
1037*e5436536SAndroid Build Coastguard Worker temp = FDKreadBits(hBs, 8);
1038*e5436536SAndroid Build Coastguard Worker bytes--;
1039*e5436536SAndroid Build Coastguard Worker if (temp != 0xa5) {
1040*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
1041*e5436536SAndroid Build Coastguard Worker break;
1042*e5436536SAndroid Build Coastguard Worker }
1043*e5436536SAndroid Build Coastguard Worker }
1044*e5436536SAndroid Build Coastguard Worker *count = bytes << 3;
1045*e5436536SAndroid Build Coastguard Worker } break;
1046*e5436536SAndroid Build Coastguard Worker
1047*e5436536SAndroid Build Coastguard Worker case EXT_DATA_ELEMENT: {
1048*e5436536SAndroid Build Coastguard Worker int dataElementVersion;
1049*e5436536SAndroid Build Coastguard Worker
1050*e5436536SAndroid Build Coastguard Worker dataElementVersion = FDKreadBits(hBs, 4);
1051*e5436536SAndroid Build Coastguard Worker *count -= 4;
1052*e5436536SAndroid Build Coastguard Worker if (dataElementVersion == 0) /* ANC_DATA */
1053*e5436536SAndroid Build Coastguard Worker {
1054*e5436536SAndroid Build Coastguard Worker int temp, dataElementLength = 0;
1055*e5436536SAndroid Build Coastguard Worker do {
1056*e5436536SAndroid Build Coastguard Worker temp = FDKreadBits(hBs, 8);
1057*e5436536SAndroid Build Coastguard Worker *count -= 8;
1058*e5436536SAndroid Build Coastguard Worker dataElementLength += temp;
1059*e5436536SAndroid Build Coastguard Worker } while (temp == 255);
1060*e5436536SAndroid Build Coastguard Worker
1061*e5436536SAndroid Build Coastguard Worker CAacDecoder_AncDataParse(&self->ancData, hBs, dataElementLength);
1062*e5436536SAndroid Build Coastguard Worker *count -= (dataElementLength << 3);
1063*e5436536SAndroid Build Coastguard Worker } else {
1064*e5436536SAndroid Build Coastguard Worker /* align = 0 */
1065*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
1066*e5436536SAndroid Build Coastguard Worker goto bail;
1067*e5436536SAndroid Build Coastguard Worker }
1068*e5436536SAndroid Build Coastguard Worker } break;
1069*e5436536SAndroid Build Coastguard Worker
1070*e5436536SAndroid Build Coastguard Worker case EXT_DATA_LENGTH:
1071*e5436536SAndroid Build Coastguard Worker if (!fIsFillElement /* Makes no sens to have an additional length in a
1072*e5436536SAndroid Build Coastguard Worker fill ... */
1073*e5436536SAndroid Build Coastguard Worker &&
1074*e5436536SAndroid Build Coastguard Worker (self->flags[0] &
1075*e5436536SAndroid Build Coastguard Worker AC_ER)) /* ... element because this extension payload type was ... */
1076*e5436536SAndroid Build Coastguard Worker { /* ... created to circumvent the missing length in ER-Syntax. */
1077*e5436536SAndroid Build Coastguard Worker int bitCnt, len = FDKreadBits(hBs, 4);
1078*e5436536SAndroid Build Coastguard Worker *count -= 4;
1079*e5436536SAndroid Build Coastguard Worker
1080*e5436536SAndroid Build Coastguard Worker if (len == 15) {
1081*e5436536SAndroid Build Coastguard Worker int add_len = FDKreadBits(hBs, 8);
1082*e5436536SAndroid Build Coastguard Worker *count -= 8;
1083*e5436536SAndroid Build Coastguard Worker len += add_len;
1084*e5436536SAndroid Build Coastguard Worker
1085*e5436536SAndroid Build Coastguard Worker if (add_len == 255) {
1086*e5436536SAndroid Build Coastguard Worker len += FDKreadBits(hBs, 16);
1087*e5436536SAndroid Build Coastguard Worker *count -= 16;
1088*e5436536SAndroid Build Coastguard Worker }
1089*e5436536SAndroid Build Coastguard Worker }
1090*e5436536SAndroid Build Coastguard Worker len <<= 3;
1091*e5436536SAndroid Build Coastguard Worker bitCnt = len;
1092*e5436536SAndroid Build Coastguard Worker
1093*e5436536SAndroid Build Coastguard Worker if ((EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4) == EXT_DATA_LENGTH) {
1094*e5436536SAndroid Build Coastguard Worker /* Check NOTE 2: The extension_payload() included here must
1095*e5436536SAndroid Build Coastguard Worker not have extension_type == EXT_DATA_LENGTH. */
1096*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_PARSE_ERROR;
1097*e5436536SAndroid Build Coastguard Worker goto bail;
1098*e5436536SAndroid Build Coastguard Worker } else {
1099*e5436536SAndroid Build Coastguard Worker /* rewind and call myself again. */
1100*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs, 4);
1101*e5436536SAndroid Build Coastguard Worker
1102*e5436536SAndroid Build Coastguard Worker error = CAacDecoder_ExtPayloadParse(
1103*e5436536SAndroid Build Coastguard Worker self, hBs, &bitCnt, previous_element, elIndex,
1104*e5436536SAndroid Build Coastguard Worker 1); /* Treat same as fill element */
1105*e5436536SAndroid Build Coastguard Worker
1106*e5436536SAndroid Build Coastguard Worker *count -= len - bitCnt;
1107*e5436536SAndroid Build Coastguard Worker }
1108*e5436536SAndroid Build Coastguard Worker /* Note: the fall through in case the if statement above is not taken is
1109*e5436536SAndroid Build Coastguard Worker * intentional. */
1110*e5436536SAndroid Build Coastguard Worker break;
1111*e5436536SAndroid Build Coastguard Worker }
1112*e5436536SAndroid Build Coastguard Worker FDK_FALLTHROUGH;
1113*e5436536SAndroid Build Coastguard Worker
1114*e5436536SAndroid Build Coastguard Worker case EXT_FIL:
1115*e5436536SAndroid Build Coastguard Worker
1116*e5436536SAndroid Build Coastguard Worker default:
1117*e5436536SAndroid Build Coastguard Worker /* align = 4 */
1118*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, *count);
1119*e5436536SAndroid Build Coastguard Worker *count = 0;
1120*e5436536SAndroid Build Coastguard Worker break;
1121*e5436536SAndroid Build Coastguard Worker }
1122*e5436536SAndroid Build Coastguard Worker
1123*e5436536SAndroid Build Coastguard Worker bail:
1124*e5436536SAndroid Build Coastguard Worker if ((error != AAC_DEC_OK) &&
1125*e5436536SAndroid Build Coastguard Worker fIsFillElement) { /* Skip the remaining extension bytes */
1126*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, *count);
1127*e5436536SAndroid Build Coastguard Worker *count = 0;
1128*e5436536SAndroid Build Coastguard Worker /* Patch error code because decoding can go on. */
1129*e5436536SAndroid Build Coastguard Worker error = AAC_DEC_OK;
1130*e5436536SAndroid Build Coastguard Worker /* Be sure that parsing errors have been stored. */
1131*e5436536SAndroid Build Coastguard Worker }
1132*e5436536SAndroid Build Coastguard Worker return error;
1133*e5436536SAndroid Build Coastguard Worker }
1134*e5436536SAndroid Build Coastguard Worker
aacDecoder_ParseExplicitMpsAndSbr(HANDLE_AACDECODER self,HANDLE_FDK_BITSTREAM bs,const MP4_ELEMENT_ID previous_element,const int previous_element_index,const int element_index,const int el_cnt[])1135*e5436536SAndroid Build Coastguard Worker static AAC_DECODER_ERROR aacDecoder_ParseExplicitMpsAndSbr(
1136*e5436536SAndroid Build Coastguard Worker HANDLE_AACDECODER self, HANDLE_FDK_BITSTREAM bs,
1137*e5436536SAndroid Build Coastguard Worker const MP4_ELEMENT_ID previous_element, const int previous_element_index,
1138*e5436536SAndroid Build Coastguard Worker const int element_index, const int el_cnt[]) {
1139*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
1140*e5436536SAndroid Build Coastguard Worker INT bitCnt = 0;
1141*e5436536SAndroid Build Coastguard Worker
1142*e5436536SAndroid Build Coastguard Worker /* get the remaining bits of this frame */
1143*e5436536SAndroid Build Coastguard Worker bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
1144*e5436536SAndroid Build Coastguard Worker
1145*e5436536SAndroid Build Coastguard Worker if ((self->flags[0] & AC_SBR_PRESENT) &&
1146*e5436536SAndroid Build Coastguard Worker (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD | AC_DRM))) {
1147*e5436536SAndroid Build Coastguard Worker SBR_ERROR err = SBRDEC_OK;
1148*e5436536SAndroid Build Coastguard Worker int chElIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE] +
1149*e5436536SAndroid Build Coastguard Worker el_cnt[ID_LFE] + el_cnt[ID_USAC_SCE] +
1150*e5436536SAndroid Build Coastguard Worker el_cnt[ID_USAC_CPE] + el_cnt[ID_USAC_LFE];
1151*e5436536SAndroid Build Coastguard Worker INT bitCntTmp = bitCnt;
1152*e5436536SAndroid Build Coastguard Worker
1153*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & AC_USAC) {
1154*e5436536SAndroid Build Coastguard Worker chElIdx = numChElements - 1;
1155*e5436536SAndroid Build Coastguard Worker } else {
1156*e5436536SAndroid Build Coastguard Worker chElIdx = 0; /* ELD case */
1157*e5436536SAndroid Build Coastguard Worker }
1158*e5436536SAndroid Build Coastguard Worker
1159*e5436536SAndroid Build Coastguard Worker for (; chElIdx < numChElements; chElIdx += 1) {
1160*e5436536SAndroid Build Coastguard Worker MP4_ELEMENT_ID sbrType;
1161*e5436536SAndroid Build Coastguard Worker SBR_ERROR errTmp;
1162*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & (AC_USAC)) {
1163*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((self->elements[element_index] == ID_USAC_SCE) ||
1164*e5436536SAndroid Build Coastguard Worker (self->elements[element_index] == ID_USAC_CPE));
1165*e5436536SAndroid Build Coastguard Worker sbrType = IS_STEREO_SBR(self->elements[element_index],
1166*e5436536SAndroid Build Coastguard Worker self->usacStereoConfigIndex[element_index])
1167*e5436536SAndroid Build Coastguard Worker ? ID_CPE
1168*e5436536SAndroid Build Coastguard Worker : ID_SCE;
1169*e5436536SAndroid Build Coastguard Worker } else
1170*e5436536SAndroid Build Coastguard Worker sbrType = self->elements[chElIdx];
1171*e5436536SAndroid Build Coastguard Worker errTmp = sbrDecoder_Parse(self->hSbrDecoder, bs, self->pDrmBsBuffer,
1172*e5436536SAndroid Build Coastguard Worker self->drmBsBufferSize, &bitCnt, -1,
1173*e5436536SAndroid Build Coastguard Worker self->flags[0] & AC_SBRCRC, sbrType, chElIdx,
1174*e5436536SAndroid Build Coastguard Worker self->flags[0], self->elFlags);
1175*e5436536SAndroid Build Coastguard Worker if (errTmp != SBRDEC_OK) {
1176*e5436536SAndroid Build Coastguard Worker err = errTmp;
1177*e5436536SAndroid Build Coastguard Worker bitCntTmp = bitCnt;
1178*e5436536SAndroid Build Coastguard Worker bitCnt = 0;
1179*e5436536SAndroid Build Coastguard Worker }
1180*e5436536SAndroid Build Coastguard Worker }
1181*e5436536SAndroid Build Coastguard Worker switch (err) {
1182*e5436536SAndroid Build Coastguard Worker case SBRDEC_PARSE_ERROR:
1183*e5436536SAndroid Build Coastguard Worker /* Can not go on parsing because we do not
1184*e5436536SAndroid Build Coastguard Worker know the length of the SBR extension data. */
1185*e5436536SAndroid Build Coastguard Worker FDKpushFor(bs, bitCntTmp);
1186*e5436536SAndroid Build Coastguard Worker bitCnt = 0;
1187*e5436536SAndroid Build Coastguard Worker break;
1188*e5436536SAndroid Build Coastguard Worker case SBRDEC_OK:
1189*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = 1;
1190*e5436536SAndroid Build Coastguard Worker break;
1191*e5436536SAndroid Build Coastguard Worker default:
1192*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
1193*e5436536SAndroid Build Coastguard Worker break;
1194*e5436536SAndroid Build Coastguard Worker }
1195*e5436536SAndroid Build Coastguard Worker }
1196*e5436536SAndroid Build Coastguard Worker
1197*e5436536SAndroid Build Coastguard Worker if ((bitCnt > 0) && (self->flags[0] & (AC_USAC | AC_RSVD50))) {
1198*e5436536SAndroid Build Coastguard Worker if ((self->flags[0] & AC_MPS_PRESENT) ||
1199*e5436536SAndroid Build Coastguard Worker (self->elFlags[element_index] & AC_EL_USAC_MPS212)) {
1200*e5436536SAndroid Build Coastguard Worker int err;
1201*e5436536SAndroid Build Coastguard Worker
1202*e5436536SAndroid Build Coastguard Worker err = mpegSurroundDecoder_ParseNoHeader(
1203*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, bs, &bitCnt,
1204*e5436536SAndroid Build Coastguard Worker self->flags[0] & AC_INDEP);
1205*e5436536SAndroid Build Coastguard Worker if (err != MPS_OK) {
1206*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
1207*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
1208*e5436536SAndroid Build Coastguard Worker }
1209*e5436536SAndroid Build Coastguard Worker }
1210*e5436536SAndroid Build Coastguard Worker }
1211*e5436536SAndroid Build Coastguard Worker
1212*e5436536SAndroid Build Coastguard Worker if (self->flags[0] & AC_DRM) {
1213*e5436536SAndroid Build Coastguard Worker if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
1214*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(bs, bitCnt);
1215*e5436536SAndroid Build Coastguard Worker }
1216*e5436536SAndroid Build Coastguard Worker }
1217*e5436536SAndroid Build Coastguard Worker
1218*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_DRM))) {
1219*e5436536SAndroid Build Coastguard Worker while (bitCnt > 7) {
1220*e5436536SAndroid Build Coastguard Worker ErrorStatus = CAacDecoder_ExtPayloadParse(
1221*e5436536SAndroid Build Coastguard Worker self, bs, &bitCnt, previous_element, previous_element_index, 0);
1222*e5436536SAndroid Build Coastguard Worker if (ErrorStatus != AAC_DEC_OK) {
1223*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
1224*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
1225*e5436536SAndroid Build Coastguard Worker break;
1226*e5436536SAndroid Build Coastguard Worker }
1227*e5436536SAndroid Build Coastguard Worker }
1228*e5436536SAndroid Build Coastguard Worker }
1229*e5436536SAndroid Build Coastguard Worker return ErrorStatus;
1230*e5436536SAndroid Build Coastguard Worker }
1231*e5436536SAndroid Build Coastguard Worker
1232*e5436536SAndroid Build Coastguard Worker /* Stream Configuration and Information.
1233*e5436536SAndroid Build Coastguard Worker
1234*e5436536SAndroid Build Coastguard Worker This class holds configuration and information data for a stream to be
1235*e5436536SAndroid Build Coastguard Worker decoded. It provides the calling application as well as the decoder with
1236*e5436536SAndroid Build Coastguard Worker substantial information, e.g. profile, sampling rate, number of channels
1237*e5436536SAndroid Build Coastguard Worker found in the bitstream etc.
1238*e5436536SAndroid Build Coastguard Worker */
CStreamInfoInit(CStreamInfo * pStreamInfo)1239*e5436536SAndroid Build Coastguard Worker static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
1240*e5436536SAndroid Build Coastguard Worker pStreamInfo->aacSampleRate = 0;
1241*e5436536SAndroid Build Coastguard Worker pStreamInfo->profile = -1;
1242*e5436536SAndroid Build Coastguard Worker pStreamInfo->aot = AOT_NONE;
1243*e5436536SAndroid Build Coastguard Worker
1244*e5436536SAndroid Build Coastguard Worker pStreamInfo->channelConfig = -1;
1245*e5436536SAndroid Build Coastguard Worker pStreamInfo->bitRate = 0;
1246*e5436536SAndroid Build Coastguard Worker pStreamInfo->aacSamplesPerFrame = 0;
1247*e5436536SAndroid Build Coastguard Worker
1248*e5436536SAndroid Build Coastguard Worker pStreamInfo->extAot = AOT_NONE;
1249*e5436536SAndroid Build Coastguard Worker pStreamInfo->extSamplingRate = 0;
1250*e5436536SAndroid Build Coastguard Worker
1251*e5436536SAndroid Build Coastguard Worker pStreamInfo->flags = 0;
1252*e5436536SAndroid Build Coastguard Worker
1253*e5436536SAndroid Build Coastguard Worker pStreamInfo->epConfig = -1; /* default: no ER */
1254*e5436536SAndroid Build Coastguard Worker
1255*e5436536SAndroid Build Coastguard Worker pStreamInfo->numChannels = 0;
1256*e5436536SAndroid Build Coastguard Worker pStreamInfo->sampleRate = 0;
1257*e5436536SAndroid Build Coastguard Worker pStreamInfo->frameSize = 0;
1258*e5436536SAndroid Build Coastguard Worker
1259*e5436536SAndroid Build Coastguard Worker pStreamInfo->outputDelay = 0;
1260*e5436536SAndroid Build Coastguard Worker
1261*e5436536SAndroid Build Coastguard Worker /* DRC */
1262*e5436536SAndroid Build Coastguard Worker pStreamInfo->drcProgRefLev =
1263*e5436536SAndroid Build Coastguard Worker -1; /* set program reference level to not indicated */
1264*e5436536SAndroid Build Coastguard Worker pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
1265*e5436536SAndroid Build Coastguard Worker
1266*e5436536SAndroid Build Coastguard Worker pStreamInfo->outputLoudness = -1; /* default: no loudness metadata present */
1267*e5436536SAndroid Build Coastguard Worker }
1268*e5436536SAndroid Build Coastguard Worker
1269*e5436536SAndroid Build Coastguard Worker /*!
1270*e5436536SAndroid Build Coastguard Worker \brief Initialization of AacDecoderChannelInfo
1271*e5436536SAndroid Build Coastguard Worker
1272*e5436536SAndroid Build Coastguard Worker The function initializes the pointers to AacDecoderChannelInfo for each
1273*e5436536SAndroid Build Coastguard Worker channel, set the start values for window shape and window sequence of
1274*e5436536SAndroid Build Coastguard Worker overlap&add to zero, set the overlap buffer to zero and initializes the
1275*e5436536SAndroid Build Coastguard Worker pointers to the window coefficients. \param bsFormat is the format of the AAC
1276*e5436536SAndroid Build Coastguard Worker bitstream
1277*e5436536SAndroid Build Coastguard Worker
1278*e5436536SAndroid Build Coastguard Worker \return AACDECODER instance
1279*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_Open(TRANSPORT_TYPE bsFormat)1280*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(
1281*e5436536SAndroid Build Coastguard Worker TRANSPORT_TYPE bsFormat) /*!< bitstream format (adif,adts,loas,...). */
1282*e5436536SAndroid Build Coastguard Worker {
1283*e5436536SAndroid Build Coastguard Worker HANDLE_AACDECODER self;
1284*e5436536SAndroid Build Coastguard Worker
1285*e5436536SAndroid Build Coastguard Worker self = GetAacDecoder();
1286*e5436536SAndroid Build Coastguard Worker if (self == NULL) {
1287*e5436536SAndroid Build Coastguard Worker goto bail;
1288*e5436536SAndroid Build Coastguard Worker }
1289*e5436536SAndroid Build Coastguard Worker
1290*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_ClearRequested(&self->qmfDomain.globalConf);
1291*e5436536SAndroid Build Coastguard Worker
1292*e5436536SAndroid Build Coastguard Worker /* Assign channel mapping info arrays (doing so removes dependency of settings
1293*e5436536SAndroid Build Coastguard Worker * header in API header). */
1294*e5436536SAndroid Build Coastguard Worker self->streamInfo.pChannelIndices = self->channelIndices;
1295*e5436536SAndroid Build Coastguard Worker self->streamInfo.pChannelType = self->channelType;
1296*e5436536SAndroid Build Coastguard Worker self->downscaleFactor = 1;
1297*e5436536SAndroid Build Coastguard Worker self->downscaleFactorInBS = 1;
1298*e5436536SAndroid Build Coastguard Worker
1299*e5436536SAndroid Build Coastguard Worker /* initialize anc data */
1300*e5436536SAndroid Build Coastguard Worker CAacDecoder_AncDataInit(&self->ancData, NULL, 0);
1301*e5436536SAndroid Build Coastguard Worker
1302*e5436536SAndroid Build Coastguard Worker /* initialize stream info */
1303*e5436536SAndroid Build Coastguard Worker CStreamInfoInit(&self->streamInfo);
1304*e5436536SAndroid Build Coastguard Worker
1305*e5436536SAndroid Build Coastguard Worker /* initialize progam config */
1306*e5436536SAndroid Build Coastguard Worker CProgramConfig_Init(&self->pce);
1307*e5436536SAndroid Build Coastguard Worker
1308*e5436536SAndroid Build Coastguard Worker /* initialize error concealment common data */
1309*e5436536SAndroid Build Coastguard Worker CConcealment_InitCommonData(&self->concealCommonData);
1310*e5436536SAndroid Build Coastguard Worker self->concealMethodUser = ConcealMethodNone; /* undefined -> auto mode */
1311*e5436536SAndroid Build Coastguard Worker
1312*e5436536SAndroid Build Coastguard Worker self->hDrcInfo = GetDrcInfo();
1313*e5436536SAndroid Build Coastguard Worker if (self->hDrcInfo == NULL) {
1314*e5436536SAndroid Build Coastguard Worker goto bail;
1315*e5436536SAndroid Build Coastguard Worker }
1316*e5436536SAndroid Build Coastguard Worker /* Init common DRC structure */
1317*e5436536SAndroid Build Coastguard Worker aacDecoder_drcInit(self->hDrcInfo);
1318*e5436536SAndroid Build Coastguard Worker /* Set default frame delay */
1319*e5436536SAndroid Build Coastguard Worker aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
1320*e5436536SAndroid Build Coastguard Worker CConcealment_GetDelay(&self->concealCommonData));
1321*e5436536SAndroid Build Coastguard Worker self->workBufferCore1 = (FIXP_DBL *)GetWorkBufferCore1();
1322*e5436536SAndroid Build Coastguard Worker
1323*e5436536SAndroid Build Coastguard Worker self->workBufferCore2 = GetWorkBufferCore2();
1324*e5436536SAndroid Build Coastguard Worker if (self->workBufferCore2 == NULL) goto bail;
1325*e5436536SAndroid Build Coastguard Worker
1326*e5436536SAndroid Build Coastguard Worker /* When RSVD60 is active use dedicated memory for core decoding */
1327*e5436536SAndroid Build Coastguard Worker self->pTimeData2 = GetWorkBufferCore5();
1328*e5436536SAndroid Build Coastguard Worker self->timeData2Size = GetRequiredMemWorkBufferCore5();
1329*e5436536SAndroid Build Coastguard Worker if (self->pTimeData2 == NULL) {
1330*e5436536SAndroid Build Coastguard Worker goto bail;
1331*e5436536SAndroid Build Coastguard Worker }
1332*e5436536SAndroid Build Coastguard Worker
1333*e5436536SAndroid Build Coastguard Worker return self;
1334*e5436536SAndroid Build Coastguard Worker
1335*e5436536SAndroid Build Coastguard Worker bail:
1336*e5436536SAndroid Build Coastguard Worker CAacDecoder_Close(self);
1337*e5436536SAndroid Build Coastguard Worker
1338*e5436536SAndroid Build Coastguard Worker return NULL;
1339*e5436536SAndroid Build Coastguard Worker }
1340*e5436536SAndroid Build Coastguard Worker
1341*e5436536SAndroid Build Coastguard Worker /* Revert CAacDecoder_Init() */
CAacDecoder_DeInit(HANDLE_AACDECODER self,const int subStreamIndex)1342*e5436536SAndroid Build Coastguard Worker static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
1343*e5436536SAndroid Build Coastguard Worker const int subStreamIndex) {
1344*e5436536SAndroid Build Coastguard Worker int ch;
1345*e5436536SAndroid Build Coastguard Worker int aacChannelOffset = 0, aacChannels = (8);
1346*e5436536SAndroid Build Coastguard Worker int numElements = (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1),
1347*e5436536SAndroid Build Coastguard Worker elementOffset = 0;
1348*e5436536SAndroid Build Coastguard Worker
1349*e5436536SAndroid Build Coastguard Worker if (self == NULL) return;
1350*e5436536SAndroid Build Coastguard Worker
1351*e5436536SAndroid Build Coastguard Worker {
1352*e5436536SAndroid Build Coastguard Worker self->ascChannels[0] = 0;
1353*e5436536SAndroid Build Coastguard Worker self->elements[0] = ID_END;
1354*e5436536SAndroid Build Coastguard Worker }
1355*e5436536SAndroid Build Coastguard Worker
1356*e5436536SAndroid Build Coastguard Worker for (ch = aacChannelOffset; ch < aacChannelOffset + aacChannels; ch++) {
1357*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch] != NULL) {
1358*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch]->pComStaticData != NULL) {
1359*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch]
1360*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1 != NULL) {
1361*e5436536SAndroid Build Coastguard Worker if (ch == aacChannelOffset) {
1362*e5436536SAndroid Build Coastguard Worker FreeWorkBufferCore1(&self->pAacDecoderChannelInfo[ch]
1363*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1);
1364*e5436536SAndroid Build Coastguard Worker }
1365*e5436536SAndroid Build Coastguard Worker }
1366*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch]
1367*e5436536SAndroid Build Coastguard Worker ->pComStaticData->cplxPredictionData != NULL) {
1368*e5436536SAndroid Build Coastguard Worker FreeCplxPredictionData(&self->pAacDecoderChannelInfo[ch]
1369*e5436536SAndroid Build Coastguard Worker ->pComStaticData->cplxPredictionData);
1370*e5436536SAndroid Build Coastguard Worker }
1371*e5436536SAndroid Build Coastguard Worker /* Avoid double free of linked pComStaticData in case of CPE by settings
1372*e5436536SAndroid Build Coastguard Worker * pointer to NULL. */
1373*e5436536SAndroid Build Coastguard Worker if (ch < (8) - 1) {
1374*e5436536SAndroid Build Coastguard Worker if ((self->pAacDecoderChannelInfo[ch + 1] != NULL) &&
1375*e5436536SAndroid Build Coastguard Worker (self->pAacDecoderChannelInfo[ch + 1]->pComStaticData ==
1376*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComStaticData)) {
1377*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]->pComStaticData = NULL;
1378*e5436536SAndroid Build Coastguard Worker }
1379*e5436536SAndroid Build Coastguard Worker }
1380*e5436536SAndroid Build Coastguard Worker FDKfree(self->pAacDecoderChannelInfo[ch]->pComStaticData);
1381*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComStaticData = NULL;
1382*e5436536SAndroid Build Coastguard Worker }
1383*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch]->pComData != NULL) {
1384*e5436536SAndroid Build Coastguard Worker /* Avoid double free of linked pComData in case of CPE by settings
1385*e5436536SAndroid Build Coastguard Worker * pointer to NULL. */
1386*e5436536SAndroid Build Coastguard Worker if (ch < (8) - 1) {
1387*e5436536SAndroid Build Coastguard Worker if ((self->pAacDecoderChannelInfo[ch + 1] != NULL) &&
1388*e5436536SAndroid Build Coastguard Worker (self->pAacDecoderChannelInfo[ch + 1]->pComData ==
1389*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComData)) {
1390*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]->pComData = NULL;
1391*e5436536SAndroid Build Coastguard Worker }
1392*e5436536SAndroid Build Coastguard Worker }
1393*e5436536SAndroid Build Coastguard Worker if (ch == aacChannelOffset) {
1394*e5436536SAndroid Build Coastguard Worker FreeWorkBufferCore6(
1395*e5436536SAndroid Build Coastguard Worker (SCHAR **)&self->pAacDecoderChannelInfo[ch]->pComData);
1396*e5436536SAndroid Build Coastguard Worker } else {
1397*e5436536SAndroid Build Coastguard Worker FDKafree(self->pAacDecoderChannelInfo[ch]->pComData);
1398*e5436536SAndroid Build Coastguard Worker }
1399*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComData = NULL;
1400*e5436536SAndroid Build Coastguard Worker }
1401*e5436536SAndroid Build Coastguard Worker }
1402*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
1403*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer != NULL) {
1404*e5436536SAndroid Build Coastguard Worker FreeOverlapBuffer(
1405*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
1406*e5436536SAndroid Build Coastguard Worker }
1407*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch]->hArCo != NULL) {
1408*e5436536SAndroid Build Coastguard Worker CArco_Destroy(self->pAacDecoderStaticChannelInfo[ch]->hArCo);
1409*e5436536SAndroid Build Coastguard Worker }
1410*e5436536SAndroid Build Coastguard Worker FreeAacDecoderStaticChannelInfo(&self->pAacDecoderStaticChannelInfo[ch]);
1411*e5436536SAndroid Build Coastguard Worker }
1412*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch] != NULL) {
1413*e5436536SAndroid Build Coastguard Worker FreeAacDecoderChannelInfo(&self->pAacDecoderChannelInfo[ch]);
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 int el;
1419*e5436536SAndroid Build Coastguard Worker for (el = elementOffset; el < elementOffset + numElements; el++) {
1420*e5436536SAndroid Build Coastguard Worker if (self->cpeStaticData[el] != NULL) {
1421*e5436536SAndroid Build Coastguard Worker FreeCpePersistentData(&self->cpeStaticData[el]);
1422*e5436536SAndroid Build Coastguard Worker }
1423*e5436536SAndroid Build Coastguard Worker }
1424*e5436536SAndroid Build Coastguard Worker }
1425*e5436536SAndroid Build Coastguard Worker
1426*e5436536SAndroid Build Coastguard Worker FDK_Delay_Destroy(&self->usacResidualDelay);
1427*e5436536SAndroid Build Coastguard Worker
1428*e5436536SAndroid Build Coastguard Worker self->aacChannels = 0;
1429*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSampleRate = 0;
1430*e5436536SAndroid Build Coastguard Worker self->streamInfo.sampleRate = 0;
1431*e5436536SAndroid Build Coastguard Worker /* This samplerate value is checked for configuration change, not the others
1432*e5436536SAndroid Build Coastguard Worker * above. */
1433*e5436536SAndroid Build Coastguard Worker self->samplingRateInfo[subStreamIndex].samplingRate = 0;
1434*e5436536SAndroid Build Coastguard Worker }
1435*e5436536SAndroid Build Coastguard Worker
1436*e5436536SAndroid Build Coastguard Worker /*!
1437*e5436536SAndroid Build Coastguard Worker * \brief CAacDecoder_AcceptFlags Accept flags and element flags
1438*e5436536SAndroid Build Coastguard Worker *
1439*e5436536SAndroid Build Coastguard Worker * \param self [o] handle to AACDECODER structure
1440*e5436536SAndroid Build Coastguard Worker * \param asc [i] handle to ASC structure
1441*e5436536SAndroid Build Coastguard Worker * \param flags [i] flags
1442*e5436536SAndroid Build Coastguard Worker * \param elFlags [i] pointer to element flags
1443*e5436536SAndroid Build Coastguard Worker * \param streamIndex [i] stream index
1444*e5436536SAndroid Build Coastguard Worker * \param elementOffset [i] element offset
1445*e5436536SAndroid Build Coastguard Worker *
1446*e5436536SAndroid Build Coastguard Worker * \return void
1447*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_AcceptFlags(HANDLE_AACDECODER self,const CSAudioSpecificConfig * asc,UINT flags,UINT * elFlags,int streamIndex,int elementOffset)1448*e5436536SAndroid Build Coastguard Worker static void CAacDecoder_AcceptFlags(HANDLE_AACDECODER self,
1449*e5436536SAndroid Build Coastguard Worker const CSAudioSpecificConfig *asc,
1450*e5436536SAndroid Build Coastguard Worker UINT flags, UINT *elFlags, int streamIndex,
1451*e5436536SAndroid Build Coastguard Worker int elementOffset) {
1452*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->elFlags, elFlags, sizeof(self->elFlags));
1453*e5436536SAndroid Build Coastguard Worker
1454*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex] = flags;
1455*e5436536SAndroid Build Coastguard Worker }
1456*e5436536SAndroid Build Coastguard Worker
1457*e5436536SAndroid Build Coastguard Worker /*!
1458*e5436536SAndroid Build Coastguard Worker * \brief CAacDecoder_CtrlCFGChange Set config change parameters.
1459*e5436536SAndroid Build Coastguard Worker *
1460*e5436536SAndroid Build Coastguard Worker * \param self [i] handle to AACDECODER structure
1461*e5436536SAndroid Build Coastguard Worker * \param flushStatus [i] flush status: on|off
1462*e5436536SAndroid Build Coastguard Worker * \param flushCnt [i] flush frame counter
1463*e5436536SAndroid Build Coastguard Worker * \param buildUpStatus [i] build up status: on|off
1464*e5436536SAndroid Build Coastguard Worker * \param buildUpCnt [i] build up frame counter
1465*e5436536SAndroid Build Coastguard Worker *
1466*e5436536SAndroid Build Coastguard Worker * \return error
1467*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_CtrlCFGChange(HANDLE_AACDECODER self,UCHAR flushStatus,SCHAR flushCnt,UCHAR buildUpStatus,SCHAR buildUpCnt)1468*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_CtrlCFGChange(HANDLE_AACDECODER self,
1469*e5436536SAndroid Build Coastguard Worker UCHAR flushStatus,
1470*e5436536SAndroid Build Coastguard Worker SCHAR flushCnt,
1471*e5436536SAndroid Build Coastguard Worker UCHAR buildUpStatus,
1472*e5436536SAndroid Build Coastguard Worker SCHAR buildUpCnt) {
1473*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR err = AAC_DEC_OK;
1474*e5436536SAndroid Build Coastguard Worker
1475*e5436536SAndroid Build Coastguard Worker self->flushStatus = flushStatus;
1476*e5436536SAndroid Build Coastguard Worker self->flushCnt = flushCnt;
1477*e5436536SAndroid Build Coastguard Worker self->buildUpStatus = buildUpStatus;
1478*e5436536SAndroid Build Coastguard Worker self->buildUpCnt = buildUpCnt;
1479*e5436536SAndroid Build Coastguard Worker
1480*e5436536SAndroid Build Coastguard Worker return (err);
1481*e5436536SAndroid Build Coastguard Worker }
1482*e5436536SAndroid Build Coastguard Worker
1483*e5436536SAndroid Build Coastguard Worker /*!
1484*e5436536SAndroid Build Coastguard Worker * \brief CAacDecoder_FreeMem Free config dependent AAC memory.
1485*e5436536SAndroid Build Coastguard Worker *
1486*e5436536SAndroid Build Coastguard Worker * \param self [i] handle to AACDECODER structure
1487*e5436536SAndroid Build Coastguard Worker *
1488*e5436536SAndroid Build Coastguard Worker * \return error
1489*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_FreeMem(HANDLE_AACDECODER self,const int subStreamIndex)1490*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self,
1491*e5436536SAndroid Build Coastguard Worker const int subStreamIndex) {
1492*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR err = AAC_DEC_OK;
1493*e5436536SAndroid Build Coastguard Worker
1494*e5436536SAndroid Build Coastguard Worker CAacDecoder_DeInit(self, subStreamIndex);
1495*e5436536SAndroid Build Coastguard Worker
1496*e5436536SAndroid Build Coastguard Worker return (err);
1497*e5436536SAndroid Build Coastguard Worker }
1498*e5436536SAndroid Build Coastguard Worker
1499*e5436536SAndroid Build Coastguard Worker /* Destroy aac decoder */
CAacDecoder_Close(HANDLE_AACDECODER self)1500*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) {
1501*e5436536SAndroid Build Coastguard Worker if (self == NULL) return;
1502*e5436536SAndroid Build Coastguard Worker
1503*e5436536SAndroid Build Coastguard Worker CAacDecoder_DeInit(self, 0);
1504*e5436536SAndroid Build Coastguard Worker
1505*e5436536SAndroid Build Coastguard Worker {
1506*e5436536SAndroid Build Coastguard Worker int ch;
1507*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < (8); ch++) {
1508*e5436536SAndroid Build Coastguard Worker if (self->pTimeDataFlush[ch] != NULL) {
1509*e5436536SAndroid Build Coastguard Worker FreeTimeDataFlush(&self->pTimeDataFlush[ch]);
1510*e5436536SAndroid Build Coastguard Worker }
1511*e5436536SAndroid Build Coastguard Worker }
1512*e5436536SAndroid Build Coastguard Worker }
1513*e5436536SAndroid Build Coastguard Worker
1514*e5436536SAndroid Build Coastguard Worker if (self->hDrcInfo) {
1515*e5436536SAndroid Build Coastguard Worker FreeDrcInfo(&self->hDrcInfo);
1516*e5436536SAndroid Build Coastguard Worker }
1517*e5436536SAndroid Build Coastguard Worker
1518*e5436536SAndroid Build Coastguard Worker if (self->workBufferCore1 != NULL) {
1519*e5436536SAndroid Build Coastguard Worker FreeWorkBufferCore1((CWorkBufferCore1 **)&self->workBufferCore1);
1520*e5436536SAndroid Build Coastguard Worker }
1521*e5436536SAndroid Build Coastguard Worker
1522*e5436536SAndroid Build Coastguard Worker /* Free WorkBufferCore2 */
1523*e5436536SAndroid Build Coastguard Worker if (self->workBufferCore2 != NULL) {
1524*e5436536SAndroid Build Coastguard Worker FreeWorkBufferCore2(&self->workBufferCore2);
1525*e5436536SAndroid Build Coastguard Worker }
1526*e5436536SAndroid Build Coastguard Worker if (self->pTimeData2 != NULL) {
1527*e5436536SAndroid Build Coastguard Worker FreeWorkBufferCore5(&self->pTimeData2);
1528*e5436536SAndroid Build Coastguard Worker }
1529*e5436536SAndroid Build Coastguard Worker
1530*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_Close(&self->qmfDomain);
1531*e5436536SAndroid Build Coastguard Worker
1532*e5436536SAndroid Build Coastguard Worker FreeAacDecoder(&self);
1533*e5436536SAndroid Build Coastguard Worker }
1534*e5436536SAndroid Build Coastguard Worker
1535*e5436536SAndroid Build Coastguard Worker /*!
1536*e5436536SAndroid Build Coastguard Worker \brief Initialization of decoder instance
1537*e5436536SAndroid Build Coastguard Worker
1538*e5436536SAndroid Build Coastguard Worker The function initializes the decoder.
1539*e5436536SAndroid Build Coastguard Worker
1540*e5436536SAndroid Build Coastguard Worker \return error status: 0 for success, <>0 for unsupported configurations
1541*e5436536SAndroid Build Coastguard Worker */
1542*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR
CAacDecoder_Init(HANDLE_AACDECODER self,const CSAudioSpecificConfig * asc,UCHAR configMode,UCHAR * configChanged)1543*e5436536SAndroid Build Coastguard Worker CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
1544*e5436536SAndroid Build Coastguard Worker UCHAR configMode, UCHAR *configChanged) {
1545*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR err = AAC_DEC_OK;
1546*e5436536SAndroid Build Coastguard Worker INT ascChannels, ascChanged = 0;
1547*e5436536SAndroid Build Coastguard Worker AACDEC_RENDER_MODE initRenderMode = AACDEC_RENDER_INVALID;
1548*e5436536SAndroid Build Coastguard Worker SCHAR usacStereoConfigIndex = -1;
1549*e5436536SAndroid Build Coastguard Worker int usacResidualDelayCompSamples = 0;
1550*e5436536SAndroid Build Coastguard Worker int elementOffset, aacChannelsOffset, aacChannelsOffsetIdx;
1551*e5436536SAndroid Build Coastguard Worker const int streamIndex = 0;
1552*e5436536SAndroid Build Coastguard Worker INT flushChannels = 0;
1553*e5436536SAndroid Build Coastguard Worker
1554*e5436536SAndroid Build Coastguard Worker UINT flags;
1555*e5436536SAndroid Build Coastguard Worker /* elFlags[(3*MAX_CHANNELS + (MAX_CHANNELS)/2 + 4 * (MAX_TRACKS) + 1]
1556*e5436536SAndroid Build Coastguard Worker where MAX_CHANNELS is (8*2) and MAX_TRACKS is 1 */
1557*e5436536SAndroid Build Coastguard Worker UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)];
1558*e5436536SAndroid Build Coastguard Worker
1559*e5436536SAndroid Build Coastguard Worker UCHAR sbrEnabled = self->sbrEnabled;
1560*e5436536SAndroid Build Coastguard Worker UCHAR sbrEnabledPrev = self->sbrEnabledPrev;
1561*e5436536SAndroid Build Coastguard Worker UCHAR mpsEnableCurr = self->mpsEnableCurr;
1562*e5436536SAndroid Build Coastguard Worker
1563*e5436536SAndroid Build Coastguard Worker if (!self) return AAC_DEC_INVALID_HANDLE;
1564*e5436536SAndroid Build Coastguard Worker
1565*e5436536SAndroid Build Coastguard Worker UCHAR downscaleFactor = self->downscaleFactor;
1566*e5436536SAndroid Build Coastguard Worker UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
1567*e5436536SAndroid Build Coastguard Worker
1568*e5436536SAndroid Build Coastguard Worker self->aacOutDataHeadroom = (3);
1569*e5436536SAndroid Build Coastguard Worker
1570*e5436536SAndroid Build Coastguard Worker // set profile and check for supported aot
1571*e5436536SAndroid Build Coastguard Worker // leave profile on default (=-1) for all other supported MPEG-4 aot's except
1572*e5436536SAndroid Build Coastguard Worker // aot=2 (=AAC-LC)
1573*e5436536SAndroid Build Coastguard Worker switch (asc->m_aot) {
1574*e5436536SAndroid Build Coastguard Worker case AOT_AAC_LC:
1575*e5436536SAndroid Build Coastguard Worker self->streamInfo.profile = 1;
1576*e5436536SAndroid Build Coastguard Worker FDK_FALLTHROUGH;
1577*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_SCAL:
1578*e5436536SAndroid Build Coastguard Worker if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) {
1579*e5436536SAndroid Build Coastguard Worker /* aac_scalable_extension_element() currently not supported. */
1580*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_FORMAT;
1581*e5436536SAndroid Build Coastguard Worker }
1582*e5436536SAndroid Build Coastguard Worker FDK_FALLTHROUGH;
1583*e5436536SAndroid Build Coastguard Worker case AOT_SBR:
1584*e5436536SAndroid Build Coastguard Worker case AOT_PS:
1585*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LC:
1586*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LD:
1587*e5436536SAndroid Build Coastguard Worker case AOT_DRM_AAC:
1588*e5436536SAndroid Build Coastguard Worker case AOT_DRM_SURROUND:
1589*e5436536SAndroid Build Coastguard Worker initRenderMode = AACDEC_RENDER_IMDCT;
1590*e5436536SAndroid Build Coastguard Worker break;
1591*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_ELD:
1592*e5436536SAndroid Build Coastguard Worker initRenderMode = AACDEC_RENDER_ELDFB;
1593*e5436536SAndroid Build Coastguard Worker break;
1594*e5436536SAndroid Build Coastguard Worker case AOT_USAC:
1595*e5436536SAndroid Build Coastguard Worker initRenderMode = AACDEC_RENDER_IMDCT;
1596*e5436536SAndroid Build Coastguard Worker break;
1597*e5436536SAndroid Build Coastguard Worker default:
1598*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_AOT;
1599*e5436536SAndroid Build Coastguard Worker }
1600*e5436536SAndroid Build Coastguard Worker
1601*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_IsValid(&self->pce) && (asc->m_channelConfiguration > 0)) {
1602*e5436536SAndroid Build Coastguard Worker /* Compare the stored (old) PCE with a default PCE created from the (new)
1603*e5436536SAndroid Build Coastguard Worker channel_config (on a temporal buffer) to find out wheter we can keep it
1604*e5436536SAndroid Build Coastguard Worker (and its metadata) or not. */
1605*e5436536SAndroid Build Coastguard Worker int pceCmpResult;
1606*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
1607*e5436536SAndroid Build Coastguard Worker
1608*e5436536SAndroid Build Coastguard Worker CProgramConfig_GetDefault(tmpPce, asc->m_channelConfiguration);
1609*e5436536SAndroid Build Coastguard Worker pceCmpResult = CProgramConfig_Compare(&self->pce, tmpPce);
1610*e5436536SAndroid Build Coastguard Worker if ((pceCmpResult < 0) /* Reset if PCEs are completely different ... */
1611*e5436536SAndroid Build Coastguard Worker ||
1612*e5436536SAndroid Build Coastguard Worker (pceCmpResult > 1)) { /* ... or have a different layout. */
1613*e5436536SAndroid Build Coastguard Worker CProgramConfig_Init(&self->pce);
1614*e5436536SAndroid Build Coastguard Worker } /* Otherwise keep the PCE (and its metadata). */
1615*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
1616*e5436536SAndroid Build Coastguard Worker } else {
1617*e5436536SAndroid Build Coastguard Worker CProgramConfig_Init(&self->pce);
1618*e5436536SAndroid Build Coastguard Worker }
1619*e5436536SAndroid Build Coastguard Worker
1620*e5436536SAndroid Build Coastguard Worker /* set channels */
1621*e5436536SAndroid Build Coastguard Worker switch (asc->m_channelConfiguration) {
1622*e5436536SAndroid Build Coastguard Worker case 0:
1623*e5436536SAndroid Build Coastguard Worker switch (asc->m_aot) {
1624*e5436536SAndroid Build Coastguard Worker case AOT_USAC:
1625*e5436536SAndroid Build Coastguard Worker self->chMapIndex = 0;
1626*e5436536SAndroid Build Coastguard Worker ascChannels = asc->m_sc.m_usacConfig.m_nUsacChannels;
1627*e5436536SAndroid Build Coastguard Worker break;
1628*e5436536SAndroid Build Coastguard Worker default:
1629*e5436536SAndroid Build Coastguard Worker /* get channels from program config (ASC) */
1630*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
1631*e5436536SAndroid Build Coastguard Worker ascChannels = asc->m_progrConfigElement.NumChannels;
1632*e5436536SAndroid Build Coastguard Worker if (ascChannels > 0) {
1633*e5436536SAndroid Build Coastguard Worker int el_tmp;
1634*e5436536SAndroid Build Coastguard Worker /* valid number of channels -> copy program config element (PCE)
1635*e5436536SAndroid Build Coastguard Worker * from ASC */
1636*e5436536SAndroid Build Coastguard Worker FDKmemcpy(&self->pce, &asc->m_progrConfigElement,
1637*e5436536SAndroid Build Coastguard Worker sizeof(CProgramConfig));
1638*e5436536SAndroid Build Coastguard Worker /* Built element table */
1639*e5436536SAndroid Build Coastguard Worker el_tmp = CProgramConfig_GetElementTable(
1640*e5436536SAndroid Build Coastguard Worker &asc->m_progrConfigElement, self->elements, (((8)) + (8)),
1641*e5436536SAndroid Build Coastguard Worker &self->chMapIndex);
1642*e5436536SAndroid Build Coastguard Worker for (; el_tmp < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
1643*e5436536SAndroid Build Coastguard Worker el_tmp++) {
1644*e5436536SAndroid Build Coastguard Worker self->elements[el_tmp] = ID_NONE;
1645*e5436536SAndroid Build Coastguard Worker }
1646*e5436536SAndroid Build Coastguard Worker } else {
1647*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
1648*e5436536SAndroid Build Coastguard Worker }
1649*e5436536SAndroid Build Coastguard Worker } else {
1650*e5436536SAndroid Build Coastguard Worker self->chMapIndex = 0;
1651*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
1652*e5436536SAndroid Build Coastguard Worker }
1653*e5436536SAndroid Build Coastguard Worker break;
1654*e5436536SAndroid Build Coastguard Worker }
1655*e5436536SAndroid Build Coastguard Worker break;
1656*e5436536SAndroid Build Coastguard Worker case 1:
1657*e5436536SAndroid Build Coastguard Worker case 2:
1658*e5436536SAndroid Build Coastguard Worker case 3:
1659*e5436536SAndroid Build Coastguard Worker case 4:
1660*e5436536SAndroid Build Coastguard Worker case 5:
1661*e5436536SAndroid Build Coastguard Worker case 6:
1662*e5436536SAndroid Build Coastguard Worker ascChannels = asc->m_channelConfiguration;
1663*e5436536SAndroid Build Coastguard Worker break;
1664*e5436536SAndroid Build Coastguard Worker case 11:
1665*e5436536SAndroid Build Coastguard Worker ascChannels = 7;
1666*e5436536SAndroid Build Coastguard Worker break;
1667*e5436536SAndroid Build Coastguard Worker case 7:
1668*e5436536SAndroid Build Coastguard Worker case 12:
1669*e5436536SAndroid Build Coastguard Worker case 14:
1670*e5436536SAndroid Build Coastguard Worker ascChannels = 8;
1671*e5436536SAndroid Build Coastguard Worker break;
1672*e5436536SAndroid Build Coastguard Worker default:
1673*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
1674*e5436536SAndroid Build Coastguard Worker }
1675*e5436536SAndroid Build Coastguard Worker
1676*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_USAC) {
1677*e5436536SAndroid Build Coastguard Worker flushChannels = fMin(ascChannels, (8));
1678*e5436536SAndroid Build Coastguard Worker INT numChannel;
1679*e5436536SAndroid Build Coastguard Worker pcmDmx_GetParam(self->hPcmUtils, MIN_NUMBER_OF_OUTPUT_CHANNELS,
1680*e5436536SAndroid Build Coastguard Worker &numChannel);
1681*e5436536SAndroid Build Coastguard Worker flushChannels = fMin(fMax(numChannel, flushChannels), (8));
1682*e5436536SAndroid Build Coastguard Worker }
1683*e5436536SAndroid Build Coastguard Worker
1684*e5436536SAndroid Build Coastguard Worker if (IS_USAC(asc->m_aot)) {
1685*e5436536SAndroid Build Coastguard Worker for (int el = 0; el < (INT)asc->m_sc.m_usacConfig.m_usacNumElements; el++) {
1686*e5436536SAndroid Build Coastguard Worker /* fix number of core channels aka ascChannels for stereoConfigIndex = 1
1687*e5436536SAndroid Build Coastguard Worker * cases */
1688*e5436536SAndroid Build Coastguard Worker if (asc->m_sc.m_usacConfig.element[el].m_stereoConfigIndex == 1) {
1689*e5436536SAndroid Build Coastguard Worker ascChannels--; /* stereoConfigIndex == 1 stereo cases do actually
1690*e5436536SAndroid Build Coastguard Worker contain only a mono core channel. */
1691*e5436536SAndroid Build Coastguard Worker } else if (asc->m_sc.m_usacConfig.element[el].m_stereoConfigIndex == 2) {
1692*e5436536SAndroid Build Coastguard Worker /* In this case it is necessary to follow up the DMX signal delay caused
1693*e5436536SAndroid Build Coastguard Worker by HBE also with the residual signal (2nd core channel). The SBR
1694*e5436536SAndroid Build Coastguard Worker overlap delay is not regarded here, this is handled by the MPS212
1695*e5436536SAndroid Build Coastguard Worker implementation.
1696*e5436536SAndroid Build Coastguard Worker */
1697*e5436536SAndroid Build Coastguard Worker if (asc->m_sc.m_usacConfig.element[el].m_harmonicSBR) {
1698*e5436536SAndroid Build Coastguard Worker usacResidualDelayCompSamples += asc->m_samplesPerFrame;
1699*e5436536SAndroid Build Coastguard Worker }
1700*e5436536SAndroid Build Coastguard Worker if (asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex == 4) {
1701*e5436536SAndroid Build Coastguard Worker usacResidualDelayCompSamples +=
1702*e5436536SAndroid Build Coastguard Worker 6 * 16; /* difference between 12 SBR
1703*e5436536SAndroid Build Coastguard Worker overlap slots from SBR and 6
1704*e5436536SAndroid Build Coastguard Worker slots delayed in MPS212 */
1705*e5436536SAndroid Build Coastguard Worker }
1706*e5436536SAndroid Build Coastguard Worker }
1707*e5436536SAndroid Build Coastguard Worker }
1708*e5436536SAndroid Build Coastguard Worker }
1709*e5436536SAndroid Build Coastguard Worker
1710*e5436536SAndroid Build Coastguard Worker aacChannelsOffset = 0;
1711*e5436536SAndroid Build Coastguard Worker aacChannelsOffsetIdx = 0;
1712*e5436536SAndroid Build Coastguard Worker elementOffset = 0;
1713*e5436536SAndroid Build Coastguard Worker if ((ascChannels <= 0) || (ascChannels > (8)) ||
1714*e5436536SAndroid Build Coastguard Worker (asc->m_channelConfiguration > AACDEC_MAX_CH_CONF)) {
1715*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
1716*e5436536SAndroid Build Coastguard Worker }
1717*e5436536SAndroid Build Coastguard Worker
1718*e5436536SAndroid Build Coastguard Worker /* Set syntax flags */
1719*e5436536SAndroid Build Coastguard Worker flags = 0;
1720*e5436536SAndroid Build Coastguard Worker { FDKmemclear(elFlags, sizeof(elFlags)); }
1721*e5436536SAndroid Build Coastguard Worker
1722*e5436536SAndroid Build Coastguard Worker if ((asc->m_channelConfiguration > 0) || IS_USAC(asc->m_aot)) {
1723*e5436536SAndroid Build Coastguard Worker if (IS_USAC(asc->m_aot)) {
1724*e5436536SAndroid Build Coastguard Worker /* copy pointer to usac config
1725*e5436536SAndroid Build Coastguard Worker (this is preliminary since there's an ongoing discussion about storing
1726*e5436536SAndroid Build Coastguard Worker the config-part of the bitstream rather than the complete decoded
1727*e5436536SAndroid Build Coastguard Worker configuration) */
1728*e5436536SAndroid Build Coastguard Worker self->pUsacConfig[streamIndex] = &asc->m_sc.m_usacConfig;
1729*e5436536SAndroid Build Coastguard Worker
1730*e5436536SAndroid Build Coastguard Worker /* copy list of elements */
1731*e5436536SAndroid Build Coastguard Worker if (self->pUsacConfig[streamIndex]->m_usacNumElements >
1732*e5436536SAndroid Build Coastguard Worker (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
1733*e5436536SAndroid Build Coastguard Worker goto bail;
1734*e5436536SAndroid Build Coastguard Worker }
1735*e5436536SAndroid Build Coastguard Worker
1736*e5436536SAndroid Build Coastguard Worker if (self->numUsacElements[streamIndex] !=
1737*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_usacConfig.m_usacNumElements) {
1738*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1739*e5436536SAndroid Build Coastguard Worker }
1740*e5436536SAndroid Build Coastguard Worker
1741*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1742*e5436536SAndroid Build Coastguard Worker self->numUsacElements[streamIndex] =
1743*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_usacConfig.m_usacNumElements;
1744*e5436536SAndroid Build Coastguard Worker }
1745*e5436536SAndroid Build Coastguard Worker
1746*e5436536SAndroid Build Coastguard Worker mpsEnableCurr = 0;
1747*e5436536SAndroid Build Coastguard Worker for (int _el = 0;
1748*e5436536SAndroid Build Coastguard Worker _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
1749*e5436536SAndroid Build Coastguard Worker _el++) {
1750*e5436536SAndroid Build Coastguard Worker int el = _el + elementOffset;
1751*e5436536SAndroid Build Coastguard Worker if (self->elements[el] !=
1752*e5436536SAndroid Build Coastguard Worker self->pUsacConfig[streamIndex]->element[_el].usacElementType) {
1753*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1754*e5436536SAndroid Build Coastguard Worker }
1755*e5436536SAndroid Build Coastguard Worker if (self->usacStereoConfigIndex[el] !=
1756*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex) {
1757*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1758*e5436536SAndroid Build Coastguard Worker }
1759*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1760*e5436536SAndroid Build Coastguard Worker self->elements[el] =
1761*e5436536SAndroid Build Coastguard Worker self->pUsacConfig[streamIndex]->element[_el].usacElementType;
1762*e5436536SAndroid Build Coastguard Worker /* for Unified Stereo Coding */
1763*e5436536SAndroid Build Coastguard Worker self->usacStereoConfigIndex[el] =
1764*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex;
1765*e5436536SAndroid Build Coastguard Worker if (self->elements[el] == ID_USAC_CPE) {
1766*e5436536SAndroid Build Coastguard Worker mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0;
1767*e5436536SAndroid Build Coastguard Worker }
1768*e5436536SAndroid Build Coastguard Worker }
1769*e5436536SAndroid Build Coastguard Worker
1770*e5436536SAndroid Build Coastguard Worker elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_noiseFilling)
1771*e5436536SAndroid Build Coastguard Worker ? AC_EL_USAC_NOISE
1772*e5436536SAndroid Build Coastguard Worker : 0;
1773*e5436536SAndroid Build Coastguard Worker elFlags[el] |=
1774*e5436536SAndroid Build Coastguard Worker (asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex > 0)
1775*e5436536SAndroid Build Coastguard Worker ? AC_EL_USAC_MPS212
1776*e5436536SAndroid Build Coastguard Worker : 0;
1777*e5436536SAndroid Build Coastguard Worker elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes)
1778*e5436536SAndroid Build Coastguard Worker ? AC_EL_USAC_ITES
1779*e5436536SAndroid Build Coastguard Worker : 0;
1780*e5436536SAndroid Build Coastguard Worker elFlags[el] |=
1781*e5436536SAndroid Build Coastguard Worker (asc->m_sc.m_usacConfig.element[_el].m_pvc) ? AC_EL_USAC_PVC : 0;
1782*e5436536SAndroid Build Coastguard Worker elFlags[el] |=
1783*e5436536SAndroid Build Coastguard Worker (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
1784*e5436536SAndroid Build Coastguard Worker ? AC_EL_USAC_LFE
1785*e5436536SAndroid Build Coastguard Worker : 0;
1786*e5436536SAndroid Build Coastguard Worker elFlags[el] |=
1787*e5436536SAndroid Build Coastguard Worker (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
1788*e5436536SAndroid Build Coastguard Worker ? AC_EL_LFE
1789*e5436536SAndroid Build Coastguard Worker : 0;
1790*e5436536SAndroid Build Coastguard Worker if ((asc->m_sc.m_usacConfig.element[_el].usacElementType ==
1791*e5436536SAndroid Build Coastguard Worker ID_USAC_CPE) &&
1792*e5436536SAndroid Build Coastguard Worker ((self->usacStereoConfigIndex[el] == 0))) {
1793*e5436536SAndroid Build Coastguard Worker elFlags[el] |= AC_EL_USAC_CP_POSSIBLE;
1794*e5436536SAndroid Build Coastguard Worker }
1795*e5436536SAndroid Build Coastguard Worker }
1796*e5436536SAndroid Build Coastguard Worker
1797*e5436536SAndroid Build Coastguard Worker self->hasAudioPreRoll = 0;
1798*e5436536SAndroid Build Coastguard Worker if (self->pUsacConfig[streamIndex]->m_usacNumElements) {
1799*e5436536SAndroid Build Coastguard Worker self->hasAudioPreRoll = asc->m_sc.m_usacConfig.element[0]
1800*e5436536SAndroid Build Coastguard Worker .extElement.usacExtElementHasAudioPreRoll;
1801*e5436536SAndroid Build Coastguard Worker }
1802*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1803*e5436536SAndroid Build Coastguard Worker self->elements[elementOffset +
1804*e5436536SAndroid Build Coastguard Worker self->pUsacConfig[streamIndex]->m_usacNumElements] =
1805*e5436536SAndroid Build Coastguard Worker ID_END;
1806*e5436536SAndroid Build Coastguard Worker }
1807*e5436536SAndroid Build Coastguard Worker } else {
1808*e5436536SAndroid Build Coastguard Worker /* Initialize constant mappings for channel config 1-7 */
1809*e5436536SAndroid Build Coastguard Worker int i;
1810*e5436536SAndroid Build Coastguard Worker for (i = 0; i < AACDEC_CH_ELEMENTS_TAB_SIZE; i++) {
1811*e5436536SAndroid Build Coastguard Worker self->elements[i] = elementsTab[asc->m_channelConfiguration - 1][i];
1812*e5436536SAndroid Build Coastguard Worker }
1813*e5436536SAndroid Build Coastguard Worker for (; i < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1); i++) {
1814*e5436536SAndroid Build Coastguard Worker self->elements[i] = ID_NONE;
1815*e5436536SAndroid Build Coastguard Worker }
1816*e5436536SAndroid Build Coastguard Worker }
1817*e5436536SAndroid Build Coastguard Worker
1818*e5436536SAndroid Build Coastguard Worker {
1819*e5436536SAndroid Build Coastguard Worker int ch;
1820*e5436536SAndroid Build Coastguard Worker
1821*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < ascChannels; ch++) {
1822*e5436536SAndroid Build Coastguard Worker self->chMapping[ch] = ch;
1823*e5436536SAndroid Build Coastguard Worker }
1824*e5436536SAndroid Build Coastguard Worker for (; ch < (8); ch++) {
1825*e5436536SAndroid Build Coastguard Worker self->chMapping[ch] = 255;
1826*e5436536SAndroid Build Coastguard Worker }
1827*e5436536SAndroid Build Coastguard Worker }
1828*e5436536SAndroid Build Coastguard Worker
1829*e5436536SAndroid Build Coastguard Worker self->chMapIndex = asc->m_channelConfiguration;
1830*e5436536SAndroid Build Coastguard Worker } else {
1831*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
1832*e5436536SAndroid Build Coastguard Worker /* Set matrix mixdown infos if available from PCE. */
1833*e5436536SAndroid Build Coastguard Worker pcmDmx_SetMatrixMixdownFromPce(
1834*e5436536SAndroid Build Coastguard Worker self->hPcmUtils, asc->m_progrConfigElement.MatrixMixdownIndexPresent,
1835*e5436536SAndroid Build Coastguard Worker asc->m_progrConfigElement.MatrixMixdownIndex,
1836*e5436536SAndroid Build Coastguard Worker asc->m_progrConfigElement.PseudoSurroundEnable);
1837*e5436536SAndroid Build Coastguard Worker }
1838*e5436536SAndroid Build Coastguard Worker }
1839*e5436536SAndroid Build Coastguard Worker
1840*e5436536SAndroid Build Coastguard Worker self->streamInfo.channelConfig = asc->m_channelConfiguration;
1841*e5436536SAndroid Build Coastguard Worker
1842*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.aot != asc->m_aot) {
1843*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1844*e5436536SAndroid Build Coastguard Worker self->streamInfo.aot = asc->m_aot;
1845*e5436536SAndroid Build Coastguard Worker }
1846*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1847*e5436536SAndroid Build Coastguard Worker }
1848*e5436536SAndroid Build Coastguard Worker
1849*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_ER_AAC_ELD &&
1850*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency != 0) {
1851*e5436536SAndroid Build Coastguard Worker if (self->samplingRateInfo[0].samplingRate !=
1852*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency ||
1853*e5436536SAndroid Build Coastguard Worker self->samplingRateInfo[0].samplingRate * self->downscaleFactor !=
1854*e5436536SAndroid Build Coastguard Worker asc->m_samplingFrequency) {
1855*e5436536SAndroid Build Coastguard Worker /* get downscaledSamplingFrequency from ESC and compute the downscale
1856*e5436536SAndroid Build Coastguard Worker * factor */
1857*e5436536SAndroid Build Coastguard Worker downscaleFactorInBS =
1858*e5436536SAndroid Build Coastguard Worker asc->m_samplingFrequency /
1859*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency;
1860*e5436536SAndroid Build Coastguard Worker if ((downscaleFactorInBS == 1 || downscaleFactorInBS == 2 ||
1861*e5436536SAndroid Build Coastguard Worker (downscaleFactorInBS == 3 &&
1862*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_frameLengthFlag) ||
1863*e5436536SAndroid Build Coastguard Worker downscaleFactorInBS == 4) &&
1864*e5436536SAndroid Build Coastguard Worker ((asc->m_samplingFrequency %
1865*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency) ==
1866*e5436536SAndroid Build Coastguard Worker 0)) {
1867*e5436536SAndroid Build Coastguard Worker downscaleFactor = downscaleFactorInBS;
1868*e5436536SAndroid Build Coastguard Worker } else {
1869*e5436536SAndroid Build Coastguard Worker downscaleFactorInBS = 1;
1870*e5436536SAndroid Build Coastguard Worker downscaleFactor = 1;
1871*e5436536SAndroid Build Coastguard Worker }
1872*e5436536SAndroid Build Coastguard Worker }
1873*e5436536SAndroid Build Coastguard Worker } else {
1874*e5436536SAndroid Build Coastguard Worker downscaleFactorInBS = 1;
1875*e5436536SAndroid Build Coastguard Worker downscaleFactor = 1;
1876*e5436536SAndroid Build Coastguard Worker }
1877*e5436536SAndroid Build Coastguard Worker
1878*e5436536SAndroid Build Coastguard Worker if (self->downscaleFactorInBS != downscaleFactorInBS) {
1879*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1880*e5436536SAndroid Build Coastguard Worker self->downscaleFactorInBS = downscaleFactorInBS;
1881*e5436536SAndroid Build Coastguard Worker self->downscaleFactor = downscaleFactor;
1882*e5436536SAndroid Build Coastguard Worker }
1883*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1884*e5436536SAndroid Build Coastguard Worker }
1885*e5436536SAndroid Build Coastguard Worker
1886*e5436536SAndroid Build Coastguard Worker if ((INT)asc->m_samplesPerFrame % downscaleFactor != 0) {
1887*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* frameSize/dsf must be an integer
1888*e5436536SAndroid Build Coastguard Worker number */
1889*e5436536SAndroid Build Coastguard Worker }
1890*e5436536SAndroid Build Coastguard Worker
1891*e5436536SAndroid Build Coastguard Worker self->streamInfo.bitRate = 0;
1892*e5436536SAndroid Build Coastguard Worker
1893*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_ER_AAC_ELD) {
1894*e5436536SAndroid Build Coastguard Worker if (self->useLdQmfTimeAlign !=
1895*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
1896*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1897*e5436536SAndroid Build Coastguard Worker }
1898*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1899*e5436536SAndroid Build Coastguard Worker self->useLdQmfTimeAlign =
1900*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
1901*e5436536SAndroid Build Coastguard Worker }
1902*e5436536SAndroid Build Coastguard Worker if (sbrEnabled != asc->m_sbrPresentFlag) {
1903*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1904*e5436536SAndroid Build Coastguard Worker }
1905*e5436536SAndroid Build Coastguard Worker }
1906*e5436536SAndroid Build Coastguard Worker
1907*e5436536SAndroid Build Coastguard Worker self->streamInfo.extAot = asc->m_extensionAudioObjectType;
1908*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.extSamplingRate !=
1909*e5436536SAndroid Build Coastguard Worker (INT)asc->m_extensionSamplingFrequency) {
1910*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
1911*e5436536SAndroid Build Coastguard Worker }
1912*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1913*e5436536SAndroid Build Coastguard Worker self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency;
1914*e5436536SAndroid Build Coastguard Worker }
1915*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0;
1916*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0;
1917*e5436536SAndroid Build Coastguard Worker if (asc->m_sbrPresentFlag) {
1918*e5436536SAndroid Build Coastguard Worker sbrEnabled = 1;
1919*e5436536SAndroid Build Coastguard Worker sbrEnabledPrev = 1;
1920*e5436536SAndroid Build Coastguard Worker } else {
1921*e5436536SAndroid Build Coastguard Worker sbrEnabled = 0;
1922*e5436536SAndroid Build Coastguard Worker sbrEnabledPrev = 0;
1923*e5436536SAndroid Build Coastguard Worker }
1924*e5436536SAndroid Build Coastguard Worker if (sbrEnabled && asc->m_extensionSamplingFrequency) {
1925*e5436536SAndroid Build Coastguard Worker if (downscaleFactor != 1 && (downscaleFactor)&1) {
1926*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale
1927*e5436536SAndroid Build Coastguard Worker factor */
1928*e5436536SAndroid Build Coastguard Worker }
1929*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
1930*e5436536SAndroid Build Coastguard Worker self->streamInfo.extSamplingRate =
1931*e5436536SAndroid Build Coastguard Worker self->streamInfo.extSamplingRate / self->downscaleFactor;
1932*e5436536SAndroid Build Coastguard Worker }
1933*e5436536SAndroid Build Coastguard Worker }
1934*e5436536SAndroid Build Coastguard Worker if ((asc->m_aot == AOT_AAC_LC) && (asc->m_sbrPresentFlag == 1) &&
1935*e5436536SAndroid Build Coastguard Worker (asc->m_extensionSamplingFrequency > (2 * asc->m_samplingFrequency))) {
1936*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* Core decoder supports at most a
1937*e5436536SAndroid Build Coastguard Worker 1:2 upsampling for HE-AAC and
1938*e5436536SAndroid Build Coastguard Worker HE-AACv2 */
1939*e5436536SAndroid Build Coastguard Worker }
1940*e5436536SAndroid Build Coastguard Worker
1941*e5436536SAndroid Build Coastguard Worker /* --------- vcb11 ------------ */
1942*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
1943*e5436536SAndroid Build Coastguard Worker
1944*e5436536SAndroid Build Coastguard Worker /* ---------- rvlc ------------ */
1945*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0;
1946*e5436536SAndroid Build Coastguard Worker
1947*e5436536SAndroid Build Coastguard Worker /* ----------- hcr ------------ */
1948*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0;
1949*e5436536SAndroid Build Coastguard Worker
1950*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_ER_AAC_ELD) {
1951*e5436536SAndroid Build Coastguard Worker mpsEnableCurr = 0;
1952*e5436536SAndroid Build Coastguard Worker flags |= AC_ELD;
1953*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_sbrPresentFlag)
1954*e5436536SAndroid Build Coastguard Worker ? AC_SBR_PRESENT
1955*e5436536SAndroid Build Coastguard Worker : 0; /* Need to set the SBR flag for backward-compatibility
1956*e5436536SAndroid Build Coastguard Worker reasons. Even if SBR is not supported. */
1957*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
1958*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign)
1959*e5436536SAndroid Build Coastguard Worker ? AC_MPS_PRESENT
1960*e5436536SAndroid Build Coastguard Worker : 0;
1961*e5436536SAndroid Build Coastguard Worker if (self->mpsApplicable) {
1962*e5436536SAndroid Build Coastguard Worker mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
1963*e5436536SAndroid Build Coastguard Worker }
1964*e5436536SAndroid Build Coastguard Worker }
1965*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
1966*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
1967*e5436536SAndroid Build Coastguard Worker
1968*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_USAC) {
1969*e5436536SAndroid Build Coastguard Worker flags |= AC_USAC;
1970*e5436536SAndroid Build Coastguard Worker flags |= (asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0)
1971*e5436536SAndroid Build Coastguard Worker ? AC_MPS_PRESENT
1972*e5436536SAndroid Build Coastguard Worker : 0;
1973*e5436536SAndroid Build Coastguard Worker }
1974*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_DRM_AAC) {
1975*e5436536SAndroid Build Coastguard Worker flags |= AC_DRM | AC_SBRCRC | AC_SCALABLE;
1976*e5436536SAndroid Build Coastguard Worker }
1977*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_DRM_SURROUND) {
1978*e5436536SAndroid Build Coastguard Worker flags |= AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT;
1979*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(!asc->m_psPresentFlag);
1980*e5436536SAndroid Build Coastguard Worker }
1981*e5436536SAndroid Build Coastguard Worker if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
1982*e5436536SAndroid Build Coastguard Worker flags |= AC_SCALABLE;
1983*e5436536SAndroid Build Coastguard Worker }
1984*e5436536SAndroid Build Coastguard Worker
1985*e5436536SAndroid Build Coastguard Worker if ((asc->m_epConfig >= 0) && (asc->m_channelConfiguration <= 0)) {
1986*e5436536SAndroid Build Coastguard Worker /* we have to know the number of channels otherwise no decoding is possible
1987*e5436536SAndroid Build Coastguard Worker */
1988*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_ER_FORMAT;
1989*e5436536SAndroid Build Coastguard Worker }
1990*e5436536SAndroid Build Coastguard Worker
1991*e5436536SAndroid Build Coastguard Worker self->streamInfo.epConfig = asc->m_epConfig;
1992*e5436536SAndroid Build Coastguard Worker /* self->hInput->asc.m_epConfig = asc->m_epConfig; */
1993*e5436536SAndroid Build Coastguard Worker
1994*e5436536SAndroid Build Coastguard Worker if (asc->m_epConfig > 1) return AAC_DEC_UNSUPPORTED_ER_FORMAT;
1995*e5436536SAndroid Build Coastguard Worker
1996*e5436536SAndroid Build Coastguard Worker /* Check if samplerate changed. */
1997*e5436536SAndroid Build Coastguard Worker if ((self->samplingRateInfo[streamIndex].samplingRate !=
1998*e5436536SAndroid Build Coastguard Worker asc->m_samplingFrequency) ||
1999*e5436536SAndroid Build Coastguard Worker (self->streamInfo.aacSamplesPerFrame !=
2000*e5436536SAndroid Build Coastguard Worker (INT)asc->m_samplesPerFrame / downscaleFactor)) {
2001*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR error;
2002*e5436536SAndroid Build Coastguard Worker
2003*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
2004*e5436536SAndroid Build Coastguard Worker
2005*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_ALLOC_MEM) {
2006*e5436536SAndroid Build Coastguard Worker /* Update samplerate info. */
2007*e5436536SAndroid Build Coastguard Worker error = getSamplingRateInfo(
2008*e5436536SAndroid Build Coastguard Worker &self->samplingRateInfo[streamIndex], asc->m_samplesPerFrame,
2009*e5436536SAndroid Build Coastguard Worker asc->m_samplingFrequencyIndex, asc->m_samplingFrequency);
2010*e5436536SAndroid Build Coastguard Worker if (error != AAC_DEC_OK) {
2011*e5436536SAndroid Build Coastguard Worker return error;
2012*e5436536SAndroid Build Coastguard Worker }
2013*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSampleRate =
2014*e5436536SAndroid Build Coastguard Worker self->samplingRateInfo[0].samplingRate / self->downscaleFactor;
2015*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame =
2016*e5436536SAndroid Build Coastguard Worker asc->m_samplesPerFrame / self->downscaleFactor;
2017*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.aacSampleRate <= 0) {
2018*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
2019*e5436536SAndroid Build Coastguard Worker }
2020*e5436536SAndroid Build Coastguard Worker }
2021*e5436536SAndroid Build Coastguard Worker }
2022*e5436536SAndroid Build Coastguard Worker
2023*e5436536SAndroid Build Coastguard Worker /* Check if amount of channels has changed. */
2024*e5436536SAndroid Build Coastguard Worker if (self->ascChannels[streamIndex] != ascChannels) {
2025*e5436536SAndroid Build Coastguard Worker ascChanged = 1;
2026*e5436536SAndroid Build Coastguard Worker }
2027*e5436536SAndroid Build Coastguard Worker
2028*e5436536SAndroid Build Coastguard Worker /* detect config change */
2029*e5436536SAndroid Build Coastguard Worker if (configMode & AC_CM_DET_CFG_CHANGE) {
2030*e5436536SAndroid Build Coastguard Worker if (ascChanged != 0) {
2031*e5436536SAndroid Build Coastguard Worker *configChanged = 1;
2032*e5436536SAndroid Build Coastguard Worker }
2033*e5436536SAndroid Build Coastguard Worker
2034*e5436536SAndroid Build Coastguard Worker CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex,
2035*e5436536SAndroid Build Coastguard Worker elementOffset);
2036*e5436536SAndroid Build Coastguard Worker
2037*e5436536SAndroid Build Coastguard Worker return err;
2038*e5436536SAndroid Build Coastguard Worker }
2039*e5436536SAndroid Build Coastguard Worker
2040*e5436536SAndroid Build Coastguard Worker /* set AC_USAC_SCFGI3 globally if any usac element uses */
2041*e5436536SAndroid Build Coastguard Worker switch (asc->m_aot) {
2042*e5436536SAndroid Build Coastguard Worker case AOT_USAC:
2043*e5436536SAndroid Build Coastguard Worker if (sbrEnabled) {
2044*e5436536SAndroid Build Coastguard Worker for (int _el = 0;
2045*e5436536SAndroid Build Coastguard Worker _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
2046*e5436536SAndroid Build Coastguard Worker _el++) {
2047*e5436536SAndroid Build Coastguard Worker int el = elementOffset + _el;
2048*e5436536SAndroid Build Coastguard Worker if (IS_USAC_CHANNEL_ELEMENT(self->elements[el])) {
2049*e5436536SAndroid Build Coastguard Worker if (usacStereoConfigIndex < 0) {
2050*e5436536SAndroid Build Coastguard Worker usacStereoConfigIndex = self->usacStereoConfigIndex[el];
2051*e5436536SAndroid Build Coastguard Worker } else {
2052*e5436536SAndroid Build Coastguard Worker if ((usacStereoConfigIndex != self->usacStereoConfigIndex[el]) ||
2053*e5436536SAndroid Build Coastguard Worker (self->usacStereoConfigIndex[el] > 0)) {
2054*e5436536SAndroid Build Coastguard Worker goto bail;
2055*e5436536SAndroid Build Coastguard Worker }
2056*e5436536SAndroid Build Coastguard Worker }
2057*e5436536SAndroid Build Coastguard Worker }
2058*e5436536SAndroid Build Coastguard Worker }
2059*e5436536SAndroid Build Coastguard Worker
2060*e5436536SAndroid Build Coastguard Worker if (usacStereoConfigIndex < 0) {
2061*e5436536SAndroid Build Coastguard Worker goto bail;
2062*e5436536SAndroid Build Coastguard Worker }
2063*e5436536SAndroid Build Coastguard Worker
2064*e5436536SAndroid Build Coastguard Worker if (usacStereoConfigIndex == 3) {
2065*e5436536SAndroid Build Coastguard Worker flags |= AC_USAC_SCFGI3;
2066*e5436536SAndroid Build Coastguard Worker }
2067*e5436536SAndroid Build Coastguard Worker }
2068*e5436536SAndroid Build Coastguard Worker break;
2069*e5436536SAndroid Build Coastguard Worker default:
2070*e5436536SAndroid Build Coastguard Worker break;
2071*e5436536SAndroid Build Coastguard Worker }
2072*e5436536SAndroid Build Coastguard Worker
2073*e5436536SAndroid Build Coastguard Worker if (*configChanged) {
2074*e5436536SAndroid Build Coastguard Worker /* Set up QMF domain for AOTs with explicit signalling of SBR and or MPS.
2075*e5436536SAndroid Build Coastguard Worker This is to be able to play out the first frame alway with the correct
2076*e5436536SAndroid Build Coastguard Worker frame size and sampling rate even in case of concealment.
2077*e5436536SAndroid Build Coastguard Worker */
2078*e5436536SAndroid Build Coastguard Worker switch (asc->m_aot) {
2079*e5436536SAndroid Build Coastguard Worker case AOT_USAC:
2080*e5436536SAndroid Build Coastguard Worker if (sbrEnabled) {
2081*e5436536SAndroid Build Coastguard Worker const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32};
2082*e5436536SAndroid Build Coastguard Worker
2083*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0);
2084*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(streamIndex == 0);
2085*e5436536SAndroid Build Coastguard Worker
2086*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nInputChannels_requested = ascChannels;
2087*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nOutputChannels_requested =
2088*e5436536SAndroid Build Coastguard Worker (usacStereoConfigIndex == 1) ? 2 : ascChannels;
2089*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.flags_requested = 0;
2090*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nBandsAnalysis_requested =
2091*e5436536SAndroid Build Coastguard Worker map_sbrRatio_2_nAnaBands[asc->m_sc.m_usacConfig.m_sbrRatioIndex -
2092*e5436536SAndroid Build Coastguard Worker 1];
2093*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nBandsSynthesis_requested = 64;
2094*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nQmfTimeSlots_requested =
2095*e5436536SAndroid Build Coastguard Worker (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 64 : 32;
2096*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nQmfOvTimeSlots_requested =
2097*e5436536SAndroid Build Coastguard Worker (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 12 : 6;
2098*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nQmfProcBands_requested = 64;
2099*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.nQmfProcChannels_requested = 1;
2100*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.parkChannel =
2101*e5436536SAndroid Build Coastguard Worker (usacStereoConfigIndex == 3) ? 1 : 0;
2102*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.parkChannel_requested =
2103*e5436536SAndroid Build Coastguard Worker (usacStereoConfigIndex == 3) ? 1 : 0;
2104*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1;
2105*e5436536SAndroid Build Coastguard Worker }
2106*e5436536SAndroid Build Coastguard Worker break;
2107*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_ELD:
2108*e5436536SAndroid Build Coastguard Worker if (mpsEnableCurr &&
2109*e5436536SAndroid Build Coastguard Worker asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
2110*e5436536SAndroid Build Coastguard Worker SAC_INPUT_CONFIG sac_interface = (sbrEnabled && self->hSbrDecoder)
2111*e5436536SAndroid Build Coastguard Worker ? SAC_INTERFACE_QMF
2112*e5436536SAndroid Build Coastguard Worker : SAC_INTERFACE_TIME;
2113*e5436536SAndroid Build Coastguard Worker mpegSurroundDecoder_ConfigureQmfDomain(
2114*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
2115*e5436536SAndroid Build Coastguard Worker (UINT)self->streamInfo.aacSampleRate, asc->m_aot);
2116*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1;
2117*e5436536SAndroid Build Coastguard Worker }
2118*e5436536SAndroid Build Coastguard Worker break;
2119*e5436536SAndroid Build Coastguard Worker default:
2120*e5436536SAndroid Build Coastguard Worker self->qmfDomain.globalConf.qmfDomainExplicitConfig =
2121*e5436536SAndroid Build Coastguard Worker 0; /* qmfDomain is initialized by SBR and MPS init functions if
2122*e5436536SAndroid Build Coastguard Worker required */
2123*e5436536SAndroid Build Coastguard Worker break;
2124*e5436536SAndroid Build Coastguard Worker }
2125*e5436536SAndroid Build Coastguard Worker
2126*e5436536SAndroid Build Coastguard Worker /* Allocate all memory structures for each channel */
2127*e5436536SAndroid Build Coastguard Worker {
2128*e5436536SAndroid Build Coastguard Worker int ch = aacChannelsOffset;
2129*e5436536SAndroid Build Coastguard Worker for (int _ch = 0; _ch < ascChannels; _ch++) {
2130*e5436536SAndroid Build Coastguard Worker if (ch >= (8)) {
2131*e5436536SAndroid Build Coastguard Worker goto bail;
2132*e5436536SAndroid Build Coastguard Worker }
2133*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch] = GetAacDecoderChannelInfo(ch);
2134*e5436536SAndroid Build Coastguard Worker /* This is temporary until the DynamicData is split into two or more
2135*e5436536SAndroid Build Coastguard Worker regions! The memory could be reused after completed core decoding. */
2136*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch] == NULL) {
2137*e5436536SAndroid Build Coastguard Worker goto bail;
2138*e5436536SAndroid Build Coastguard Worker }
2139*e5436536SAndroid Build Coastguard Worker ch++;
2140*e5436536SAndroid Build Coastguard Worker }
2141*e5436536SAndroid Build Coastguard Worker
2142*e5436536SAndroid Build Coastguard Worker int chIdx = aacChannelsOffsetIdx;
2143*e5436536SAndroid Build Coastguard Worker ch = aacChannelsOffset;
2144*e5436536SAndroid Build Coastguard Worker int _numElements;
2145*e5436536SAndroid Build Coastguard Worker _numElements = (((8)) + (8));
2146*e5436536SAndroid Build Coastguard Worker if (flags & (AC_RSV603DA | AC_USAC)) {
2147*e5436536SAndroid Build Coastguard Worker _numElements = (int)asc->m_sc.m_usacConfig.m_usacNumElements;
2148*e5436536SAndroid Build Coastguard Worker }
2149*e5436536SAndroid Build Coastguard Worker for (int _el = 0; _el < _numElements; _el++) {
2150*e5436536SAndroid Build Coastguard Worker int el_channels = 0;
2151*e5436536SAndroid Build Coastguard Worker int el = elementOffset + _el;
2152*e5436536SAndroid Build Coastguard Worker
2153*e5436536SAndroid Build Coastguard Worker if (flags &
2154*e5436536SAndroid Build Coastguard Worker (AC_ER | AC_LD | AC_ELD | AC_RSV603DA | AC_USAC | AC_RSVD50)) {
2155*e5436536SAndroid Build Coastguard Worker if (ch >= ascChannels) {
2156*e5436536SAndroid Build Coastguard Worker break;
2157*e5436536SAndroid Build Coastguard Worker }
2158*e5436536SAndroid Build Coastguard Worker }
2159*e5436536SAndroid Build Coastguard Worker
2160*e5436536SAndroid Build Coastguard Worker switch (self->elements[el]) {
2161*e5436536SAndroid Build Coastguard Worker case ID_SCE:
2162*e5436536SAndroid Build Coastguard Worker case ID_CPE:
2163*e5436536SAndroid Build Coastguard Worker case ID_LFE:
2164*e5436536SAndroid Build Coastguard Worker case ID_USAC_SCE:
2165*e5436536SAndroid Build Coastguard Worker case ID_USAC_CPE:
2166*e5436536SAndroid Build Coastguard Worker case ID_USAC_LFE:
2167*e5436536SAndroid Build Coastguard Worker
2168*e5436536SAndroid Build Coastguard Worker el_channels = CAacDecoder_GetELChannels(
2169*e5436536SAndroid Build Coastguard Worker self->elements[el], self->usacStereoConfigIndex[el]);
2170*e5436536SAndroid Build Coastguard Worker
2171*e5436536SAndroid Build Coastguard Worker {
2172*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComStaticData =
2173*e5436536SAndroid Build Coastguard Worker (CAacDecoderCommonStaticData *)FDKcalloc(
2174*e5436536SAndroid Build Coastguard Worker 1, sizeof(CAacDecoderCommonStaticData));
2175*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch]->pComStaticData == NULL) {
2176*e5436536SAndroid Build Coastguard Worker goto bail;
2177*e5436536SAndroid Build Coastguard Worker }
2178*e5436536SAndroid Build Coastguard Worker if (ch == aacChannelsOffset) {
2179*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComData =
2180*e5436536SAndroid Build Coastguard Worker (CAacDecoderCommonData *)GetWorkBufferCore6();
2181*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]
2182*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1 = GetWorkBufferCore1();
2183*e5436536SAndroid Build Coastguard Worker } else {
2184*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComData =
2185*e5436536SAndroid Build Coastguard Worker (CAacDecoderCommonData *)FDKaalloc(
2186*e5436536SAndroid Build Coastguard Worker sizeof(CAacDecoderCommonData), ALIGNMENT_DEFAULT);
2187*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]
2188*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1 =
2189*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[aacChannelsOffset]
2190*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1;
2191*e5436536SAndroid Build Coastguard Worker }
2192*e5436536SAndroid Build Coastguard Worker if ((self->pAacDecoderChannelInfo[ch]->pComData == NULL) ||
2193*e5436536SAndroid Build Coastguard Worker (self->pAacDecoderChannelInfo[ch]
2194*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1 == NULL)) {
2195*e5436536SAndroid Build Coastguard Worker goto bail;
2196*e5436536SAndroid Build Coastguard Worker }
2197*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pDynData =
2198*e5436536SAndroid Build Coastguard Worker &(self->pAacDecoderChannelInfo[ch]
2199*e5436536SAndroid Build Coastguard Worker ->pComData->pAacDecoderDynamicData[0]);
2200*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pSpectralCoefficient =
2201*e5436536SAndroid Build Coastguard Worker (SPECTRAL_PTR)&self->workBufferCore2[ch * 1024];
2202*e5436536SAndroid Build Coastguard Worker
2203*e5436536SAndroid Build Coastguard Worker if (el_channels == 2) {
2204*e5436536SAndroid Build Coastguard Worker if (ch >= (8) - 1) {
2205*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
2206*e5436536SAndroid Build Coastguard Worker }
2207*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]->pComData =
2208*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComData;
2209*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]->pComStaticData =
2210*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComStaticData;
2211*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]
2212*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1 =
2213*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]
2214*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1;
2215*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]->pDynData =
2216*e5436536SAndroid Build Coastguard Worker &(self->pAacDecoderChannelInfo[ch]
2217*e5436536SAndroid Build Coastguard Worker ->pComData->pAacDecoderDynamicData[1]);
2218*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch + 1]->pSpectralCoefficient =
2219*e5436536SAndroid Build Coastguard Worker (SPECTRAL_PTR)&self->workBufferCore2[(ch + 1) * 1024];
2220*e5436536SAndroid Build Coastguard Worker }
2221*e5436536SAndroid Build Coastguard Worker
2222*e5436536SAndroid Build Coastguard Worker ch += el_channels;
2223*e5436536SAndroid Build Coastguard Worker }
2224*e5436536SAndroid Build Coastguard Worker chIdx += el_channels;
2225*e5436536SAndroid Build Coastguard Worker break;
2226*e5436536SAndroid Build Coastguard Worker
2227*e5436536SAndroid Build Coastguard Worker default:
2228*e5436536SAndroid Build Coastguard Worker break;
2229*e5436536SAndroid Build Coastguard Worker }
2230*e5436536SAndroid Build Coastguard Worker
2231*e5436536SAndroid Build Coastguard Worker if (self->elements[el] == ID_END) {
2232*e5436536SAndroid Build Coastguard Worker break;
2233*e5436536SAndroid Build Coastguard Worker }
2234*e5436536SAndroid Build Coastguard Worker
2235*e5436536SAndroid Build Coastguard Worker el++;
2236*e5436536SAndroid Build Coastguard Worker }
2237*e5436536SAndroid Build Coastguard Worker
2238*e5436536SAndroid Build Coastguard Worker chIdx = aacChannelsOffsetIdx;
2239*e5436536SAndroid Build Coastguard Worker ch = aacChannelsOffset;
2240*e5436536SAndroid Build Coastguard Worker for (int _ch = 0; _ch < ascChannels; _ch++) {
2241*e5436536SAndroid Build Coastguard Worker /* Allocate persistent channel memory */
2242*e5436536SAndroid Build Coastguard Worker {
2243*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch] =
2244*e5436536SAndroid Build Coastguard Worker GetAacDecoderStaticChannelInfo(ch);
2245*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch] == NULL) {
2246*e5436536SAndroid Build Coastguard Worker goto bail;
2247*e5436536SAndroid Build Coastguard Worker }
2248*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer =
2249*e5436536SAndroid Build Coastguard Worker GetOverlapBuffer(ch); /* This area size depends on the AOT */
2250*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) {
2251*e5436536SAndroid Build Coastguard Worker goto bail;
2252*e5436536SAndroid Build Coastguard Worker }
2253*e5436536SAndroid Build Coastguard Worker if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) {
2254*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->hArCo = CArco_Create();
2255*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch]->hArCo == NULL) {
2256*e5436536SAndroid Build Coastguard Worker goto bail;
2257*e5436536SAndroid Build Coastguard Worker }
2258*e5436536SAndroid Build Coastguard Worker }
2259*e5436536SAndroid Build Coastguard Worker
2260*e5436536SAndroid Build Coastguard Worker if (!(flags & (AC_USAC | AC_RSV603DA))) {
2261*e5436536SAndroid Build Coastguard Worker CPns_UpdateNoiseState(
2262*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderChannelInfo[ch]->data.aac.PnsData,
2263*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[ch]->pnsCurrentSeed,
2264*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
2265*e5436536SAndroid Build Coastguard Worker }
2266*e5436536SAndroid Build Coastguard Worker ch++;
2267*e5436536SAndroid Build Coastguard Worker }
2268*e5436536SAndroid Build Coastguard Worker chIdx++;
2269*e5436536SAndroid Build Coastguard Worker }
2270*e5436536SAndroid Build Coastguard Worker
2271*e5436536SAndroid Build Coastguard Worker if (flags & AC_USAC) {
2272*e5436536SAndroid Build Coastguard Worker for (int _ch = 0; _ch < flushChannels; _ch++) {
2273*e5436536SAndroid Build Coastguard Worker ch = aacChannelsOffset + _ch;
2274*e5436536SAndroid Build Coastguard Worker if (self->pTimeDataFlush[ch] == NULL) {
2275*e5436536SAndroid Build Coastguard Worker self->pTimeDataFlush[ch] = GetTimeDataFlush(ch);
2276*e5436536SAndroid Build Coastguard Worker if (self->pTimeDataFlush[ch] == NULL) {
2277*e5436536SAndroid Build Coastguard Worker goto bail;
2278*e5436536SAndroid Build Coastguard Worker }
2279*e5436536SAndroid Build Coastguard Worker }
2280*e5436536SAndroid Build Coastguard Worker }
2281*e5436536SAndroid Build Coastguard Worker }
2282*e5436536SAndroid Build Coastguard Worker
2283*e5436536SAndroid Build Coastguard Worker if (flags & (AC_USAC | AC_RSV603DA)) {
2284*e5436536SAndroid Build Coastguard Worker int complexStereoPredPossible = 0;
2285*e5436536SAndroid Build Coastguard Worker ch = aacChannelsOffset;
2286*e5436536SAndroid Build Coastguard Worker chIdx = aacChannelsOffsetIdx;
2287*e5436536SAndroid Build Coastguard Worker for (int _el2 = 0; _el2 < (int)asc->m_sc.m_usacConfig.m_usacNumElements;
2288*e5436536SAndroid Build Coastguard Worker _el2++) {
2289*e5436536SAndroid Build Coastguard Worker int el2 = elementOffset + _el2;
2290*e5436536SAndroid Build Coastguard Worker int elCh = 0, ch2;
2291*e5436536SAndroid Build Coastguard Worker
2292*e5436536SAndroid Build Coastguard Worker if ((self->elements[el2] == ID_USAC_CPE) &&
2293*e5436536SAndroid Build Coastguard Worker !(self->usacStereoConfigIndex[el2] == 1)) {
2294*e5436536SAndroid Build Coastguard Worker elCh = 2;
2295*e5436536SAndroid Build Coastguard Worker } else if (IS_CHANNEL_ELEMENT(self->elements[el2])) {
2296*e5436536SAndroid Build Coastguard Worker elCh = 1;
2297*e5436536SAndroid Build Coastguard Worker }
2298*e5436536SAndroid Build Coastguard Worker
2299*e5436536SAndroid Build Coastguard Worker if (elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) {
2300*e5436536SAndroid Build Coastguard Worker complexStereoPredPossible = 1;
2301*e5436536SAndroid Build Coastguard Worker if (self->cpeStaticData[el2] == NULL) {
2302*e5436536SAndroid Build Coastguard Worker self->cpeStaticData[el2] = GetCpePersistentData();
2303*e5436536SAndroid Build Coastguard Worker if (self->cpeStaticData[el2] == NULL) {
2304*e5436536SAndroid Build Coastguard Worker goto bail;
2305*e5436536SAndroid Build Coastguard Worker }
2306*e5436536SAndroid Build Coastguard Worker }
2307*e5436536SAndroid Build Coastguard Worker }
2308*e5436536SAndroid Build Coastguard Worker
2309*e5436536SAndroid Build Coastguard Worker for (ch2 = 0; ch2 < elCh; ch2++) {
2310*e5436536SAndroid Build Coastguard Worker /* Hook element specific cpeStaticData into channel specific
2311*e5436536SAndroid Build Coastguard Worker * aacDecoderStaticChannelInfo */
2312*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData =
2313*e5436536SAndroid Build Coastguard Worker self->cpeStaticData[el2];
2314*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData !=
2315*e5436536SAndroid Build Coastguard Worker NULL) {
2316*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]
2317*e5436536SAndroid Build Coastguard Worker ->pCpeStaticData->jointStereoPersistentData
2318*e5436536SAndroid Build Coastguard Worker .spectralCoeffs[ch2] =
2319*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]
2320*e5436536SAndroid Build Coastguard Worker ->concealmentInfo.spectralCoefficient;
2321*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]
2322*e5436536SAndroid Build Coastguard Worker ->pCpeStaticData->jointStereoPersistentData.specScale[ch2] =
2323*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]
2324*e5436536SAndroid Build Coastguard Worker ->concealmentInfo.specScale;
2325*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]
2326*e5436536SAndroid Build Coastguard Worker ->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
2327*e5436536SAndroid Build Coastguard Worker (FIXP_DBL *)self->pTimeData2;
2328*e5436536SAndroid Build Coastguard Worker }
2329*e5436536SAndroid Build Coastguard Worker chIdx++;
2330*e5436536SAndroid Build Coastguard Worker ch++;
2331*e5436536SAndroid Build Coastguard Worker } /* for each channel in current element */
2332*e5436536SAndroid Build Coastguard Worker if (complexStereoPredPossible && (elCh == 2)) {
2333*e5436536SAndroid Build Coastguard Worker /* needed once for all channels */
2334*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch - 1]
2335*e5436536SAndroid Build Coastguard Worker ->pComStaticData->cplxPredictionData == NULL) {
2336*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch - 1]
2337*e5436536SAndroid Build Coastguard Worker ->pComStaticData->cplxPredictionData =
2338*e5436536SAndroid Build Coastguard Worker GetCplxPredictionData();
2339*e5436536SAndroid Build Coastguard Worker }
2340*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[ch - 1]
2341*e5436536SAndroid Build Coastguard Worker ->pComStaticData->cplxPredictionData == NULL) {
2342*e5436536SAndroid Build Coastguard Worker goto bail;
2343*e5436536SAndroid Build Coastguard Worker }
2344*e5436536SAndroid Build Coastguard Worker }
2345*e5436536SAndroid Build Coastguard Worker if (elCh > 0) {
2346*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch - elCh]->nfRandomSeed =
2347*e5436536SAndroid Build Coastguard Worker (ULONG)0x3039;
2348*e5436536SAndroid Build Coastguard Worker if (self->elements[el2] == ID_USAC_CPE) {
2349*e5436536SAndroid Build Coastguard Worker if (asc->m_sc.m_usacConfig.element[el2].m_stereoConfigIndex !=
2350*e5436536SAndroid Build Coastguard Worker 1) {
2351*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch - elCh + 1]
2352*e5436536SAndroid Build Coastguard Worker ->nfRandomSeed = (ULONG)0x10932;
2353*e5436536SAndroid Build Coastguard Worker }
2354*e5436536SAndroid Build Coastguard Worker }
2355*e5436536SAndroid Build Coastguard Worker }
2356*e5436536SAndroid Build Coastguard Worker } /* for each element */
2357*e5436536SAndroid Build Coastguard Worker }
2358*e5436536SAndroid Build Coastguard Worker
2359*e5436536SAndroid Build Coastguard Worker if (ascChannels != self->aacChannels) {
2360*e5436536SAndroid Build Coastguard Worker /* Make allocated channel count persistent in decoder context. */
2361*e5436536SAndroid Build Coastguard Worker self->aacChannels = aacChannelsOffset + ch;
2362*e5436536SAndroid Build Coastguard Worker }
2363*e5436536SAndroid Build Coastguard Worker }
2364*e5436536SAndroid Build Coastguard Worker
2365*e5436536SAndroid Build Coastguard Worker if (usacResidualDelayCompSamples) {
2366*e5436536SAndroid Build Coastguard Worker INT delayErr = FDK_Delay_Create(&self->usacResidualDelay,
2367*e5436536SAndroid Build Coastguard Worker (USHORT)usacResidualDelayCompSamples, 1);
2368*e5436536SAndroid Build Coastguard Worker if (delayErr) {
2369*e5436536SAndroid Build Coastguard Worker goto bail;
2370*e5436536SAndroid Build Coastguard Worker }
2371*e5436536SAndroid Build Coastguard Worker }
2372*e5436536SAndroid Build Coastguard Worker
2373*e5436536SAndroid Build Coastguard Worker /* Make amount of signalled channels persistent in decoder context. */
2374*e5436536SAndroid Build Coastguard Worker self->ascChannels[streamIndex] = ascChannels;
2375*e5436536SAndroid Build Coastguard Worker /* Init the previous channel count values. This is required to avoid a
2376*e5436536SAndroid Build Coastguard Worker mismatch of memory accesses in the error concealment module and the
2377*e5436536SAndroid Build Coastguard Worker allocated channel structures in this function. */
2378*e5436536SAndroid Build Coastguard Worker self->aacChannelsPrev = 0;
2379*e5436536SAndroid Build Coastguard Worker }
2380*e5436536SAndroid Build Coastguard Worker
2381*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderChannelInfo[0] != NULL) {
2382*e5436536SAndroid Build Coastguard Worker self->pDrmBsBuffer = self->pAacDecoderChannelInfo[0]
2383*e5436536SAndroid Build Coastguard Worker ->pComStaticData->pWorkBufferCore1->DrmBsBuffer;
2384*e5436536SAndroid Build Coastguard Worker self->drmBsBufferSize = DRM_BS_BUFFER_SIZE;
2385*e5436536SAndroid Build Coastguard Worker }
2386*e5436536SAndroid Build Coastguard Worker
2387*e5436536SAndroid Build Coastguard Worker /* Update structures */
2388*e5436536SAndroid Build Coastguard Worker if (*configChanged) {
2389*e5436536SAndroid Build Coastguard Worker /* Things to be done for each channel, which do not involve allocating
2390*e5436536SAndroid Build Coastguard Worker memory. Doing these things only on the channels needed for the current
2391*e5436536SAndroid Build Coastguard Worker configuration (ascChannels) could lead to memory access violation later
2392*e5436536SAndroid Build Coastguard Worker (error concealment). */
2393*e5436536SAndroid Build Coastguard Worker int ch = 0;
2394*e5436536SAndroid Build Coastguard Worker int chIdx = 0;
2395*e5436536SAndroid Build Coastguard Worker for (int _ch = 0; _ch < self->ascChannels[streamIndex]; _ch++) {
2396*e5436536SAndroid Build Coastguard Worker switch (self->streamInfo.aot) {
2397*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_ELD:
2398*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LD:
2399*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->granuleLength =
2400*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame;
2401*e5436536SAndroid Build Coastguard Worker break;
2402*e5436536SAndroid Build Coastguard Worker default:
2403*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->granuleLength =
2404*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame / 8;
2405*e5436536SAndroid Build Coastguard Worker break;
2406*e5436536SAndroid Build Coastguard Worker }
2407*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[ch]->renderMode = initRenderMode;
2408*e5436536SAndroid Build Coastguard Worker
2409*e5436536SAndroid Build Coastguard Worker mdct_init(&self->pAacDecoderStaticChannelInfo[ch]->IMdct,
2410*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
2411*e5436536SAndroid Build Coastguard Worker OverlapBufferSize);
2412*e5436536SAndroid Build Coastguard Worker
2413*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->last_core_mode = FD_LONG;
2414*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->last_lpd_mode = 255;
2415*e5436536SAndroid Build Coastguard Worker
2416*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[ch]->last_tcx_pitch = L_DIV;
2417*e5436536SAndroid Build Coastguard Worker
2418*e5436536SAndroid Build Coastguard Worker /* Reset DRC control data for this channel */
2419*e5436536SAndroid Build Coastguard Worker aacDecoder_drcInitChannelData(
2420*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[ch]->drcData);
2421*e5436536SAndroid Build Coastguard Worker
2422*e5436536SAndroid Build Coastguard Worker /* Delete mixdown metadata from the past */
2423*e5436536SAndroid Build Coastguard Worker pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
2424*e5436536SAndroid Build Coastguard Worker
2425*e5436536SAndroid Build Coastguard Worker /* Reset concealment only if ASC changed. Otherwise it will be done with
2426*e5436536SAndroid Build Coastguard Worker any config callback. E.g. every time the LATM SMC is present. */
2427*e5436536SAndroid Build Coastguard Worker CConcealment_InitChannelData(
2428*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
2429*e5436536SAndroid Build Coastguard Worker &self->concealCommonData, initRenderMode,
2430*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame);
2431*e5436536SAndroid Build Coastguard Worker ch++;
2432*e5436536SAndroid Build Coastguard Worker chIdx++;
2433*e5436536SAndroid Build Coastguard Worker }
2434*e5436536SAndroid Build Coastguard Worker }
2435*e5436536SAndroid Build Coastguard Worker
2436*e5436536SAndroid Build Coastguard Worker if (*configChanged) {
2437*e5436536SAndroid Build Coastguard Worker int drcDecSampleRate, drcDecFrameSize;
2438*e5436536SAndroid Build Coastguard Worker
2439*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.extSamplingRate != 0) {
2440*e5436536SAndroid Build Coastguard Worker drcDecSampleRate = self->streamInfo.extSamplingRate;
2441*e5436536SAndroid Build Coastguard Worker drcDecFrameSize = (self->streamInfo.aacSamplesPerFrame *
2442*e5436536SAndroid Build Coastguard Worker self->streamInfo.extSamplingRate) /
2443*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSampleRate;
2444*e5436536SAndroid Build Coastguard Worker } else {
2445*e5436536SAndroid Build Coastguard Worker drcDecSampleRate = self->streamInfo.aacSampleRate;
2446*e5436536SAndroid Build Coastguard Worker drcDecFrameSize = self->streamInfo.aacSamplesPerFrame;
2447*e5436536SAndroid Build Coastguard Worker }
2448*e5436536SAndroid Build Coastguard Worker
2449*e5436536SAndroid Build Coastguard Worker if (FDK_drcDec_Init(self->hUniDrcDecoder, drcDecFrameSize, drcDecSampleRate,
2450*e5436536SAndroid Build Coastguard Worker self->aacChannels) != 0)
2451*e5436536SAndroid Build Coastguard Worker goto bail;
2452*e5436536SAndroid Build Coastguard Worker }
2453*e5436536SAndroid Build Coastguard Worker
2454*e5436536SAndroid Build Coastguard Worker if (*configChanged) {
2455*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_USAC) {
2456*e5436536SAndroid Build Coastguard Worker aacDecoder_drcDisable(self->hDrcInfo);
2457*e5436536SAndroid Build Coastguard Worker }
2458*e5436536SAndroid Build Coastguard Worker }
2459*e5436536SAndroid Build Coastguard Worker
2460*e5436536SAndroid Build Coastguard Worker if (asc->m_aot == AOT_USAC) {
2461*e5436536SAndroid Build Coastguard Worker pcmLimiter_SetAttack(self->hLimiter, (5));
2462*e5436536SAndroid Build Coastguard Worker pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
2463*e5436536SAndroid Build Coastguard Worker }
2464*e5436536SAndroid Build Coastguard Worker
2465*e5436536SAndroid Build Coastguard Worker CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex,
2466*e5436536SAndroid Build Coastguard Worker elementOffset);
2467*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = sbrEnabled;
2468*e5436536SAndroid Build Coastguard Worker self->sbrEnabledPrev = sbrEnabledPrev;
2469*e5436536SAndroid Build Coastguard Worker self->mpsEnableCurr = mpsEnableCurr;
2470*e5436536SAndroid Build Coastguard Worker
2471*e5436536SAndroid Build Coastguard Worker /* Update externally visible copy of flags */
2472*e5436536SAndroid Build Coastguard Worker self->streamInfo.flags = self->flags[0];
2473*e5436536SAndroid Build Coastguard Worker
2474*e5436536SAndroid Build Coastguard Worker return err;
2475*e5436536SAndroid Build Coastguard Worker
2476*e5436536SAndroid Build Coastguard Worker bail:
2477*e5436536SAndroid Build Coastguard Worker CAacDecoder_DeInit(self, 0);
2478*e5436536SAndroid Build Coastguard Worker return AAC_DEC_OUT_OF_MEMORY;
2479*e5436536SAndroid Build Coastguard Worker }
2480*e5436536SAndroid Build Coastguard Worker
CAacDecoder_DecodeFrame(HANDLE_AACDECODER self,const UINT flags,PCM_DEC * pTimeData,const INT timeDataSize,const int timeDataChannelOffset)2481*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
2482*e5436536SAndroid Build Coastguard Worker HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData,
2483*e5436536SAndroid Build Coastguard Worker const INT timeDataSize, const int timeDataChannelOffset) {
2484*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
2485*e5436536SAndroid Build Coastguard Worker
2486*e5436536SAndroid Build Coastguard Worker CProgramConfig *pce;
2487*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM bs = transportDec_GetBitstream(self->hInput, 0);
2488*e5436536SAndroid Build Coastguard Worker
2489*e5436536SAndroid Build Coastguard Worker MP4_ELEMENT_ID type = ID_NONE; /* Current element type */
2490*e5436536SAndroid Build Coastguard Worker INT aacChannels = 0; /* Channel counter for channels found in the bitstream */
2491*e5436536SAndroid Build Coastguard Worker const int streamIndex = 0; /* index of the current substream */
2492*e5436536SAndroid Build Coastguard Worker
2493*e5436536SAndroid Build Coastguard Worker INT auStartAnchor = (INT)FDKgetValidBits(
2494*e5436536SAndroid Build Coastguard Worker bs); /* AU start bit buffer position for AU byte alignment */
2495*e5436536SAndroid Build Coastguard Worker
2496*e5436536SAndroid Build Coastguard Worker INT checkSampleRate = self->streamInfo.aacSampleRate;
2497*e5436536SAndroid Build Coastguard Worker
2498*e5436536SAndroid Build Coastguard Worker INT CConceal_TDFading_Applied[(8)] = {
2499*e5436536SAndroid Build Coastguard Worker 0}; /* Initialize status of Time Domain fading */
2500*e5436536SAndroid Build Coastguard Worker
2501*e5436536SAndroid Build Coastguard Worker if (self->aacChannels <= 0) {
2502*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
2503*e5436536SAndroid Build Coastguard Worker }
2504*e5436536SAndroid Build Coastguard Worker
2505*e5436536SAndroid Build Coastguard Worker /* Any supported base layer valid AU will require more than 16 bits. */
2506*e5436536SAndroid Build Coastguard Worker if ((transportDec_GetAuBitsRemaining(self->hInput, 0) < 15) &&
2507*e5436536SAndroid Build Coastguard Worker (flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) == 0) {
2508*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2509*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
2510*e5436536SAndroid Build Coastguard Worker }
2511*e5436536SAndroid Build Coastguard Worker
2512*e5436536SAndroid Build Coastguard Worker /* Reset Program Config structure */
2513*e5436536SAndroid Build Coastguard Worker pce = &self->pce;
2514*e5436536SAndroid Build Coastguard Worker CProgramConfig_Reset(pce);
2515*e5436536SAndroid Build Coastguard Worker
2516*e5436536SAndroid Build Coastguard Worker CAacDecoder_AncDataReset(&self->ancData);
2517*e5436536SAndroid Build Coastguard Worker if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
2518*e5436536SAndroid Build Coastguard Worker !(self->flags[0] & (AC_USAC | AC_RSV603DA))) {
2519*e5436536SAndroid Build Coastguard Worker int ch;
2520*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.channelConfig == 0) {
2521*e5436536SAndroid Build Coastguard Worker /* Init Channel/Element mapping table */
2522*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < (8); ch++) {
2523*e5436536SAndroid Build Coastguard Worker self->chMapping[ch] = 255;
2524*e5436536SAndroid Build Coastguard Worker }
2525*e5436536SAndroid Build Coastguard Worker if (!CProgramConfig_IsValid(pce)) {
2526*e5436536SAndroid Build Coastguard Worker int el;
2527*e5436536SAndroid Build Coastguard Worker for (el = 0; el < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
2528*e5436536SAndroid Build Coastguard Worker el++) {
2529*e5436536SAndroid Build Coastguard Worker self->elements[el] = ID_NONE;
2530*e5436536SAndroid Build Coastguard Worker }
2531*e5436536SAndroid Build Coastguard Worker }
2532*e5436536SAndroid Build Coastguard Worker }
2533*e5436536SAndroid Build Coastguard Worker }
2534*e5436536SAndroid Build Coastguard Worker
2535*e5436536SAndroid Build Coastguard Worker if (self->downscaleFactor > 1 && (self->flags[0] & AC_ELD)) {
2536*e5436536SAndroid Build Coastguard Worker self->flags[0] |= AC_ELD_DOWNSCALE;
2537*e5436536SAndroid Build Coastguard Worker } else {
2538*e5436536SAndroid Build Coastguard Worker self->flags[0] &= ~AC_ELD_DOWNSCALE;
2539*e5436536SAndroid Build Coastguard Worker }
2540*e5436536SAndroid Build Coastguard Worker /* unsupported dsf (aacSampleRate has not yet been divided by dsf) -> divide
2541*e5436536SAndroid Build Coastguard Worker */
2542*e5436536SAndroid Build Coastguard Worker if (self->downscaleFactorInBS > 1 &&
2543*e5436536SAndroid Build Coastguard Worker (self->flags[0] & AC_ELD_DOWNSCALE) == 0) {
2544*e5436536SAndroid Build Coastguard Worker checkSampleRate =
2545*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSampleRate / self->downscaleFactorInBS;
2546*e5436536SAndroid Build Coastguard Worker }
2547*e5436536SAndroid Build Coastguard Worker
2548*e5436536SAndroid Build Coastguard Worker /* Check sampling frequency */
2549*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.aacSampleRate <= 0) {
2550*e5436536SAndroid Build Coastguard Worker /* Instance maybe uninitialized! */
2551*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
2552*e5436536SAndroid Build Coastguard Worker }
2553*e5436536SAndroid Build Coastguard Worker switch (checkSampleRate) {
2554*e5436536SAndroid Build Coastguard Worker case 96000:
2555*e5436536SAndroid Build Coastguard Worker case 88200:
2556*e5436536SAndroid Build Coastguard Worker case 64000:
2557*e5436536SAndroid Build Coastguard Worker case 16000:
2558*e5436536SAndroid Build Coastguard Worker case 12000:
2559*e5436536SAndroid Build Coastguard Worker case 11025:
2560*e5436536SAndroid Build Coastguard Worker case 8000:
2561*e5436536SAndroid Build Coastguard Worker case 7350:
2562*e5436536SAndroid Build Coastguard Worker case 48000:
2563*e5436536SAndroid Build Coastguard Worker case 44100:
2564*e5436536SAndroid Build Coastguard Worker case 32000:
2565*e5436536SAndroid Build Coastguard Worker case 24000:
2566*e5436536SAndroid Build Coastguard Worker case 22050:
2567*e5436536SAndroid Build Coastguard Worker break;
2568*e5436536SAndroid Build Coastguard Worker default:
2569*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
2570*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
2571*e5436536SAndroid Build Coastguard Worker }
2572*e5436536SAndroid Build Coastguard Worker break;
2573*e5436536SAndroid Build Coastguard Worker }
2574*e5436536SAndroid Build Coastguard Worker
2575*e5436536SAndroid Build Coastguard Worker if (flags & AACDEC_CLRHIST) {
2576*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] & AC_USAC)) {
2577*e5436536SAndroid Build Coastguard Worker int ch;
2578*e5436536SAndroid Build Coastguard Worker /* Clear history */
2579*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->aacChannels; ch++) {
2580*e5436536SAndroid Build Coastguard Worker /* Reset concealment */
2581*e5436536SAndroid Build Coastguard Worker CConcealment_InitChannelData(
2582*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
2583*e5436536SAndroid Build Coastguard Worker &self->concealCommonData,
2584*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[0]->renderMode,
2585*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame);
2586*e5436536SAndroid Build Coastguard Worker /* Clear overlap-add buffers to avoid clicks. */
2587*e5436536SAndroid Build Coastguard Worker FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
2588*e5436536SAndroid Build Coastguard Worker OverlapBufferSize * sizeof(FIXP_DBL));
2589*e5436536SAndroid Build Coastguard Worker }
2590*e5436536SAndroid Build Coastguard Worker if (self->streamInfo.channelConfig > 0) {
2591*e5436536SAndroid Build Coastguard Worker /* Declare the possibly adopted old PCE (with outdated metadata)
2592*e5436536SAndroid Build Coastguard Worker * invalid. */
2593*e5436536SAndroid Build Coastguard Worker CProgramConfig_Init(pce);
2594*e5436536SAndroid Build Coastguard Worker }
2595*e5436536SAndroid Build Coastguard Worker }
2596*e5436536SAndroid Build Coastguard Worker }
2597*e5436536SAndroid Build Coastguard Worker
2598*e5436536SAndroid Build Coastguard Worker int pceRead = 0; /* Flag indicating a PCE in the current raw_data_block() */
2599*e5436536SAndroid Build Coastguard Worker
2600*e5436536SAndroid Build Coastguard Worker INT hdaacDecoded = 0;
2601*e5436536SAndroid Build Coastguard Worker MP4_ELEMENT_ID previous_element =
2602*e5436536SAndroid Build Coastguard Worker ID_END; /* Last element ID (required for extension payload mapping */
2603*e5436536SAndroid Build Coastguard Worker UCHAR previous_element_index = 0; /* Canonical index of last element */
2604*e5436536SAndroid Build Coastguard Worker int element_count =
2605*e5436536SAndroid Build Coastguard Worker 0; /* Element counter for elements found in the bitstream */
2606*e5436536SAndroid Build Coastguard Worker int channel_element_count = 0; /* Channel element counter */
2607*e5436536SAndroid Build Coastguard Worker MP4_ELEMENT_ID
2608*e5436536SAndroid Build Coastguard Worker channel_elements[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
2609*e5436536SAndroid Build Coastguard Worker 1)]; /* Channel elements in bit stream order. */
2610*e5436536SAndroid Build Coastguard Worker int el_cnt[ID_LAST] = {0}; /* element counter ( robustness ) */
2611*e5436536SAndroid Build Coastguard Worker int element_count_prev_streams =
2612*e5436536SAndroid Build Coastguard Worker 0; /* Element count of all previous sub streams. */
2613*e5436536SAndroid Build Coastguard Worker
2614*e5436536SAndroid Build Coastguard Worker while ((type != ID_END) && (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) &&
2615*e5436536SAndroid Build Coastguard Worker self->frameOK) {
2616*e5436536SAndroid Build Coastguard Worker int el_channels;
2617*e5436536SAndroid Build Coastguard Worker
2618*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] &
2619*e5436536SAndroid Build Coastguard Worker (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD | AC_SCALABLE | AC_ER)))
2620*e5436536SAndroid Build Coastguard Worker type = (MP4_ELEMENT_ID)FDKreadBits(bs, 3);
2621*e5436536SAndroid Build Coastguard Worker else {
2622*e5436536SAndroid Build Coastguard Worker if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
2623*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2624*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2625*e5436536SAndroid Build Coastguard Worker break;
2626*e5436536SAndroid Build Coastguard Worker }
2627*e5436536SAndroid Build Coastguard Worker type = self->elements[element_count];
2628*e5436536SAndroid Build Coastguard Worker }
2629*e5436536SAndroid Build Coastguard Worker
2630*e5436536SAndroid Build Coastguard Worker if ((self->flags[streamIndex] & (AC_USAC | AC_RSVD50) &&
2631*e5436536SAndroid Build Coastguard Worker element_count == 0) ||
2632*e5436536SAndroid Build Coastguard Worker (self->flags[streamIndex] & AC_RSV603DA)) {
2633*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex] &= ~AC_INDEP;
2634*e5436536SAndroid Build Coastguard Worker
2635*e5436536SAndroid Build Coastguard Worker if (FDKreadBit(bs)) {
2636*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex] |= AC_INDEP;
2637*e5436536SAndroid Build Coastguard Worker }
2638*e5436536SAndroid Build Coastguard Worker
2639*e5436536SAndroid Build Coastguard Worker int ch = aacChannels;
2640*e5436536SAndroid Build Coastguard Worker for (int chIdx = aacChannels; chIdx < self->ascChannels[streamIndex];
2641*e5436536SAndroid Build Coastguard Worker chIdx++) {
2642*e5436536SAndroid Build Coastguard Worker {
2643*e5436536SAndroid Build Coastguard Worker /* Robustness check */
2644*e5436536SAndroid Build Coastguard Worker if (ch >= self->aacChannels) {
2645*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNKNOWN;
2646*e5436536SAndroid Build Coastguard Worker }
2647*e5436536SAndroid Build Coastguard Worker
2648*e5436536SAndroid Build Coastguard Worker /* if last frame was broken and this frame is no independent frame,
2649*e5436536SAndroid Build Coastguard Worker * correct decoding is impossible we need to trigger concealment */
2650*e5436536SAndroid Build Coastguard Worker if ((CConcealment_GetLastFrameOk(
2651*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
2652*e5436536SAndroid Build Coastguard Worker 1) == 0) &&
2653*e5436536SAndroid Build Coastguard Worker !(self->flags[streamIndex] & AC_INDEP)) {
2654*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2655*e5436536SAndroid Build Coastguard Worker }
2656*e5436536SAndroid Build Coastguard Worker ch++;
2657*e5436536SAndroid Build Coastguard Worker }
2658*e5436536SAndroid Build Coastguard Worker }
2659*e5436536SAndroid Build Coastguard Worker }
2660*e5436536SAndroid Build Coastguard Worker
2661*e5436536SAndroid Build Coastguard Worker if ((INT)FDKgetValidBits(bs) < 0) {
2662*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2663*e5436536SAndroid Build Coastguard Worker }
2664*e5436536SAndroid Build Coastguard Worker
2665*e5436536SAndroid Build Coastguard Worker switch (type) {
2666*e5436536SAndroid Build Coastguard Worker case ID_SCE:
2667*e5436536SAndroid Build Coastguard Worker case ID_CPE:
2668*e5436536SAndroid Build Coastguard Worker case ID_LFE:
2669*e5436536SAndroid Build Coastguard Worker case ID_USAC_SCE:
2670*e5436536SAndroid Build Coastguard Worker case ID_USAC_CPE:
2671*e5436536SAndroid Build Coastguard Worker case ID_USAC_LFE:
2672*e5436536SAndroid Build Coastguard Worker if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
2673*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2674*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2675*e5436536SAndroid Build Coastguard Worker break;
2676*e5436536SAndroid Build Coastguard Worker }
2677*e5436536SAndroid Build Coastguard Worker
2678*e5436536SAndroid Build Coastguard Worker el_channels = CAacDecoder_GetELChannels(
2679*e5436536SAndroid Build Coastguard Worker type, self->usacStereoConfigIndex[element_count]);
2680*e5436536SAndroid Build Coastguard Worker
2681*e5436536SAndroid Build Coastguard Worker /*
2682*e5436536SAndroid Build Coastguard Worker Consistency check
2683*e5436536SAndroid Build Coastguard Worker */
2684*e5436536SAndroid Build Coastguard Worker {
2685*e5436536SAndroid Build Coastguard Worker int totalAscChannels = 0;
2686*e5436536SAndroid Build Coastguard Worker
2687*e5436536SAndroid Build Coastguard Worker for (int i = 0; i < (1 * 1); i++) {
2688*e5436536SAndroid Build Coastguard Worker totalAscChannels += self->ascChannels[i];
2689*e5436536SAndroid Build Coastguard Worker }
2690*e5436536SAndroid Build Coastguard Worker if ((el_cnt[type] >= (totalAscChannels >> (el_channels - 1))) ||
2691*e5436536SAndroid Build Coastguard Worker (aacChannels > (totalAscChannels - el_channels))) {
2692*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
2693*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2694*e5436536SAndroid Build Coastguard Worker break;
2695*e5436536SAndroid Build Coastguard Worker }
2696*e5436536SAndroid Build Coastguard Worker }
2697*e5436536SAndroid Build Coastguard Worker
2698*e5436536SAndroid Build Coastguard Worker if (!(self->flags[streamIndex] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
2699*e5436536SAndroid Build Coastguard Worker int ch;
2700*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < el_channels; ch += 1) {
2701*e5436536SAndroid Build Coastguard Worker CPns_ResetData(&self->pAacDecoderChannelInfo[aacChannels + ch]
2702*e5436536SAndroid Build Coastguard Worker ->data.aac.PnsData,
2703*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderChannelInfo[aacChannels + ch]
2704*e5436536SAndroid Build Coastguard Worker ->pComData->pnsInterChannelData);
2705*e5436536SAndroid Build Coastguard Worker }
2706*e5436536SAndroid Build Coastguard Worker }
2707*e5436536SAndroid Build Coastguard Worker
2708*e5436536SAndroid Build Coastguard Worker if (self->frameOK) {
2709*e5436536SAndroid Build Coastguard Worker ErrorStatus = CChannelElement_Read(
2710*e5436536SAndroid Build Coastguard Worker bs, &self->pAacDecoderChannelInfo[aacChannels],
2711*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[aacChannels],
2712*e5436536SAndroid Build Coastguard Worker self->streamInfo.aot, &self->samplingRateInfo[streamIndex],
2713*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex], self->elFlags[element_count],
2714*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame, el_channels,
2715*e5436536SAndroid Build Coastguard Worker self->streamInfo.epConfig, self->hInput);
2716*e5436536SAndroid Build Coastguard Worker if (ErrorStatus != AAC_DEC_OK) {
2717*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2718*e5436536SAndroid Build Coastguard Worker }
2719*e5436536SAndroid Build Coastguard Worker }
2720*e5436536SAndroid Build Coastguard Worker
2721*e5436536SAndroid Build Coastguard Worker if (self->frameOK) {
2722*e5436536SAndroid Build Coastguard Worker /* Lookup the element and decode it only if it belongs to the current
2723*e5436536SAndroid Build Coastguard Worker * program */
2724*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_LookupElement(
2725*e5436536SAndroid Build Coastguard Worker pce, self->streamInfo.channelConfig,
2726*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[aacChannels]->ElementInstanceTag,
2727*e5436536SAndroid Build Coastguard Worker aacChannels, self->chMapping, self->channelType,
2728*e5436536SAndroid Build Coastguard Worker self->channelIndices, (8), &previous_element_index,
2729*e5436536SAndroid Build Coastguard Worker self->elements, type)) {
2730*e5436536SAndroid Build Coastguard Worker channel_elements[channel_element_count++] = type;
2731*e5436536SAndroid Build Coastguard Worker aacChannels += el_channels;
2732*e5436536SAndroid Build Coastguard Worker } else {
2733*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2734*e5436536SAndroid Build Coastguard Worker }
2735*e5436536SAndroid Build Coastguard Worker /* Create SBR element for SBR for upsampling for LFE elements,
2736*e5436536SAndroid Build Coastguard Worker and if SBR was implicitly signaled, because the first frame(s)
2737*e5436536SAndroid Build Coastguard Worker may not contain SBR payload (broken encoder, bit errors). */
2738*e5436536SAndroid Build Coastguard Worker if (self->frameOK &&
2739*e5436536SAndroid Build Coastguard Worker ((self->flags[streamIndex] & AC_SBR_PRESENT) ||
2740*e5436536SAndroid Build Coastguard Worker (self->sbrEnabled == 1)) &&
2741*e5436536SAndroid Build Coastguard Worker !(self->flags[streamIndex] &
2742*e5436536SAndroid Build Coastguard Worker AC_USAC) /* Is done during explicit config set up */
2743*e5436536SAndroid Build Coastguard Worker ) {
2744*e5436536SAndroid Build Coastguard Worker SBR_ERROR sbrError;
2745*e5436536SAndroid Build Coastguard Worker UCHAR configMode = 0;
2746*e5436536SAndroid Build Coastguard Worker UCHAR configChanged = 0;
2747*e5436536SAndroid Build Coastguard Worker configMode |= AC_CM_ALLOC_MEM;
2748*e5436536SAndroid Build Coastguard Worker
2749*e5436536SAndroid Build Coastguard Worker sbrError = sbrDecoder_InitElement(
2750*e5436536SAndroid Build Coastguard Worker self->hSbrDecoder, self->streamInfo.aacSampleRate,
2751*e5436536SAndroid Build Coastguard Worker self->streamInfo.extSamplingRate,
2752*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot, type,
2753*e5436536SAndroid Build Coastguard Worker previous_element_index, 2, /* Signalize that harmonicSBR shall
2754*e5436536SAndroid Build Coastguard Worker be ignored in the config change
2755*e5436536SAndroid Build Coastguard Worker detection */
2756*e5436536SAndroid Build Coastguard Worker 0, configMode, &configChanged, self->downscaleFactor);
2757*e5436536SAndroid Build Coastguard Worker if (sbrError != SBRDEC_OK) {
2758*e5436536SAndroid Build Coastguard Worker /* Do not try to apply SBR because initializing the element
2759*e5436536SAndroid Build Coastguard Worker * failed. */
2760*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = 0;
2761*e5436536SAndroid Build Coastguard Worker }
2762*e5436536SAndroid Build Coastguard Worker }
2763*e5436536SAndroid Build Coastguard Worker }
2764*e5436536SAndroid Build Coastguard Worker
2765*e5436536SAndroid Build Coastguard Worker el_cnt[type]++;
2766*e5436536SAndroid Build Coastguard Worker if (self->frameOK && (self->flags[streamIndex] & AC_USAC) &&
2767*e5436536SAndroid Build Coastguard Worker (type == ID_USAC_CPE || type == ID_USAC_SCE)) {
2768*e5436536SAndroid Build Coastguard Worker ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr(
2769*e5436536SAndroid Build Coastguard Worker self, bs, previous_element, previous_element_index, element_count,
2770*e5436536SAndroid Build Coastguard Worker el_cnt);
2771*e5436536SAndroid Build Coastguard Worker if (ErrorStatus != AAC_DEC_OK) {
2772*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2773*e5436536SAndroid Build Coastguard Worker }
2774*e5436536SAndroid Build Coastguard Worker }
2775*e5436536SAndroid Build Coastguard Worker break;
2776*e5436536SAndroid Build Coastguard Worker
2777*e5436536SAndroid Build Coastguard Worker case ID_CCE:
2778*e5436536SAndroid Build Coastguard Worker /*
2779*e5436536SAndroid Build Coastguard Worker Consistency check
2780*e5436536SAndroid Build Coastguard Worker */
2781*e5436536SAndroid Build Coastguard Worker if (el_cnt[type] > self->ascChannels[streamIndex]) {
2782*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
2783*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2784*e5436536SAndroid Build Coastguard Worker break;
2785*e5436536SAndroid Build Coastguard Worker }
2786*e5436536SAndroid Build Coastguard Worker
2787*e5436536SAndroid Build Coastguard Worker if (self->frameOK) {
2788*e5436536SAndroid Build Coastguard Worker CAacDecoderCommonData commonData;
2789*e5436536SAndroid Build Coastguard Worker CAacDecoderCommonStaticData commonStaticData;
2790*e5436536SAndroid Build Coastguard Worker CWorkBufferCore1 workBufferCore1;
2791*e5436536SAndroid Build Coastguard Worker commonStaticData.pWorkBufferCore1 = &workBufferCore1;
2792*e5436536SAndroid Build Coastguard Worker /* memory for spectral lines temporal on scratch */
2793*e5436536SAndroid Build Coastguard Worker C_AALLOC_SCRATCH_START(mdctSpec, FIXP_DBL, 1024);
2794*e5436536SAndroid Build Coastguard Worker
2795*e5436536SAndroid Build Coastguard Worker /* create dummy channel for CCE parsing on stack */
2796*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo tmpAacDecoderChannelInfo,
2797*e5436536SAndroid Build Coastguard Worker *pTmpAacDecoderChannelInfo;
2798*e5436536SAndroid Build Coastguard Worker
2799*e5436536SAndroid Build Coastguard Worker FDKmemclear(mdctSpec, 1024 * sizeof(FIXP_DBL));
2800*e5436536SAndroid Build Coastguard Worker
2801*e5436536SAndroid Build Coastguard Worker tmpAacDecoderChannelInfo.pDynData = commonData.pAacDecoderDynamicData;
2802*e5436536SAndroid Build Coastguard Worker tmpAacDecoderChannelInfo.pComData = &commonData;
2803*e5436536SAndroid Build Coastguard Worker tmpAacDecoderChannelInfo.pComStaticData = &commonStaticData;
2804*e5436536SAndroid Build Coastguard Worker tmpAacDecoderChannelInfo.pSpectralCoefficient =
2805*e5436536SAndroid Build Coastguard Worker (SPECTRAL_PTR)mdctSpec;
2806*e5436536SAndroid Build Coastguard Worker /* Assume AAC-LC */
2807*e5436536SAndroid Build Coastguard Worker tmpAacDecoderChannelInfo.granuleLength =
2808*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame / 8;
2809*e5436536SAndroid Build Coastguard Worker /* Reset PNS data. */
2810*e5436536SAndroid Build Coastguard Worker CPns_ResetData(
2811*e5436536SAndroid Build Coastguard Worker &tmpAacDecoderChannelInfo.data.aac.PnsData,
2812*e5436536SAndroid Build Coastguard Worker &tmpAacDecoderChannelInfo.pComData->pnsInterChannelData);
2813*e5436536SAndroid Build Coastguard Worker pTmpAacDecoderChannelInfo = &tmpAacDecoderChannelInfo;
2814*e5436536SAndroid Build Coastguard Worker /* do CCE parsing */
2815*e5436536SAndroid Build Coastguard Worker ErrorStatus = CChannelElement_Read(
2816*e5436536SAndroid Build Coastguard Worker bs, &pTmpAacDecoderChannelInfo, NULL, self->streamInfo.aot,
2817*e5436536SAndroid Build Coastguard Worker &self->samplingRateInfo[streamIndex], self->flags[streamIndex],
2818*e5436536SAndroid Build Coastguard Worker AC_EL_GA_CCE, self->streamInfo.aacSamplesPerFrame, 1,
2819*e5436536SAndroid Build Coastguard Worker self->streamInfo.epConfig, self->hInput);
2820*e5436536SAndroid Build Coastguard Worker
2821*e5436536SAndroid Build Coastguard Worker C_AALLOC_SCRATCH_END(mdctSpec, FIXP_DBL, 1024);
2822*e5436536SAndroid Build Coastguard Worker
2823*e5436536SAndroid Build Coastguard Worker if (ErrorStatus) {
2824*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2825*e5436536SAndroid Build Coastguard Worker }
2826*e5436536SAndroid Build Coastguard Worker
2827*e5436536SAndroid Build Coastguard Worker if (self->frameOK) {
2828*e5436536SAndroid Build Coastguard Worker /* Lookup the element and decode it only if it belongs to the
2829*e5436536SAndroid Build Coastguard Worker * current program */
2830*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_LookupElement(
2831*e5436536SAndroid Build Coastguard Worker pce, self->streamInfo.channelConfig,
2832*e5436536SAndroid Build Coastguard Worker pTmpAacDecoderChannelInfo->ElementInstanceTag, 0,
2833*e5436536SAndroid Build Coastguard Worker self->chMapping, self->channelType, self->channelIndices,
2834*e5436536SAndroid Build Coastguard Worker (8), &previous_element_index, self->elements, type)) {
2835*e5436536SAndroid Build Coastguard Worker /* decoding of CCE not supported */
2836*e5436536SAndroid Build Coastguard Worker } else {
2837*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2838*e5436536SAndroid Build Coastguard Worker }
2839*e5436536SAndroid Build Coastguard Worker }
2840*e5436536SAndroid Build Coastguard Worker }
2841*e5436536SAndroid Build Coastguard Worker el_cnt[type]++;
2842*e5436536SAndroid Build Coastguard Worker break;
2843*e5436536SAndroid Build Coastguard Worker
2844*e5436536SAndroid Build Coastguard Worker case ID_DSE: {
2845*e5436536SAndroid Build Coastguard Worker UCHAR element_instance_tag;
2846*e5436536SAndroid Build Coastguard Worker
2847*e5436536SAndroid Build Coastguard Worker CDataStreamElement_Read(self, bs, &element_instance_tag, auStartAnchor);
2848*e5436536SAndroid Build Coastguard Worker
2849*e5436536SAndroid Build Coastguard Worker if (!CProgramConfig_LookupElement(
2850*e5436536SAndroid Build Coastguard Worker pce, self->streamInfo.channelConfig, element_instance_tag, 0,
2851*e5436536SAndroid Build Coastguard Worker self->chMapping, self->channelType, self->channelIndices, (8),
2852*e5436536SAndroid Build Coastguard Worker &previous_element_index, self->elements, type)) {
2853*e5436536SAndroid Build Coastguard Worker /* most likely an error in bitstream occured */
2854*e5436536SAndroid Build Coastguard Worker // self->frameOK = 0;
2855*e5436536SAndroid Build Coastguard Worker }
2856*e5436536SAndroid Build Coastguard Worker } break;
2857*e5436536SAndroid Build Coastguard Worker
2858*e5436536SAndroid Build Coastguard Worker case ID_PCE: {
2859*e5436536SAndroid Build Coastguard Worker int result = CProgramConfigElement_Read(bs, self->hInput, pce,
2860*e5436536SAndroid Build Coastguard Worker self->streamInfo.channelConfig,
2861*e5436536SAndroid Build Coastguard Worker auStartAnchor);
2862*e5436536SAndroid Build Coastguard Worker if (result < 0) {
2863*e5436536SAndroid Build Coastguard Worker /* Something went wrong */
2864*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2865*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2866*e5436536SAndroid Build Coastguard Worker } else if (result > 1) {
2867*e5436536SAndroid Build Coastguard Worker /* Built element table */
2868*e5436536SAndroid Build Coastguard Worker int elIdx = CProgramConfig_GetElementTable(
2869*e5436536SAndroid Build Coastguard Worker pce, self->elements, (((8)) + (8)), &self->chMapIndex);
2870*e5436536SAndroid Build Coastguard Worker /* Reset the remaining tabs */
2871*e5436536SAndroid Build Coastguard Worker for (; elIdx < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
2872*e5436536SAndroid Build Coastguard Worker elIdx++) {
2873*e5436536SAndroid Build Coastguard Worker self->elements[elIdx] = ID_NONE;
2874*e5436536SAndroid Build Coastguard Worker }
2875*e5436536SAndroid Build Coastguard Worker /* Make new number of channel persistent */
2876*e5436536SAndroid Build Coastguard Worker self->ascChannels[streamIndex] = pce->NumChannels;
2877*e5436536SAndroid Build Coastguard Worker /* If PCE is not first element conceal this frame to avoid
2878*e5436536SAndroid Build Coastguard Worker * inconsistencies */
2879*e5436536SAndroid Build Coastguard Worker if (element_count != 0) {
2880*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2881*e5436536SAndroid Build Coastguard Worker }
2882*e5436536SAndroid Build Coastguard Worker }
2883*e5436536SAndroid Build Coastguard Worker pceRead = (result >= 0) ? 1 : 0;
2884*e5436536SAndroid Build Coastguard Worker } break;
2885*e5436536SAndroid Build Coastguard Worker
2886*e5436536SAndroid Build Coastguard Worker case ID_FIL: {
2887*e5436536SAndroid Build Coastguard Worker int bitCnt = FDKreadBits(bs, 4); /* bs_count */
2888*e5436536SAndroid Build Coastguard Worker
2889*e5436536SAndroid Build Coastguard Worker if (bitCnt == 15) {
2890*e5436536SAndroid Build Coastguard Worker int esc_count = FDKreadBits(bs, 8); /* bs_esc_count */
2891*e5436536SAndroid Build Coastguard Worker bitCnt = esc_count + 14;
2892*e5436536SAndroid Build Coastguard Worker }
2893*e5436536SAndroid Build Coastguard Worker
2894*e5436536SAndroid Build Coastguard Worker /* Convert to bits */
2895*e5436536SAndroid Build Coastguard Worker bitCnt <<= 3;
2896*e5436536SAndroid Build Coastguard Worker
2897*e5436536SAndroid Build Coastguard Worker while (bitCnt > 0) {
2898*e5436536SAndroid Build Coastguard Worker ErrorStatus = CAacDecoder_ExtPayloadParse(
2899*e5436536SAndroid Build Coastguard Worker self, bs, &bitCnt, previous_element, previous_element_index, 1);
2900*e5436536SAndroid Build Coastguard Worker if (ErrorStatus != AAC_DEC_OK) {
2901*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2902*e5436536SAndroid Build Coastguard Worker break;
2903*e5436536SAndroid Build Coastguard Worker }
2904*e5436536SAndroid Build Coastguard Worker }
2905*e5436536SAndroid Build Coastguard Worker } break;
2906*e5436536SAndroid Build Coastguard Worker
2907*e5436536SAndroid Build Coastguard Worker case ID_EXT:
2908*e5436536SAndroid Build Coastguard Worker if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
2909*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2910*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2911*e5436536SAndroid Build Coastguard Worker break;
2912*e5436536SAndroid Build Coastguard Worker }
2913*e5436536SAndroid Build Coastguard Worker
2914*e5436536SAndroid Build Coastguard Worker ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr(
2915*e5436536SAndroid Build Coastguard Worker self, bs, previous_element, previous_element_index, element_count,
2916*e5436536SAndroid Build Coastguard Worker el_cnt);
2917*e5436536SAndroid Build Coastguard Worker break;
2918*e5436536SAndroid Build Coastguard Worker
2919*e5436536SAndroid Build Coastguard Worker case ID_USAC_EXT: {
2920*e5436536SAndroid Build Coastguard Worker if ((element_count - element_count_prev_streams) >=
2921*e5436536SAndroid Build Coastguard Worker TP_USAC_MAX_ELEMENTS) {
2922*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2923*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2924*e5436536SAndroid Build Coastguard Worker break;
2925*e5436536SAndroid Build Coastguard Worker }
2926*e5436536SAndroid Build Coastguard Worker /* parse extension element payload
2927*e5436536SAndroid Build Coastguard Worker q.v. rsv603daExtElement() ISO/IEC DIS 23008-3 Table 30
2928*e5436536SAndroid Build Coastguard Worker or UsacExElement() ISO/IEC FDIS 23003-3:2011(E) Table 21
2929*e5436536SAndroid Build Coastguard Worker */
2930*e5436536SAndroid Build Coastguard Worker int usacExtElementPayloadLength;
2931*e5436536SAndroid Build Coastguard Worker /* int usacExtElementStart, usacExtElementStop; */
2932*e5436536SAndroid Build Coastguard Worker
2933*e5436536SAndroid Build Coastguard Worker if (FDKreadBit(bs)) { /* usacExtElementPresent */
2934*e5436536SAndroid Build Coastguard Worker if (FDKreadBit(bs)) { /* usacExtElementUseDefaultLength */
2935*e5436536SAndroid Build Coastguard Worker usacExtElementPayloadLength =
2936*e5436536SAndroid Build Coastguard Worker self->pUsacConfig[streamIndex]
2937*e5436536SAndroid Build Coastguard Worker ->element[element_count - element_count_prev_streams]
2938*e5436536SAndroid Build Coastguard Worker .extElement.usacExtElementDefaultLength;
2939*e5436536SAndroid Build Coastguard Worker } else {
2940*e5436536SAndroid Build Coastguard Worker usacExtElementPayloadLength = FDKreadBits(bs, 8);
2941*e5436536SAndroid Build Coastguard Worker if (usacExtElementPayloadLength == (UINT)(1 << 8) - 1) {
2942*e5436536SAndroid Build Coastguard Worker UINT valueAdd = FDKreadBits(bs, 16);
2943*e5436536SAndroid Build Coastguard Worker usacExtElementPayloadLength += (INT)valueAdd - 2;
2944*e5436536SAndroid Build Coastguard Worker }
2945*e5436536SAndroid Build Coastguard Worker }
2946*e5436536SAndroid Build Coastguard Worker if (usacExtElementPayloadLength > 0) {
2947*e5436536SAndroid Build Coastguard Worker int usacExtBitPos;
2948*e5436536SAndroid Build Coastguard Worker
2949*e5436536SAndroid Build Coastguard Worker if (self->pUsacConfig[streamIndex]
2950*e5436536SAndroid Build Coastguard Worker ->element[element_count - element_count_prev_streams]
2951*e5436536SAndroid Build Coastguard Worker .extElement.usacExtElementPayloadFrag) {
2952*e5436536SAndroid Build Coastguard Worker /* usacExtElementStart = */ FDKreadBit(bs);
2953*e5436536SAndroid Build Coastguard Worker /* usacExtElementStop = */ FDKreadBit(bs);
2954*e5436536SAndroid Build Coastguard Worker } else {
2955*e5436536SAndroid Build Coastguard Worker /* usacExtElementStart = 1; */
2956*e5436536SAndroid Build Coastguard Worker /* usacExtElementStop = 1; */
2957*e5436536SAndroid Build Coastguard Worker }
2958*e5436536SAndroid Build Coastguard Worker
2959*e5436536SAndroid Build Coastguard Worker usacExtBitPos = (INT)FDKgetValidBits(bs);
2960*e5436536SAndroid Build Coastguard Worker
2961*e5436536SAndroid Build Coastguard Worker USAC_EXT_ELEMENT_TYPE usacExtElementType =
2962*e5436536SAndroid Build Coastguard Worker self->pUsacConfig[streamIndex]
2963*e5436536SAndroid Build Coastguard Worker ->element[element_count - element_count_prev_streams]
2964*e5436536SAndroid Build Coastguard Worker .extElement.usacExtElementType;
2965*e5436536SAndroid Build Coastguard Worker
2966*e5436536SAndroid Build Coastguard Worker switch (usacExtElementType) {
2967*e5436536SAndroid Build Coastguard Worker case ID_EXT_ELE_UNI_DRC: /* uniDrcGain() */
2968*e5436536SAndroid Build Coastguard Worker if (streamIndex == 0) {
2969*e5436536SAndroid Build Coastguard Worker int drcErr;
2970*e5436536SAndroid Build Coastguard Worker
2971*e5436536SAndroid Build Coastguard Worker drcErr = FDK_drcDec_ReadUniDrcGain(self->hUniDrcDecoder, bs);
2972*e5436536SAndroid Build Coastguard Worker if (drcErr != 0) {
2973*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2974*e5436536SAndroid Build Coastguard Worker }
2975*e5436536SAndroid Build Coastguard Worker }
2976*e5436536SAndroid Build Coastguard Worker break;
2977*e5436536SAndroid Build Coastguard Worker
2978*e5436536SAndroid Build Coastguard Worker default:
2979*e5436536SAndroid Build Coastguard Worker break;
2980*e5436536SAndroid Build Coastguard Worker }
2981*e5436536SAndroid Build Coastguard Worker
2982*e5436536SAndroid Build Coastguard Worker /* Skip any remaining bits of extension payload */
2983*e5436536SAndroid Build Coastguard Worker usacExtBitPos = (usacExtElementPayloadLength * 8) -
2984*e5436536SAndroid Build Coastguard Worker (usacExtBitPos - (INT)FDKgetValidBits(bs));
2985*e5436536SAndroid Build Coastguard Worker if (usacExtBitPos < 0) {
2986*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
2987*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
2988*e5436536SAndroid Build Coastguard Worker }
2989*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(bs, usacExtBitPos);
2990*e5436536SAndroid Build Coastguard Worker }
2991*e5436536SAndroid Build Coastguard Worker }
2992*e5436536SAndroid Build Coastguard Worker } break;
2993*e5436536SAndroid Build Coastguard Worker case ID_END:
2994*e5436536SAndroid Build Coastguard Worker case ID_USAC_END:
2995*e5436536SAndroid Build Coastguard Worker break;
2996*e5436536SAndroid Build Coastguard Worker
2997*e5436536SAndroid Build Coastguard Worker default:
2998*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
2999*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3000*e5436536SAndroid Build Coastguard Worker break;
3001*e5436536SAndroid Build Coastguard Worker }
3002*e5436536SAndroid Build Coastguard Worker
3003*e5436536SAndroid Build Coastguard Worker previous_element = type;
3004*e5436536SAndroid Build Coastguard Worker element_count++;
3005*e5436536SAndroid Build Coastguard Worker
3006*e5436536SAndroid Build Coastguard Worker } /* while ( (type != ID_END) ... ) */
3007*e5436536SAndroid Build Coastguard Worker
3008*e5436536SAndroid Build Coastguard Worker if (!(self->flags[streamIndex] &
3009*e5436536SAndroid Build Coastguard Worker (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_BSAC | AC_LD | AC_ELD | AC_ER |
3010*e5436536SAndroid Build Coastguard Worker AC_SCALABLE)) &&
3011*e5436536SAndroid Build Coastguard Worker (self->streamInfo.channelConfig == 0) && pce->isValid &&
3012*e5436536SAndroid Build Coastguard Worker (ErrorStatus == AAC_DEC_OK) && self->frameOK &&
3013*e5436536SAndroid Build Coastguard Worker !(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
3014*e5436536SAndroid Build Coastguard Worker /* Check whether all PCE listed element instance tags are present in
3015*e5436536SAndroid Build Coastguard Worker * raw_data_block() */
3016*e5436536SAndroid Build Coastguard Worker if (!validateElementInstanceTags(
3017*e5436536SAndroid Build Coastguard Worker &self->pce, self->pAacDecoderChannelInfo, aacChannels,
3018*e5436536SAndroid Build Coastguard Worker channel_elements,
3019*e5436536SAndroid Build Coastguard Worker fMin(channel_element_count, (int)(sizeof(channel_elements) /
3020*e5436536SAndroid Build Coastguard Worker sizeof(*channel_elements))))) {
3021*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
3022*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3023*e5436536SAndroid Build Coastguard Worker }
3024*e5436536SAndroid Build Coastguard Worker }
3025*e5436536SAndroid Build Coastguard Worker
3026*e5436536SAndroid Build Coastguard Worker if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
3027*e5436536SAndroid Build Coastguard Worker /* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are
3028*e5436536SAndroid Build Coastguard Worker * byteAligned with respect to the first bit */
3029*e5436536SAndroid Build Coastguard Worker /* Byte alignment with respect to the first bit of the raw_data_block(). */
3030*e5436536SAndroid Build Coastguard Worker if (!(self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) ||
3031*e5436536SAndroid Build Coastguard Worker (self->prerollAULength[self->accessUnit]) /* indicates preroll */
3032*e5436536SAndroid Build Coastguard Worker ) {
3033*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(bs, auStartAnchor);
3034*e5436536SAndroid Build Coastguard Worker }
3035*e5436536SAndroid Build Coastguard Worker
3036*e5436536SAndroid Build Coastguard Worker /* Check if all bits of the raw_data_block() have been read. */
3037*e5436536SAndroid Build Coastguard Worker if (transportDec_GetAuBitsTotal(self->hInput, 0) > 0) {
3038*e5436536SAndroid Build Coastguard Worker INT unreadBits = transportDec_GetAuBitsRemaining(self->hInput, 0);
3039*e5436536SAndroid Build Coastguard Worker /* for pre-roll frames pre-roll length has to be used instead of total AU
3040*e5436536SAndroid Build Coastguard Worker * lenght */
3041*e5436536SAndroid Build Coastguard Worker /* unreadBits regarding preroll bounds */
3042*e5436536SAndroid Build Coastguard Worker if (self->prerollAULength[self->accessUnit]) {
3043*e5436536SAndroid Build Coastguard Worker unreadBits = unreadBits - transportDec_GetAuBitsTotal(self->hInput, 0) +
3044*e5436536SAndroid Build Coastguard Worker (INT)self->prerollAULength[self->accessUnit];
3045*e5436536SAndroid Build Coastguard Worker }
3046*e5436536SAndroid Build Coastguard Worker if (((self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) &&
3047*e5436536SAndroid Build Coastguard Worker ((unreadBits < 0) || (unreadBits > 7)) &&
3048*e5436536SAndroid Build Coastguard Worker !(self->prerollAULength[self->accessUnit])) ||
3049*e5436536SAndroid Build Coastguard Worker ((!(self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) ||
3050*e5436536SAndroid Build Coastguard Worker (self->prerollAULength[self->accessUnit])) &&
3051*e5436536SAndroid Build Coastguard Worker (unreadBits != 0))) {
3052*e5436536SAndroid Build Coastguard Worker if ((((unreadBits < 0) || (unreadBits > 7)) && self->frameOK) &&
3053*e5436536SAndroid Build Coastguard Worker ((transportDec_GetFormat(self->hInput) == TT_DRM) &&
3054*e5436536SAndroid Build Coastguard Worker (self->flags[streamIndex] & AC_USAC))) {
3055*e5436536SAndroid Build Coastguard Worker /* Set frame OK because of fill bits. */
3056*e5436536SAndroid Build Coastguard Worker self->frameOK = 1;
3057*e5436536SAndroid Build Coastguard Worker } else {
3058*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3059*e5436536SAndroid Build Coastguard Worker }
3060*e5436536SAndroid Build Coastguard Worker
3061*e5436536SAndroid Build Coastguard Worker /* Do not overwrite current error */
3062*e5436536SAndroid Build Coastguard Worker if (ErrorStatus == AAC_DEC_OK && self->frameOK == 0) {
3063*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
3064*e5436536SAndroid Build Coastguard Worker }
3065*e5436536SAndroid Build Coastguard Worker /* Always put the bitbuffer at the right position after the current
3066*e5436536SAndroid Build Coastguard Worker * Access Unit. */
3067*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(bs, unreadBits);
3068*e5436536SAndroid Build Coastguard Worker }
3069*e5436536SAndroid Build Coastguard Worker }
3070*e5436536SAndroid Build Coastguard Worker
3071*e5436536SAndroid Build Coastguard Worker /* Check the last element. The terminator (ID_END) has to be the last one
3072*e5436536SAndroid Build Coastguard Worker * (even if ER syntax is used). */
3073*e5436536SAndroid Build Coastguard Worker if (self->frameOK && type != ID_END) {
3074*e5436536SAndroid Build Coastguard Worker /* Do not overwrite current error */
3075*e5436536SAndroid Build Coastguard Worker if (ErrorStatus == AAC_DEC_OK) {
3076*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_PARSE_ERROR;
3077*e5436536SAndroid Build Coastguard Worker }
3078*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3079*e5436536SAndroid Build Coastguard Worker }
3080*e5436536SAndroid Build Coastguard Worker }
3081*e5436536SAndroid Build Coastguard Worker
3082*e5436536SAndroid Build Coastguard Worker if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && self->frameOK) {
3083*e5436536SAndroid Build Coastguard Worker channel_elements[channel_element_count++] = ID_END;
3084*e5436536SAndroid Build Coastguard Worker }
3085*e5436536SAndroid Build Coastguard Worker element_count = 0;
3086*e5436536SAndroid Build Coastguard Worker aacChannels = 0;
3087*e5436536SAndroid Build Coastguard Worker type = ID_NONE;
3088*e5436536SAndroid Build Coastguard Worker previous_element_index = 0;
3089*e5436536SAndroid Build Coastguard Worker
3090*e5436536SAndroid Build Coastguard Worker while (type != ID_END &&
3091*e5436536SAndroid Build Coastguard Worker element_count < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
3092*e5436536SAndroid Build Coastguard Worker int el_channels;
3093*e5436536SAndroid Build Coastguard Worker
3094*e5436536SAndroid Build Coastguard Worker if ((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || !self->frameOK) {
3095*e5436536SAndroid Build Coastguard Worker channel_elements[element_count] = self->elements[element_count];
3096*e5436536SAndroid Build Coastguard Worker if (channel_elements[element_count] == ID_NONE) {
3097*e5436536SAndroid Build Coastguard Worker channel_elements[element_count] = ID_END;
3098*e5436536SAndroid Build Coastguard Worker }
3099*e5436536SAndroid Build Coastguard Worker }
3100*e5436536SAndroid Build Coastguard Worker
3101*e5436536SAndroid Build Coastguard Worker if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA | AC_BSAC)) {
3102*e5436536SAndroid Build Coastguard Worker type = self->elements[element_count];
3103*e5436536SAndroid Build Coastguard Worker } else {
3104*e5436536SAndroid Build Coastguard Worker type = channel_elements[element_count];
3105*e5436536SAndroid Build Coastguard Worker }
3106*e5436536SAndroid Build Coastguard Worker
3107*e5436536SAndroid Build Coastguard Worker if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && self->frameOK) {
3108*e5436536SAndroid Build Coastguard Worker switch (type) {
3109*e5436536SAndroid Build Coastguard Worker case ID_SCE:
3110*e5436536SAndroid Build Coastguard Worker case ID_CPE:
3111*e5436536SAndroid Build Coastguard Worker case ID_LFE:
3112*e5436536SAndroid Build Coastguard Worker case ID_USAC_SCE:
3113*e5436536SAndroid Build Coastguard Worker case ID_USAC_CPE:
3114*e5436536SAndroid Build Coastguard Worker case ID_USAC_LFE:
3115*e5436536SAndroid Build Coastguard Worker
3116*e5436536SAndroid Build Coastguard Worker el_channels = CAacDecoder_GetELChannels(
3117*e5436536SAndroid Build Coastguard Worker type, self->usacStereoConfigIndex[element_count]);
3118*e5436536SAndroid Build Coastguard Worker
3119*e5436536SAndroid Build Coastguard Worker if (!hdaacDecoded) {
3120*e5436536SAndroid Build Coastguard Worker if (self->pAacDecoderStaticChannelInfo[aacChannels]
3121*e5436536SAndroid Build Coastguard Worker ->pCpeStaticData != NULL) {
3122*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[aacChannels]
3123*e5436536SAndroid Build Coastguard Worker ->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
3124*e5436536SAndroid Build Coastguard Worker (FIXP_DBL *)pTimeData;
3125*e5436536SAndroid Build Coastguard Worker }
3126*e5436536SAndroid Build Coastguard Worker CChannelElement_Decode(
3127*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderChannelInfo[aacChannels],
3128*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[aacChannels],
3129*e5436536SAndroid Build Coastguard Worker &self->samplingRateInfo[streamIndex], self->flags[streamIndex],
3130*e5436536SAndroid Build Coastguard Worker self->elFlags[element_count], el_channels);
3131*e5436536SAndroid Build Coastguard Worker }
3132*e5436536SAndroid Build Coastguard Worker aacChannels += el_channels;
3133*e5436536SAndroid Build Coastguard Worker break;
3134*e5436536SAndroid Build Coastguard Worker case ID_NONE:
3135*e5436536SAndroid Build Coastguard Worker type = ID_END;
3136*e5436536SAndroid Build Coastguard Worker break;
3137*e5436536SAndroid Build Coastguard Worker default:
3138*e5436536SAndroid Build Coastguard Worker break;
3139*e5436536SAndroid Build Coastguard Worker }
3140*e5436536SAndroid Build Coastguard Worker }
3141*e5436536SAndroid Build Coastguard Worker element_count++;
3142*e5436536SAndroid Build Coastguard Worker }
3143*e5436536SAndroid Build Coastguard Worker
3144*e5436536SAndroid Build Coastguard Worker /* More AAC channels than specified by the ASC not allowed. */
3145*e5436536SAndroid Build Coastguard Worker if ((aacChannels == 0 || aacChannels > self->aacChannels) &&
3146*e5436536SAndroid Build Coastguard Worker !(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
3147*e5436536SAndroid Build Coastguard Worker /* Do not overwrite current error */
3148*e5436536SAndroid Build Coastguard Worker if (ErrorStatus == AAC_DEC_OK) {
3149*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
3150*e5436536SAndroid Build Coastguard Worker }
3151*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3152*e5436536SAndroid Build Coastguard Worker aacChannels = 0;
3153*e5436536SAndroid Build Coastguard Worker }
3154*e5436536SAndroid Build Coastguard Worker
3155*e5436536SAndroid Build Coastguard Worker if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
3156*e5436536SAndroid Build Coastguard Worker if (TRANSPORTDEC_OK != transportDec_CrcCheck(self->hInput)) {
3157*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_CRC_ERROR;
3158*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3159*e5436536SAndroid Build Coastguard Worker }
3160*e5436536SAndroid Build Coastguard Worker }
3161*e5436536SAndroid Build Coastguard Worker
3162*e5436536SAndroid Build Coastguard Worker /* Ensure that in case of concealment a proper error status is set. */
3163*e5436536SAndroid Build Coastguard Worker if ((self->frameOK == 0) && (ErrorStatus == AAC_DEC_OK)) {
3164*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
3165*e5436536SAndroid Build Coastguard Worker }
3166*e5436536SAndroid Build Coastguard Worker
3167*e5436536SAndroid Build Coastguard Worker if (self->frameOK && (flags & AACDEC_FLUSH)) {
3168*e5436536SAndroid Build Coastguard Worker aacChannels = self->aacChannelsPrev;
3169*e5436536SAndroid Build Coastguard Worker /* Because the downmix could be active, its necessary to restore the channel
3170*e5436536SAndroid Build Coastguard Worker * type and indices. */
3171*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->channelType, self->channelTypePrev,
3172*e5436536SAndroid Build Coastguard Worker (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
3173*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->channelIndices, self->channelIndicesPrev,
3174*e5436536SAndroid Build Coastguard Worker (8) * sizeof(UCHAR)); /* restore */
3175*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = self->sbrEnabledPrev;
3176*e5436536SAndroid Build Coastguard Worker } else {
3177*e5436536SAndroid Build Coastguard Worker /* store or restore the number of channels and the corresponding info */
3178*e5436536SAndroid Build Coastguard Worker if (self->frameOK && !(flags & AACDEC_CONCEAL)) {
3179*e5436536SAndroid Build Coastguard Worker self->aacChannelsPrev = aacChannels; /* store */
3180*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->channelTypePrev, self->channelType,
3181*e5436536SAndroid Build Coastguard Worker (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* store */
3182*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->channelIndicesPrev, self->channelIndices,
3183*e5436536SAndroid Build Coastguard Worker (8) * sizeof(UCHAR)); /* store */
3184*e5436536SAndroid Build Coastguard Worker self->sbrEnabledPrev = self->sbrEnabled;
3185*e5436536SAndroid Build Coastguard Worker } else {
3186*e5436536SAndroid Build Coastguard Worker if (self->aacChannels > 0) {
3187*e5436536SAndroid Build Coastguard Worker if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
3188*e5436536SAndroid Build Coastguard Worker (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
3189*e5436536SAndroid Build Coastguard Worker (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
3190*e5436536SAndroid Build Coastguard Worker aacChannels = self->aacChannels;
3191*e5436536SAndroid Build Coastguard Worker self->aacChannelsPrev = aacChannels; /* store */
3192*e5436536SAndroid Build Coastguard Worker } else {
3193*e5436536SAndroid Build Coastguard Worker aacChannels = self->aacChannelsPrev; /* restore */
3194*e5436536SAndroid Build Coastguard Worker }
3195*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->channelType, self->channelTypePrev,
3196*e5436536SAndroid Build Coastguard Worker (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
3197*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->channelIndices, self->channelIndicesPrev,
3198*e5436536SAndroid Build Coastguard Worker (8) * sizeof(UCHAR)); /* restore */
3199*e5436536SAndroid Build Coastguard Worker self->sbrEnabled = self->sbrEnabledPrev;
3200*e5436536SAndroid Build Coastguard Worker }
3201*e5436536SAndroid Build Coastguard Worker }
3202*e5436536SAndroid Build Coastguard Worker }
3203*e5436536SAndroid Build Coastguard Worker
3204*e5436536SAndroid Build Coastguard Worker /* Update number of output channels */
3205*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacNumChannels = aacChannels;
3206*e5436536SAndroid Build Coastguard Worker
3207*e5436536SAndroid Build Coastguard Worker /* Ensure consistency of IS_OUTPUT_VALID() macro. */
3208*e5436536SAndroid Build Coastguard Worker if (aacChannels == 0) {
3209*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_UNKNOWN;
3210*e5436536SAndroid Build Coastguard Worker }
3211*e5436536SAndroid Build Coastguard Worker
3212*e5436536SAndroid Build Coastguard Worker if (pceRead == 1 && CProgramConfig_IsValid(pce)) {
3213*e5436536SAndroid Build Coastguard Worker /* Set matrix mixdown infos if available from PCE. */
3214*e5436536SAndroid Build Coastguard Worker pcmDmx_SetMatrixMixdownFromPce(
3215*e5436536SAndroid Build Coastguard Worker self->hPcmUtils, pce->MatrixMixdownIndexPresent,
3216*e5436536SAndroid Build Coastguard Worker pce->MatrixMixdownIndex, pce->PseudoSurroundEnable);
3217*e5436536SAndroid Build Coastguard Worker ;
3218*e5436536SAndroid Build Coastguard Worker }
3219*e5436536SAndroid Build Coastguard Worker
3220*e5436536SAndroid Build Coastguard Worker /* If there is no valid data to transfrom into time domain, return. */
3221*e5436536SAndroid Build Coastguard Worker if (!IS_OUTPUT_VALID(ErrorStatus)) {
3222*e5436536SAndroid Build Coastguard Worker return ErrorStatus;
3223*e5436536SAndroid Build Coastguard Worker }
3224*e5436536SAndroid Build Coastguard Worker
3225*e5436536SAndroid Build Coastguard Worker /* Setup the output channel mapping. The table below shows the three
3226*e5436536SAndroid Build Coastguard Worker * possibilities: # | chCfg | PCE | chMapIndex
3227*e5436536SAndroid Build Coastguard Worker * ---+-------+-----+------------------
3228*e5436536SAndroid Build Coastguard Worker * 1 | > 0 | no | chCfg
3229*e5436536SAndroid Build Coastguard Worker * 2 | 0 | yes | cChCfg
3230*e5436536SAndroid Build Coastguard Worker * 3 | 0 | no | aacChannels || 0
3231*e5436536SAndroid Build Coastguard Worker * ---+-------+-----+--------+------------------
3232*e5436536SAndroid Build Coastguard Worker * Where chCfg is the channel configuration index from ASC and cChCfg is a
3233*e5436536SAndroid Build Coastguard Worker * corresponding chCfg derived from a given PCE. The variable aacChannels
3234*e5436536SAndroid Build Coastguard Worker * represents the number of channel found during bitstream decoding. Due to
3235*e5436536SAndroid Build Coastguard Worker * the structure of the mapping table it can only be used for mapping if its
3236*e5436536SAndroid Build Coastguard Worker * value is smaller than 7. Otherwise we use the fallback (0) which is a
3237*e5436536SAndroid Build Coastguard Worker * simple pass-through. The possibility #3 should appear only with MPEG-2
3238*e5436536SAndroid Build Coastguard Worker * (ADTS) streams. This is mode is called "implicit channel mapping".
3239*e5436536SAndroid Build Coastguard Worker */
3240*e5436536SAndroid Build Coastguard Worker if ((self->streamInfo.channelConfig == 0) && !pce->isValid) {
3241*e5436536SAndroid Build Coastguard Worker self->chMapIndex = (aacChannels < 7) ? aacChannels : 0;
3242*e5436536SAndroid Build Coastguard Worker }
3243*e5436536SAndroid Build Coastguard Worker
3244*e5436536SAndroid Build Coastguard Worker /*
3245*e5436536SAndroid Build Coastguard Worker Inverse transform
3246*e5436536SAndroid Build Coastguard Worker */
3247*e5436536SAndroid Build Coastguard Worker {
3248*e5436536SAndroid Build Coastguard Worker int c, cIdx;
3249*e5436536SAndroid Build Coastguard Worker int mapped, fCopyChMap = 1;
3250*e5436536SAndroid Build Coastguard Worker UCHAR drcChMap[(8)];
3251*e5436536SAndroid Build Coastguard Worker
3252*e5436536SAndroid Build Coastguard Worker if ((self->streamInfo.channelConfig == 0) && CProgramConfig_IsValid(pce)) {
3253*e5436536SAndroid Build Coastguard Worker /* ISO/IEC 14496-3 says:
3254*e5436536SAndroid Build Coastguard Worker If a PCE is present, the exclude_mask bits correspond to the audio
3255*e5436536SAndroid Build Coastguard Worker channels in the SCE, CPE, CCE and LFE syntax elements in the order of
3256*e5436536SAndroid Build Coastguard Worker their appearance in the PCE. In the case of a CPE, the first
3257*e5436536SAndroid Build Coastguard Worker transmitted mask bit corresponds to the first channel in the CPE, the
3258*e5436536SAndroid Build Coastguard Worker second transmitted mask bit to the second channel. In the case of a
3259*e5436536SAndroid Build Coastguard Worker CCE, a mask bit is transmitted only if the coupling channel is
3260*e5436536SAndroid Build Coastguard Worker specified to be an independently switched coupling channel. Thus we
3261*e5436536SAndroid Build Coastguard Worker have to convert the internal channel mapping from "canonical" MPEG to
3262*e5436536SAndroid Build Coastguard Worker PCE order: */
3263*e5436536SAndroid Build Coastguard Worker UCHAR tmpChMap[(8)];
3264*e5436536SAndroid Build Coastguard Worker if (CProgramConfig_GetPceChMap(pce, tmpChMap, (8)) == 0) {
3265*e5436536SAndroid Build Coastguard Worker for (c = 0; c < aacChannels; c += 1) {
3266*e5436536SAndroid Build Coastguard Worker drcChMap[c] =
3267*e5436536SAndroid Build Coastguard Worker (self->chMapping[c] == 255) ? 255 : tmpChMap[self->chMapping[c]];
3268*e5436536SAndroid Build Coastguard Worker }
3269*e5436536SAndroid Build Coastguard Worker fCopyChMap = 0;
3270*e5436536SAndroid Build Coastguard Worker }
3271*e5436536SAndroid Build Coastguard Worker }
3272*e5436536SAndroid Build Coastguard Worker if (fCopyChMap != 0) {
3273*e5436536SAndroid Build Coastguard Worker FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR));
3274*e5436536SAndroid Build Coastguard Worker }
3275*e5436536SAndroid Build Coastguard Worker
3276*e5436536SAndroid Build Coastguard Worker /* Extract DRC control data and map it to channels (without bitstream delay)
3277*e5436536SAndroid Build Coastguard Worker */
3278*e5436536SAndroid Build Coastguard Worker mapped = aacDecoder_drcProlog(
3279*e5436536SAndroid Build Coastguard Worker self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
3280*e5436536SAndroid Build Coastguard Worker pce->ElementInstanceTag, drcChMap, aacChannels);
3281*e5436536SAndroid Build Coastguard Worker if (mapped > 0) {
3282*e5436536SAndroid Build Coastguard Worker if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
3283*e5436536SAndroid Build Coastguard Worker /* If at least one DRC thread has been mapped to a channel there was DRC
3284*e5436536SAndroid Build Coastguard Worker * data in the bitstream. */
3285*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex] |= AC_DRC_PRESENT;
3286*e5436536SAndroid Build Coastguard Worker } else {
3287*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
3288*e5436536SAndroid Build Coastguard Worker }
3289*e5436536SAndroid Build Coastguard Worker }
3290*e5436536SAndroid Build Coastguard Worker if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) {
3291*e5436536SAndroid Build Coastguard Worker aacDecoder_drcDisable(self->hDrcInfo);
3292*e5436536SAndroid Build Coastguard Worker }
3293*e5436536SAndroid Build Coastguard Worker
3294*e5436536SAndroid Build Coastguard Worker /* Create a reverse mapping table */
3295*e5436536SAndroid Build Coastguard Worker UCHAR Reverse_chMapping[((8) * 2)];
3296*e5436536SAndroid Build Coastguard Worker for (c = 0; c < aacChannels; c++) {
3297*e5436536SAndroid Build Coastguard Worker int d;
3298*e5436536SAndroid Build Coastguard Worker for (d = 0; d < aacChannels - 1; d++) {
3299*e5436536SAndroid Build Coastguard Worker if (self->chMapping[d] == c) {
3300*e5436536SAndroid Build Coastguard Worker break;
3301*e5436536SAndroid Build Coastguard Worker }
3302*e5436536SAndroid Build Coastguard Worker }
3303*e5436536SAndroid Build Coastguard Worker Reverse_chMapping[c] = d;
3304*e5436536SAndroid Build Coastguard Worker }
3305*e5436536SAndroid Build Coastguard Worker
3306*e5436536SAndroid Build Coastguard Worker int el;
3307*e5436536SAndroid Build Coastguard Worker int el_channels;
3308*e5436536SAndroid Build Coastguard Worker c = 0;
3309*e5436536SAndroid Build Coastguard Worker cIdx = 0;
3310*e5436536SAndroid Build Coastguard Worker el_channels = 0;
3311*e5436536SAndroid Build Coastguard Worker for (el = 0; el < element_count; el++) {
3312*e5436536SAndroid Build Coastguard Worker int frameOk_butConceal =
3313*e5436536SAndroid Build Coastguard Worker 0; /* Force frame concealment during mute release active state. */
3314*e5436536SAndroid Build Coastguard Worker int concealApplyReturnCode;
3315*e5436536SAndroid Build Coastguard Worker
3316*e5436536SAndroid Build Coastguard Worker if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA | AC_BSAC)) {
3317*e5436536SAndroid Build Coastguard Worker type = self->elements[el];
3318*e5436536SAndroid Build Coastguard Worker } else {
3319*e5436536SAndroid Build Coastguard Worker type = channel_elements[el];
3320*e5436536SAndroid Build Coastguard Worker }
3321*e5436536SAndroid Build Coastguard Worker
3322*e5436536SAndroid Build Coastguard Worker {
3323*e5436536SAndroid Build Coastguard Worker int nElementChannels;
3324*e5436536SAndroid Build Coastguard Worker
3325*e5436536SAndroid Build Coastguard Worker nElementChannels =
3326*e5436536SAndroid Build Coastguard Worker CAacDecoder_GetELChannels(type, self->usacStereoConfigIndex[el]);
3327*e5436536SAndroid Build Coastguard Worker
3328*e5436536SAndroid Build Coastguard Worker el_channels += nElementChannels;
3329*e5436536SAndroid Build Coastguard Worker
3330*e5436536SAndroid Build Coastguard Worker if (nElementChannels == 0) {
3331*e5436536SAndroid Build Coastguard Worker continue;
3332*e5436536SAndroid Build Coastguard Worker }
3333*e5436536SAndroid Build Coastguard Worker }
3334*e5436536SAndroid Build Coastguard Worker
3335*e5436536SAndroid Build Coastguard Worker int offset;
3336*e5436536SAndroid Build Coastguard Worker int elCh = 0;
3337*e5436536SAndroid Build Coastguard Worker /* "c" iterates in canonical MPEG channel order */
3338*e5436536SAndroid Build Coastguard Worker for (; cIdx < el_channels; c++, cIdx++, elCh++) {
3339*e5436536SAndroid Build Coastguard Worker /* Robustness check */
3340*e5436536SAndroid Build Coastguard Worker if (c >= aacChannels) {
3341*e5436536SAndroid Build Coastguard Worker return AAC_DEC_UNKNOWN;
3342*e5436536SAndroid Build Coastguard Worker }
3343*e5436536SAndroid Build Coastguard Worker
3344*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo =
3345*e5436536SAndroid Build Coastguard Worker self->pAacDecoderChannelInfo[c];
3346*e5436536SAndroid Build Coastguard Worker CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
3347*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[c];
3348*e5436536SAndroid Build Coastguard Worker
3349*e5436536SAndroid Build Coastguard Worker /* Setup offset for time buffer traversal. */
3350*e5436536SAndroid Build Coastguard Worker {
3351*e5436536SAndroid Build Coastguard Worker pAacDecoderStaticChannelInfo =
3352*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[Reverse_chMapping[c]];
3353*e5436536SAndroid Build Coastguard Worker offset =
3354*e5436536SAndroid Build Coastguard Worker FDK_chMapDescr_getMapValue(
3355*e5436536SAndroid Build Coastguard Worker &self->mapDescr, Reverse_chMapping[cIdx], self->chMapIndex) *
3356*e5436536SAndroid Build Coastguard Worker timeDataChannelOffset;
3357*e5436536SAndroid Build Coastguard Worker }
3358*e5436536SAndroid Build Coastguard Worker
3359*e5436536SAndroid Build Coastguard Worker if (flags & AACDEC_FLUSH) {
3360*e5436536SAndroid Build Coastguard Worker /* Clear pAacDecoderChannelInfo->pSpectralCoefficient because with
3361*e5436536SAndroid Build Coastguard Worker * AACDEC_FLUSH set it contains undefined data. */
3362*e5436536SAndroid Build Coastguard Worker FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
3363*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * self->streamInfo.aacSamplesPerFrame);
3364*e5436536SAndroid Build Coastguard Worker }
3365*e5436536SAndroid Build Coastguard Worker
3366*e5436536SAndroid Build Coastguard Worker /* if The ics info is not valid and it will be stored and used in the
3367*e5436536SAndroid Build Coastguard Worker * following concealment method, mark the frame as erroneous */
3368*e5436536SAndroid Build Coastguard Worker {
3369*e5436536SAndroid Build Coastguard Worker CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
3370*e5436536SAndroid Build Coastguard Worker CConcealmentInfo *hConcealmentInfo =
3371*e5436536SAndroid Build Coastguard Worker &pAacDecoderStaticChannelInfo->concealmentInfo;
3372*e5436536SAndroid Build Coastguard Worker const int mute_release_active =
3373*e5436536SAndroid Build Coastguard Worker (self->frameOK && !(flags & AACDEC_CONCEAL)) &&
3374*e5436536SAndroid Build Coastguard Worker ((hConcealmentInfo->concealState >= ConcealState_Mute) &&
3375*e5436536SAndroid Build Coastguard Worker (hConcealmentInfo->cntValidFrames + 1 <=
3376*e5436536SAndroid Build Coastguard Worker hConcealmentInfo->pConcealParams->numMuteReleaseFrames));
3377*e5436536SAndroid Build Coastguard Worker const int icsIsInvalid = (GetScaleFactorBandsTransmitted(pIcsInfo) >
3378*e5436536SAndroid Build Coastguard Worker GetScaleFactorBandsTotal(pIcsInfo));
3379*e5436536SAndroid Build Coastguard Worker const int icsInfoUsedinFadeOut =
3380*e5436536SAndroid Build Coastguard Worker !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
3381*e5436536SAndroid Build Coastguard Worker pAacDecoderStaticChannelInfo->last_lpd_mode == 0);
3382*e5436536SAndroid Build Coastguard Worker if (icsInfoUsedinFadeOut && icsIsInvalid && !mute_release_active) {
3383*e5436536SAndroid Build Coastguard Worker self->frameOK = 0;
3384*e5436536SAndroid Build Coastguard Worker }
3385*e5436536SAndroid Build Coastguard Worker }
3386*e5436536SAndroid Build Coastguard Worker
3387*e5436536SAndroid Build Coastguard Worker /*
3388*e5436536SAndroid Build Coastguard Worker Conceal defective spectral data
3389*e5436536SAndroid Build Coastguard Worker */
3390*e5436536SAndroid Build Coastguard Worker {
3391*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo **ppAacDecoderChannelInfo =
3392*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo;
3393*e5436536SAndroid Build Coastguard Worker CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo =
3394*e5436536SAndroid Build Coastguard Worker &pAacDecoderStaticChannelInfo;
3395*e5436536SAndroid Build Coastguard Worker {
3396*e5436536SAndroid Build Coastguard Worker concealApplyReturnCode = CConcealment_Apply(
3397*e5436536SAndroid Build Coastguard Worker &(*ppAacDecoderStaticChannelInfo)->concealmentInfo,
3398*e5436536SAndroid Build Coastguard Worker *ppAacDecoderChannelInfo, *ppAacDecoderStaticChannelInfo,
3399*e5436536SAndroid Build Coastguard Worker &self->samplingRateInfo[streamIndex],
3400*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame,
3401*e5436536SAndroid Build Coastguard Worker pAacDecoderStaticChannelInfo->last_lpd_mode,
3402*e5436536SAndroid Build Coastguard Worker (self->frameOK && !(flags & AACDEC_CONCEAL)),
3403*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex]);
3404*e5436536SAndroid Build Coastguard Worker }
3405*e5436536SAndroid Build Coastguard Worker }
3406*e5436536SAndroid Build Coastguard Worker if (concealApplyReturnCode == -1) {
3407*e5436536SAndroid Build Coastguard Worker frameOk_butConceal = 1;
3408*e5436536SAndroid Build Coastguard Worker }
3409*e5436536SAndroid Build Coastguard Worker
3410*e5436536SAndroid Build Coastguard Worker if (flags & (AACDEC_INTR)) {
3411*e5436536SAndroid Build Coastguard Worker /* Reset DRC control data for this channel */
3412*e5436536SAndroid Build Coastguard Worker aacDecoder_drcInitChannelData(&pAacDecoderStaticChannelInfo->drcData);
3413*e5436536SAndroid Build Coastguard Worker }
3414*e5436536SAndroid Build Coastguard Worker if (flags & (AACDEC_CLRHIST)) {
3415*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] & AC_USAC)) {
3416*e5436536SAndroid Build Coastguard Worker /* Reset DRC control data for this channel */
3417*e5436536SAndroid Build Coastguard Worker aacDecoder_drcInitChannelData(
3418*e5436536SAndroid Build Coastguard Worker &pAacDecoderStaticChannelInfo->drcData);
3419*e5436536SAndroid Build Coastguard Worker }
3420*e5436536SAndroid Build Coastguard Worker }
3421*e5436536SAndroid Build Coastguard Worker
3422*e5436536SAndroid Build Coastguard Worker /* The DRC module demands to be called with the gain field holding the
3423*e5436536SAndroid Build Coastguard Worker * gain scale. */
3424*e5436536SAndroid Build Coastguard Worker self->extGain[0] = (FIXP_DBL)AACDEC_DRC_GAIN_SCALING;
3425*e5436536SAndroid Build Coastguard Worker
3426*e5436536SAndroid Build Coastguard Worker /* DRC processing */
3427*e5436536SAndroid Build Coastguard Worker aacDecoder_drcApply(
3428*e5436536SAndroid Build Coastguard Worker self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
3429*e5436536SAndroid Build Coastguard Worker &pAacDecoderStaticChannelInfo->drcData, self->extGain, c,
3430*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame, self->sbrEnabled
3431*e5436536SAndroid Build Coastguard Worker
3432*e5436536SAndroid Build Coastguard Worker );
3433*e5436536SAndroid Build Coastguard Worker
3434*e5436536SAndroid Build Coastguard Worker if (timeDataSize < timeDataChannelOffset * self->aacChannels) {
3435*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
3436*e5436536SAndroid Build Coastguard Worker break;
3437*e5436536SAndroid Build Coastguard Worker }
3438*e5436536SAndroid Build Coastguard Worker if (self->flushStatus && (self->flushCnt > 0) &&
3439*e5436536SAndroid Build Coastguard Worker !(flags & AACDEC_CONCEAL)) {
3440*e5436536SAndroid Build Coastguard Worker FDKmemclear(pTimeData + offset,
3441*e5436536SAndroid Build Coastguard Worker sizeof(PCM_DEC) * self->streamInfo.aacSamplesPerFrame);
3442*e5436536SAndroid Build Coastguard Worker } else
3443*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->renderMode) {
3444*e5436536SAndroid Build Coastguard Worker case AACDEC_RENDER_IMDCT:
3445*e5436536SAndroid Build Coastguard Worker
3446*e5436536SAndroid Build Coastguard Worker CBlock_FrequencyToTime(
3447*e5436536SAndroid Build Coastguard Worker pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
3448*e5436536SAndroid Build Coastguard Worker pTimeData + offset, self->streamInfo.aacSamplesPerFrame,
3449*e5436536SAndroid Build Coastguard Worker (self->frameOK && !(flags & AACDEC_CONCEAL) &&
3450*e5436536SAndroid Build Coastguard Worker !frameOk_butConceal),
3451*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
3452*e5436536SAndroid Build Coastguard Worker ->mdctOutTemp,
3453*e5436536SAndroid Build Coastguard Worker self->aacOutDataHeadroom, self->elFlags[el], elCh);
3454*e5436536SAndroid Build Coastguard Worker
3455*e5436536SAndroid Build Coastguard Worker self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
3456*e5436536SAndroid Build Coastguard Worker break;
3457*e5436536SAndroid Build Coastguard Worker case AACDEC_RENDER_ELDFB: {
3458*e5436536SAndroid Build Coastguard Worker CBlock_FrequencyToTimeLowDelay(
3459*e5436536SAndroid Build Coastguard Worker pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
3460*e5436536SAndroid Build Coastguard Worker pTimeData + offset, self->streamInfo.aacSamplesPerFrame);
3461*e5436536SAndroid Build Coastguard Worker self->extGainDelay =
3462*e5436536SAndroid Build Coastguard Worker (self->streamInfo.aacSamplesPerFrame * 2 -
3463*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame / 2 - 1) /
3464*e5436536SAndroid Build Coastguard Worker 2;
3465*e5436536SAndroid Build Coastguard Worker } break;
3466*e5436536SAndroid Build Coastguard Worker case AACDEC_RENDER_LPD:
3467*e5436536SAndroid Build Coastguard Worker
3468*e5436536SAndroid Build Coastguard Worker CLpd_RenderTimeSignal(
3469*e5436536SAndroid Build Coastguard Worker pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
3470*e5436536SAndroid Build Coastguard Worker pTimeData + offset, self->streamInfo.aacSamplesPerFrame,
3471*e5436536SAndroid Build Coastguard Worker &self->samplingRateInfo[streamIndex],
3472*e5436536SAndroid Build Coastguard Worker (self->frameOK && !(flags & AACDEC_CONCEAL) &&
3473*e5436536SAndroid Build Coastguard Worker !frameOk_butConceal),
3474*e5436536SAndroid Build Coastguard Worker self->aacOutDataHeadroom, flags, self->flags[streamIndex]);
3475*e5436536SAndroid Build Coastguard Worker
3476*e5436536SAndroid Build Coastguard Worker self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
3477*e5436536SAndroid Build Coastguard Worker break;
3478*e5436536SAndroid Build Coastguard Worker default:
3479*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_UNKNOWN;
3480*e5436536SAndroid Build Coastguard Worker break;
3481*e5436536SAndroid Build Coastguard Worker }
3482*e5436536SAndroid Build Coastguard Worker /* TimeDomainFading */
3483*e5436536SAndroid Build Coastguard Worker if (!CConceal_TDFading_Applied[c]) {
3484*e5436536SAndroid Build Coastguard Worker CConceal_TDFading_Applied[c] = CConcealment_TDFading(
3485*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame,
3486*e5436536SAndroid Build Coastguard Worker &self->pAacDecoderStaticChannelInfo[c], self->aacOutDataHeadroom,
3487*e5436536SAndroid Build Coastguard Worker pTimeData + offset, 0);
3488*e5436536SAndroid Build Coastguard Worker if (c + 1 < (8) && c < aacChannels - 1) {
3489*e5436536SAndroid Build Coastguard Worker /* update next TDNoise Seed to avoid muting in case of Parametric
3490*e5436536SAndroid Build Coastguard Worker * Stereo */
3491*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[c + 1]
3492*e5436536SAndroid Build Coastguard Worker ->concealmentInfo.TDNoiseSeed =
3493*e5436536SAndroid Build Coastguard Worker self->pAacDecoderStaticChannelInfo[c]
3494*e5436536SAndroid Build Coastguard Worker ->concealmentInfo.TDNoiseSeed;
3495*e5436536SAndroid Build Coastguard Worker }
3496*e5436536SAndroid Build Coastguard Worker }
3497*e5436536SAndroid Build Coastguard Worker }
3498*e5436536SAndroid Build Coastguard Worker }
3499*e5436536SAndroid Build Coastguard Worker
3500*e5436536SAndroid Build Coastguard Worker if (self->flags[streamIndex] & AC_USAC) {
3501*e5436536SAndroid Build Coastguard Worker int bsPseudoLr = 0;
3502*e5436536SAndroid Build Coastguard Worker mpegSurroundDecoder_IsPseudoLR(
3503*e5436536SAndroid Build Coastguard Worker (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, &bsPseudoLr);
3504*e5436536SAndroid Build Coastguard Worker /* ISO/IEC 23003-3, 7.11.2.6 Modification of core decoder output (pseudo
3505*e5436536SAndroid Build Coastguard Worker * LR) */
3506*e5436536SAndroid Build Coastguard Worker if ((aacChannels == 2) && bsPseudoLr) {
3507*e5436536SAndroid Build Coastguard Worker int i, offset2;
3508*e5436536SAndroid Build Coastguard Worker const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
3509*e5436536SAndroid Build Coastguard Worker PCM_DEC *pTD = pTimeData;
3510*e5436536SAndroid Build Coastguard Worker
3511*e5436536SAndroid Build Coastguard Worker offset2 = timeDataChannelOffset;
3512*e5436536SAndroid Build Coastguard Worker
3513*e5436536SAndroid Build Coastguard Worker for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
3514*e5436536SAndroid Build Coastguard Worker FIXP_DBL L = PCM_DEC2FIXP_DBL(pTD[0]);
3515*e5436536SAndroid Build Coastguard Worker FIXP_DBL R = PCM_DEC2FIXP_DBL(pTD[offset2]);
3516*e5436536SAndroid Build Coastguard Worker L = fMult(L, invSqrt2);
3517*e5436536SAndroid Build Coastguard Worker R = fMult(R, invSqrt2);
3518*e5436536SAndroid Build Coastguard Worker pTD[0] = L + R;
3519*e5436536SAndroid Build Coastguard Worker pTD[offset2] = L - R;
3520*e5436536SAndroid Build Coastguard Worker pTD++;
3521*e5436536SAndroid Build Coastguard Worker }
3522*e5436536SAndroid Build Coastguard Worker }
3523*e5436536SAndroid Build Coastguard Worker }
3524*e5436536SAndroid Build Coastguard Worker
3525*e5436536SAndroid Build Coastguard Worker /* Extract DRC control data and map it to channels (with bitstream delay) */
3526*e5436536SAndroid Build Coastguard Worker mapped = aacDecoder_drcEpilog(
3527*e5436536SAndroid Build Coastguard Worker self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
3528*e5436536SAndroid Build Coastguard Worker pce->ElementInstanceTag, drcChMap, aacChannels);
3529*e5436536SAndroid Build Coastguard Worker if (mapped > 0) {
3530*e5436536SAndroid Build Coastguard Worker if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
3531*e5436536SAndroid Build Coastguard Worker /* If at least one DRC thread has been mapped to a channel there was DRC
3532*e5436536SAndroid Build Coastguard Worker * data in the bitstream. */
3533*e5436536SAndroid Build Coastguard Worker self->flags[streamIndex] |= AC_DRC_PRESENT;
3534*e5436536SAndroid Build Coastguard Worker } else {
3535*e5436536SAndroid Build Coastguard Worker ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
3536*e5436536SAndroid Build Coastguard Worker }
3537*e5436536SAndroid Build Coastguard Worker }
3538*e5436536SAndroid Build Coastguard Worker if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) {
3539*e5436536SAndroid Build Coastguard Worker aacDecoder_drcDisable(self->hDrcInfo);
3540*e5436536SAndroid Build Coastguard Worker }
3541*e5436536SAndroid Build Coastguard Worker }
3542*e5436536SAndroid Build Coastguard Worker
3543*e5436536SAndroid Build Coastguard Worker /* Add additional concealment delay */
3544*e5436536SAndroid Build Coastguard Worker self->streamInfo.outputDelay +=
3545*e5436536SAndroid Build Coastguard Worker CConcealment_GetDelay(&self->concealCommonData) *
3546*e5436536SAndroid Build Coastguard Worker self->streamInfo.aacSamplesPerFrame;
3547*e5436536SAndroid Build Coastguard Worker
3548*e5436536SAndroid Build Coastguard Worker /* Map DRC data to StreamInfo structure */
3549*e5436536SAndroid Build Coastguard Worker aacDecoder_drcGetInfo(self->hDrcInfo, &self->streamInfo.drcPresMode,
3550*e5436536SAndroid Build Coastguard Worker &self->streamInfo.drcProgRefLev);
3551*e5436536SAndroid Build Coastguard Worker
3552*e5436536SAndroid Build Coastguard Worker /* Reorder channel type information tables. */
3553*e5436536SAndroid Build Coastguard Worker if (!(self->flags[0] & AC_RSV603DA)) {
3554*e5436536SAndroid Build Coastguard Worker AUDIO_CHANNEL_TYPE types[(8)];
3555*e5436536SAndroid Build Coastguard Worker UCHAR idx[(8)];
3556*e5436536SAndroid Build Coastguard Worker int c;
3557*e5436536SAndroid Build Coastguard Worker int mapValue;
3558*e5436536SAndroid Build Coastguard Worker
3559*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(sizeof(self->channelType) == sizeof(types));
3560*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(sizeof(self->channelIndices) == sizeof(idx));
3561*e5436536SAndroid Build Coastguard Worker
3562*e5436536SAndroid Build Coastguard Worker FDKmemcpy(types, self->channelType, sizeof(types));
3563*e5436536SAndroid Build Coastguard Worker FDKmemcpy(idx, self->channelIndices, sizeof(idx));
3564*e5436536SAndroid Build Coastguard Worker
3565*e5436536SAndroid Build Coastguard Worker for (c = 0; c < aacChannels; c++) {
3566*e5436536SAndroid Build Coastguard Worker mapValue =
3567*e5436536SAndroid Build Coastguard Worker FDK_chMapDescr_getMapValue(&self->mapDescr, c, self->chMapIndex);
3568*e5436536SAndroid Build Coastguard Worker self->channelType[mapValue] = types[c];
3569*e5436536SAndroid Build Coastguard Worker self->channelIndices[mapValue] = idx[c];
3570*e5436536SAndroid Build Coastguard Worker }
3571*e5436536SAndroid Build Coastguard Worker }
3572*e5436536SAndroid Build Coastguard Worker
3573*e5436536SAndroid Build Coastguard Worker self->blockNumber++;
3574*e5436536SAndroid Build Coastguard Worker
3575*e5436536SAndroid Build Coastguard Worker return ErrorStatus;
3576*e5436536SAndroid Build Coastguard Worker }
3577*e5436536SAndroid Build Coastguard Worker
3578*e5436536SAndroid Build Coastguard Worker /*!
3579*e5436536SAndroid Build Coastguard Worker \brief returns the streaminfo pointer
3580*e5436536SAndroid Build Coastguard Worker
3581*e5436536SAndroid Build Coastguard Worker The function hands back a pointer to the streaminfo structure
3582*e5436536SAndroid Build Coastguard Worker
3583*e5436536SAndroid Build Coastguard Worker \return pointer to the struct
3584*e5436536SAndroid Build Coastguard Worker */
CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self)3585*e5436536SAndroid Build Coastguard Worker LINKSPEC_CPP CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
3586*e5436536SAndroid Build Coastguard Worker if (!self) {
3587*e5436536SAndroid Build Coastguard Worker return NULL;
3588*e5436536SAndroid Build Coastguard Worker }
3589*e5436536SAndroid Build Coastguard Worker return &self->streamInfo;
3590*e5436536SAndroid Build Coastguard Worker }
3591