xref: /aosp_15_r20/external/aac/libSACdec/src/sac_bitdec.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2020 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 /*********************** MPEG surround decoder library *************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: SAC Dec bitstream decoder
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "sac_bitdec.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "sac_dec_errorcodes.h"
106*e5436536SAndroid Build Coastguard Worker #include "nlc_dec.h"
107*e5436536SAndroid Build Coastguard Worker #include "sac_rom.h"
108*e5436536SAndroid Build Coastguard Worker #include "FDK_matrixCalloc.h"
109*e5436536SAndroid Build Coastguard Worker #include "sac_tsd.h"
110*e5436536SAndroid Build Coastguard Worker 
111*e5436536SAndroid Build Coastguard Worker enum {
112*e5436536SAndroid Build Coastguard Worker   ottVsTotInactiv = 0,
113*e5436536SAndroid Build Coastguard Worker   ottVsTotDb1Activ = 1,
114*e5436536SAndroid Build Coastguard Worker   ottVsTotDb2Activ = 2,
115*e5436536SAndroid Build Coastguard Worker   ottVsTotDb1Db2Activ = 3
116*e5436536SAndroid Build Coastguard Worker };
117*e5436536SAndroid Build Coastguard Worker 
SpatialDecDecodeHelperInfo(SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig,UPMIXTYPE upmixType)118*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR SpatialDecDecodeHelperInfo(
119*e5436536SAndroid Build Coastguard Worker     SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, UPMIXTYPE upmixType) {
120*e5436536SAndroid Build Coastguard Worker   int i;
121*e5436536SAndroid Build Coastguard Worker   UINT syntaxFlags;
122*e5436536SAndroid Build Coastguard Worker 
123*e5436536SAndroid Build Coastguard Worker   /* Determine bit stream syntax */
124*e5436536SAndroid Build Coastguard Worker   syntaxFlags = 0;
125*e5436536SAndroid Build Coastguard Worker   switch (pSpatialSpecificConfig->coreCodec) {
126*e5436536SAndroid Build Coastguard Worker     case AOT_ER_AAC_ELD:
127*e5436536SAndroid Build Coastguard Worker     case AOT_ER_AAC_LD:
128*e5436536SAndroid Build Coastguard Worker       syntaxFlags |= SACDEC_SYNTAX_LD;
129*e5436536SAndroid Build Coastguard Worker       break;
130*e5436536SAndroid Build Coastguard Worker     case AOT_USAC:
131*e5436536SAndroid Build Coastguard Worker       syntaxFlags |= SACDEC_SYNTAX_USAC;
132*e5436536SAndroid Build Coastguard Worker       break;
133*e5436536SAndroid Build Coastguard Worker     case AOT_NONE:
134*e5436536SAndroid Build Coastguard Worker     default:
135*e5436536SAndroid Build Coastguard Worker       return MPS_UNSUPPORTED_FORMAT;
136*e5436536SAndroid Build Coastguard Worker   }
137*e5436536SAndroid Build Coastguard Worker 
138*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->syntaxFlags = syntaxFlags;
139*e5436536SAndroid Build Coastguard Worker 
140*e5436536SAndroid Build Coastguard Worker   switch (pSpatialSpecificConfig->treeConfig) {
141*e5436536SAndroid Build Coastguard Worker     case TREE_212: {
142*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->ottCLDdefault[0] = 0;
143*e5436536SAndroid Build Coastguard Worker     } break;
144*e5436536SAndroid Build Coastguard Worker     default:
145*e5436536SAndroid Build Coastguard Worker       return MPS_INVALID_TREECONFIG;
146*e5436536SAndroid Build Coastguard Worker   }
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker   if (syntaxFlags & SACDEC_SYNTAX_USAC) {
149*e5436536SAndroid Build Coastguard Worker     if (pSpatialSpecificConfig->bsOttBandsPhasePresent) {
150*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->numOttBandsIPD =
151*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->bsOttBandsPhase;
152*e5436536SAndroid Build Coastguard Worker     } else {
153*e5436536SAndroid Build Coastguard Worker       int numParameterBands;
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker       numParameterBands = pSpatialSpecificConfig->freqRes;
156*e5436536SAndroid Build Coastguard Worker       switch (numParameterBands) {
157*e5436536SAndroid Build Coastguard Worker         case 4:
158*e5436536SAndroid Build Coastguard Worker         case 5:
159*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->numOttBandsIPD = 2;
160*e5436536SAndroid Build Coastguard Worker           break;
161*e5436536SAndroid Build Coastguard Worker         case 7:
162*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->numOttBandsIPD = 3;
163*e5436536SAndroid Build Coastguard Worker           break;
164*e5436536SAndroid Build Coastguard Worker         case 10:
165*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->numOttBandsIPD = 5;
166*e5436536SAndroid Build Coastguard Worker           break;
167*e5436536SAndroid Build Coastguard Worker         case 14:
168*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->numOttBandsIPD = 7;
169*e5436536SAndroid Build Coastguard Worker           break;
170*e5436536SAndroid Build Coastguard Worker         case 20:
171*e5436536SAndroid Build Coastguard Worker         case 28:
172*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->numOttBandsIPD = 10;
173*e5436536SAndroid Build Coastguard Worker           break;
174*e5436536SAndroid Build Coastguard Worker         default:
175*e5436536SAndroid Build Coastguard Worker           return MPS_INVALID_PARAMETERBANDS;
176*e5436536SAndroid Build Coastguard Worker       }
177*e5436536SAndroid Build Coastguard Worker     }
178*e5436536SAndroid Build Coastguard Worker   } else {
179*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->numOttBandsIPD = 0;
180*e5436536SAndroid Build Coastguard Worker   }
181*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
182*e5436536SAndroid Build Coastguard Worker     {
183*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bitstreamOttBands[i] =
184*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->freqRes;
185*e5436536SAndroid Build Coastguard Worker     }
186*e5436536SAndroid Build Coastguard Worker     {
187*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->numOttBands[i] =
188*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->bitstreamOttBands[i];
189*e5436536SAndroid Build Coastguard Worker       if (syntaxFlags & SACDEC_SYNTAX_USAC &&
190*e5436536SAndroid Build Coastguard Worker           !pSpatialSpecificConfig->bsOttBandsPhasePresent) {
191*e5436536SAndroid Build Coastguard Worker         if (pSpatialSpecificConfig->bResidualCoding &&
192*e5436536SAndroid Build Coastguard Worker             pSpatialSpecificConfig->ResidualConfig[i].bResidualPresent &&
193*e5436536SAndroid Build Coastguard Worker             (pSpatialSpecificConfig->numOttBandsIPD <
194*e5436536SAndroid Build Coastguard Worker              pSpatialSpecificConfig->ResidualConfig[i].nResidualBands)) {
195*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->numOttBandsIPD =
196*e5436536SAndroid Build Coastguard Worker               pSpatialSpecificConfig->ResidualConfig[i].nResidualBands;
197*e5436536SAndroid Build Coastguard Worker         }
198*e5436536SAndroid Build Coastguard Worker       }
199*e5436536SAndroid Build Coastguard Worker     }
200*e5436536SAndroid Build Coastguard Worker   } /* i */
201*e5436536SAndroid Build Coastguard Worker 
202*e5436536SAndroid Build Coastguard Worker   return MPS_OK;
203*e5436536SAndroid Build Coastguard Worker }
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
206*e5436536SAndroid Build Coastguard Worker  Functionname: SpatialDecParseExtensionConfig
207*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
208*e5436536SAndroid Build Coastguard Worker 
209*e5436536SAndroid Build Coastguard Worker  Description:
210*e5436536SAndroid Build Coastguard Worker 
211*e5436536SAndroid Build Coastguard Worker  Arguments:
212*e5436536SAndroid Build Coastguard Worker 
213*e5436536SAndroid Build Coastguard Worker  Return:
214*e5436536SAndroid Build Coastguard Worker 
215*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
216*e5436536SAndroid Build Coastguard Worker 
SpatialDecParseExtensionConfig(HANDLE_FDK_BITSTREAM bitstream,SPATIAL_SPECIFIC_CONFIG * config,int numOttBoxes,int numTttBoxes,int numOutChan,int bitsAvailable)217*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR SpatialDecParseExtensionConfig(
218*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream, SPATIAL_SPECIFIC_CONFIG *config,
219*e5436536SAndroid Build Coastguard Worker     int numOttBoxes, int numTttBoxes, int numOutChan, int bitsAvailable) {
220*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
221*e5436536SAndroid Build Coastguard Worker   INT ba = bitsAvailable;
222*e5436536SAndroid Build Coastguard Worker 
223*e5436536SAndroid Build Coastguard Worker   config->sacExtCnt = 0;
224*e5436536SAndroid Build Coastguard Worker   config->bResidualCoding = 0;
225*e5436536SAndroid Build Coastguard Worker 
226*e5436536SAndroid Build Coastguard Worker   ba = fMin((int)FDKgetValidBits(bitstream), ba);
227*e5436536SAndroid Build Coastguard Worker 
228*e5436536SAndroid Build Coastguard Worker   while ((ba >= 8) && (config->sacExtCnt < MAX_NUM_EXT_TYPES)) {
229*e5436536SAndroid Build Coastguard Worker     int bitsRead, nFillBits;
230*e5436536SAndroid Build Coastguard Worker     INT tmp;
231*e5436536SAndroid Build Coastguard Worker     UINT sacExtLen;
232*e5436536SAndroid Build Coastguard Worker 
233*e5436536SAndroid Build Coastguard Worker     config->sacExtType[config->sacExtCnt] = FDKreadBits(bitstream, 4);
234*e5436536SAndroid Build Coastguard Worker     ba -= 4;
235*e5436536SAndroid Build Coastguard Worker 
236*e5436536SAndroid Build Coastguard Worker     sacExtLen = FDKreadBits(bitstream, 4);
237*e5436536SAndroid Build Coastguard Worker     ba -= 4;
238*e5436536SAndroid Build Coastguard Worker 
239*e5436536SAndroid Build Coastguard Worker     if (sacExtLen == 15) {
240*e5436536SAndroid Build Coastguard Worker       sacExtLen += FDKreadBits(bitstream, 8);
241*e5436536SAndroid Build Coastguard Worker       ba -= 8;
242*e5436536SAndroid Build Coastguard Worker       if (sacExtLen == 15 + 255) {
243*e5436536SAndroid Build Coastguard Worker         sacExtLen += FDKreadBits(bitstream, 16);
244*e5436536SAndroid Build Coastguard Worker         ba -= 16;
245*e5436536SAndroid Build Coastguard Worker       }
246*e5436536SAndroid Build Coastguard Worker     }
247*e5436536SAndroid Build Coastguard Worker 
248*e5436536SAndroid Build Coastguard Worker     tmp = (INT)FDKgetValidBits(
249*e5436536SAndroid Build Coastguard Worker         bitstream); /* Extension config payload start anchor. */
250*e5436536SAndroid Build Coastguard Worker     if ((tmp <= 0) || (tmp < (INT)sacExtLen * 8) || (ba < (INT)sacExtLen * 8)) {
251*e5436536SAndroid Build Coastguard Worker       err = MPS_PARSE_ERROR;
252*e5436536SAndroid Build Coastguard Worker       goto bail;
253*e5436536SAndroid Build Coastguard Worker     }
254*e5436536SAndroid Build Coastguard Worker 
255*e5436536SAndroid Build Coastguard Worker     switch (config->sacExtType[config->sacExtCnt]) {
256*e5436536SAndroid Build Coastguard Worker       default:; /* unknown extension data => do nothing */
257*e5436536SAndroid Build Coastguard Worker     }
258*e5436536SAndroid Build Coastguard Worker 
259*e5436536SAndroid Build Coastguard Worker     /* skip remaining extension data */
260*e5436536SAndroid Build Coastguard Worker     bitsRead = tmp - FDKgetValidBits(bitstream);
261*e5436536SAndroid Build Coastguard Worker     nFillBits = 8 * sacExtLen - bitsRead;
262*e5436536SAndroid Build Coastguard Worker 
263*e5436536SAndroid Build Coastguard Worker     if (nFillBits < 0) {
264*e5436536SAndroid Build Coastguard Worker       err = MPS_PARSE_ERROR;
265*e5436536SAndroid Build Coastguard Worker       goto bail;
266*e5436536SAndroid Build Coastguard Worker     } else {
267*e5436536SAndroid Build Coastguard Worker       /* Skip fill bits or an unkown extension. */
268*e5436536SAndroid Build Coastguard Worker       FDKpushFor(bitstream, nFillBits);
269*e5436536SAndroid Build Coastguard Worker     }
270*e5436536SAndroid Build Coastguard Worker 
271*e5436536SAndroid Build Coastguard Worker     ba -= 8 * sacExtLen;
272*e5436536SAndroid Build Coastguard Worker     config->sacExtCnt++;
273*e5436536SAndroid Build Coastguard Worker   }
274*e5436536SAndroid Build Coastguard Worker 
275*e5436536SAndroid Build Coastguard Worker bail:
276*e5436536SAndroid Build Coastguard Worker   return err;
277*e5436536SAndroid Build Coastguard Worker }
278*e5436536SAndroid Build Coastguard Worker 
SpatialDecParseSpecificConfigHeader(HANDLE_FDK_BITSTREAM bitstream,SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig,AUDIO_OBJECT_TYPE coreCodec,SPATIAL_DEC_UPMIX_TYPE upmixType)279*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecParseSpecificConfigHeader(
280*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream,
281*e5436536SAndroid Build Coastguard Worker     SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
282*e5436536SAndroid Build Coastguard Worker     AUDIO_OBJECT_TYPE coreCodec, SPATIAL_DEC_UPMIX_TYPE upmixType) {
283*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
284*e5436536SAndroid Build Coastguard Worker   INT numFillBits;
285*e5436536SAndroid Build Coastguard Worker   int sacHeaderLen = 0;
286*e5436536SAndroid Build Coastguard Worker   int sacTimeAlignFlag = 0;
287*e5436536SAndroid Build Coastguard Worker 
288*e5436536SAndroid Build Coastguard Worker   sacTimeAlignFlag = FDKreadBits(bitstream, 1);
289*e5436536SAndroid Build Coastguard Worker   sacHeaderLen = FDKreadBits(bitstream, 7);
290*e5436536SAndroid Build Coastguard Worker 
291*e5436536SAndroid Build Coastguard Worker   if (sacHeaderLen == 127) {
292*e5436536SAndroid Build Coastguard Worker     sacHeaderLen += FDKreadBits(bitstream, 16);
293*e5436536SAndroid Build Coastguard Worker   }
294*e5436536SAndroid Build Coastguard Worker   numFillBits = (INT)FDKgetValidBits(bitstream);
295*e5436536SAndroid Build Coastguard Worker 
296*e5436536SAndroid Build Coastguard Worker   err = SpatialDecParseSpecificConfig(bitstream, pSpatialSpecificConfig,
297*e5436536SAndroid Build Coastguard Worker                                       sacHeaderLen, coreCodec);
298*e5436536SAndroid Build Coastguard Worker 
299*e5436536SAndroid Build Coastguard Worker   numFillBits -=
300*e5436536SAndroid Build Coastguard Worker       (INT)FDKgetValidBits(bitstream); /* the number of read bits (tmpBits) */
301*e5436536SAndroid Build Coastguard Worker   numFillBits = (8 * sacHeaderLen) - numFillBits;
302*e5436536SAndroid Build Coastguard Worker   if (numFillBits < 0) {
303*e5436536SAndroid Build Coastguard Worker     /* Parsing went wrong */
304*e5436536SAndroid Build Coastguard Worker     err = MPS_PARSE_ERROR;
305*e5436536SAndroid Build Coastguard Worker   }
306*e5436536SAndroid Build Coastguard Worker   /* Move to the very end of the SSC */
307*e5436536SAndroid Build Coastguard Worker   FDKpushBiDirectional(bitstream, numFillBits);
308*e5436536SAndroid Build Coastguard Worker 
309*e5436536SAndroid Build Coastguard Worker   if ((err == MPS_OK) && sacTimeAlignFlag) {
310*e5436536SAndroid Build Coastguard Worker     /* not supported */
311*e5436536SAndroid Build Coastguard Worker     FDKreadBits(bitstream, 16);
312*e5436536SAndroid Build Coastguard Worker     err = MPS_UNSUPPORTED_CONFIG;
313*e5436536SAndroid Build Coastguard Worker   }
314*e5436536SAndroid Build Coastguard Worker 
315*e5436536SAndroid Build Coastguard Worker   /* Derive additional helper variables */
316*e5436536SAndroid Build Coastguard Worker   SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, (UPMIXTYPE)upmixType);
317*e5436536SAndroid Build Coastguard Worker 
318*e5436536SAndroid Build Coastguard Worker   return err;
319*e5436536SAndroid Build Coastguard Worker }
320*e5436536SAndroid Build Coastguard Worker 
SpatialDecParseMps212Config(HANDLE_FDK_BITSTREAM bitstream,SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig,int samplingRate,AUDIO_OBJECT_TYPE coreCodec,INT stereoConfigIndex,INT coreSbrFrameLengthIndex)321*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecParseMps212Config(
322*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream,
323*e5436536SAndroid Build Coastguard Worker     SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, int samplingRate,
324*e5436536SAndroid Build Coastguard Worker     AUDIO_OBJECT_TYPE coreCodec, INT stereoConfigIndex,
325*e5436536SAndroid Build Coastguard Worker     INT coreSbrFrameLengthIndex) {
326*e5436536SAndroid Build Coastguard Worker   int i;
327*e5436536SAndroid Build Coastguard Worker 
328*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pSpatialSpecificConfig, sizeof(SPATIAL_SPECIFIC_CONFIG));
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->stereoConfigIndex = stereoConfigIndex;
331*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->coreSbrFrameLengthIndex = coreSbrFrameLengthIndex;
332*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->freqRes =
333*e5436536SAndroid Build Coastguard Worker       (SPATIALDEC_FREQ_RES)freqResTable[FDKreadBits(bitstream, 3)];
334*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->freqRes == 0) {
335*e5436536SAndroid Build Coastguard Worker     return MPS_PARSE_ERROR; /* reserved value */
336*e5436536SAndroid Build Coastguard Worker   }
337*e5436536SAndroid Build Coastguard Worker 
338*e5436536SAndroid Build Coastguard Worker   switch (coreCodec) {
339*e5436536SAndroid Build Coastguard Worker     case AOT_DRM_USAC:
340*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsFixedGainDMX =
341*e5436536SAndroid Build Coastguard Worker           (SPATIALDEC_FIXED_GAINS)FDKreadBits(bitstream, 3);
342*e5436536SAndroid Build Coastguard Worker       /* tempShapeConfig = (bsTempShapeConfigDrm == 1) ? 3 : 0 */
343*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->tempShapeConfig =
344*e5436536SAndroid Build Coastguard Worker           (SPATIALDEC_TS_CONF)(FDKreadBits(bitstream, 1) * 3);
345*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->decorrConfig = (SPATIALDEC_DECORR_CONF)0;
346*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsDecorrType = 0;
347*e5436536SAndroid Build Coastguard Worker       break;
348*e5436536SAndroid Build Coastguard Worker     case AOT_USAC:
349*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsFixedGainDMX =
350*e5436536SAndroid Build Coastguard Worker           (SPATIALDEC_FIXED_GAINS)FDKreadBits(bitstream, 3);
351*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->tempShapeConfig =
352*e5436536SAndroid Build Coastguard Worker           (SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2);
353*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->decorrConfig =
354*e5436536SAndroid Build Coastguard Worker           (SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2);
355*e5436536SAndroid Build Coastguard Worker       if (pSpatialSpecificConfig->decorrConfig > 2) {
356*e5436536SAndroid Build Coastguard Worker         return MPS_PARSE_ERROR; /* reserved value */
357*e5436536SAndroid Build Coastguard Worker       }
358*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsDecorrType = 0;
359*e5436536SAndroid Build Coastguard Worker       break;
360*e5436536SAndroid Build Coastguard Worker     default:
361*e5436536SAndroid Build Coastguard Worker       return MPS_UNSUPPORTED_FORMAT;
362*e5436536SAndroid Build Coastguard Worker   }
363*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->nTimeSlots = (coreSbrFrameLengthIndex == 4) ? 64 : 32;
364*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bsHighRateMode = (UCHAR)FDKreadBits(bitstream, 1);
365*e5436536SAndroid Build Coastguard Worker 
366*e5436536SAndroid Build Coastguard Worker   {
367*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bsPhaseCoding = (UCHAR)FDKreadBits(bitstream, 1);
368*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bsOttBandsPhasePresent =
369*e5436536SAndroid Build Coastguard Worker         (UCHAR)FDKreadBits(bitstream, 1);
370*e5436536SAndroid Build Coastguard Worker     if (pSpatialSpecificConfig->bsOttBandsPhasePresent) {
371*e5436536SAndroid Build Coastguard Worker       if (MAX_PARAMETER_BANDS < (pSpatialSpecificConfig->bsOttBandsPhase =
372*e5436536SAndroid Build Coastguard Worker                                      FDKreadBits(bitstream, 5))) {
373*e5436536SAndroid Build Coastguard Worker         return MPS_PARSE_ERROR;
374*e5436536SAndroid Build Coastguard Worker       }
375*e5436536SAndroid Build Coastguard Worker     } else {
376*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsOttBandsPhase = 0;
377*e5436536SAndroid Build Coastguard Worker     }
378*e5436536SAndroid Build Coastguard Worker   }
379*e5436536SAndroid Build Coastguard Worker 
380*e5436536SAndroid Build Coastguard Worker   if (stereoConfigIndex > 1) { /* do residual coding */
381*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bResidualCoding = 1;
382*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->ResidualConfig->bResidualPresent = 1;
383*e5436536SAndroid Build Coastguard Worker     if (pSpatialSpecificConfig->freqRes <
384*e5436536SAndroid Build Coastguard Worker         (pSpatialSpecificConfig->ResidualConfig->nResidualBands =
385*e5436536SAndroid Build Coastguard Worker              FDKreadBits(bitstream, 5))) {
386*e5436536SAndroid Build Coastguard Worker       return MPS_PARSE_ERROR;
387*e5436536SAndroid Build Coastguard Worker     }
388*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bsOttBandsPhase =
389*e5436536SAndroid Build Coastguard Worker         fMax(pSpatialSpecificConfig->bsOttBandsPhase,
390*e5436536SAndroid Build Coastguard Worker              pSpatialSpecificConfig->ResidualConfig->nResidualBands);
391*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bsPseudoLr = (UCHAR)FDKreadBits(bitstream, 1);
392*e5436536SAndroid Build Coastguard Worker 
393*e5436536SAndroid Build Coastguard Worker     if (pSpatialSpecificConfig->bsPhaseCoding) {
394*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsPhaseCoding = 3;
395*e5436536SAndroid Build Coastguard Worker     }
396*e5436536SAndroid Build Coastguard Worker   } else {
397*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bResidualCoding = 0;
398*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->ResidualConfig->bResidualPresent = 0;
399*e5436536SAndroid Build Coastguard Worker   }
400*e5436536SAndroid Build Coastguard Worker 
401*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->tempShapeConfig == 2) {
402*e5436536SAndroid Build Coastguard Worker     switch (coreCodec) {
403*e5436536SAndroid Build Coastguard Worker       case AOT_USAC:
404*e5436536SAndroid Build Coastguard Worker         pSpatialSpecificConfig->envQuantMode = FDKreadBits(bitstream, 1);
405*e5436536SAndroid Build Coastguard Worker         break;
406*e5436536SAndroid Build Coastguard Worker       default: /* added to avoid compiler warning */
407*e5436536SAndroid Build Coastguard Worker         break; /* added to avoid compiler warning */
408*e5436536SAndroid Build Coastguard Worker     }
409*e5436536SAndroid Build Coastguard Worker   }
410*e5436536SAndroid Build Coastguard Worker 
411*e5436536SAndroid Build Coastguard Worker   /* Static parameters */
412*e5436536SAndroid Build Coastguard Worker 
413*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->samplingFreq =
414*e5436536SAndroid Build Coastguard Worker       samplingRate; /* wrong for stereoConfigIndex == 3 but value is unused */
415*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->treeConfig = SPATIALDEC_MODE_RSVD7;
416*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->nOttBoxes =
417*e5436536SAndroid Build Coastguard Worker       treePropertyTable[pSpatialSpecificConfig->treeConfig].numOttBoxes;
418*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->nInputChannels =
419*e5436536SAndroid Build Coastguard Worker       treePropertyTable[pSpatialSpecificConfig->treeConfig].numInputChannels;
420*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->nOutputChannels =
421*e5436536SAndroid Build Coastguard Worker       treePropertyTable[pSpatialSpecificConfig->treeConfig].numOutputChannels;
422*e5436536SAndroid Build Coastguard Worker 
423*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bArbitraryDownmix = 0;
424*e5436536SAndroid Build Coastguard Worker 
425*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
426*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->OttConfig[i].nOttBands = 0;
427*e5436536SAndroid Build Coastguard Worker   }
428*e5436536SAndroid Build Coastguard Worker 
429*e5436536SAndroid Build Coastguard Worker   if (coreCodec == AOT_DRM_USAC) {
430*e5436536SAndroid Build Coastguard Worker     /* MPS payload is MPEG conform -> no need for pseudo DRM AOT */
431*e5436536SAndroid Build Coastguard Worker     coreCodec = AOT_USAC;
432*e5436536SAndroid Build Coastguard Worker   }
433*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->coreCodec = coreCodec;
434*e5436536SAndroid Build Coastguard Worker 
435*e5436536SAndroid Build Coastguard Worker   /* Derive additional helper variables */
436*e5436536SAndroid Build Coastguard Worker   SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, UPMIXTYPE_NORMAL);
437*e5436536SAndroid Build Coastguard Worker 
438*e5436536SAndroid Build Coastguard Worker   return MPS_OK;
439*e5436536SAndroid Build Coastguard Worker }
440*e5436536SAndroid Build Coastguard Worker 
SpatialDecParseSpecificConfig(HANDLE_FDK_BITSTREAM bitstream,SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig,int sacHeaderLen,AUDIO_OBJECT_TYPE coreCodec)441*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecParseSpecificConfig(
442*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream,
443*e5436536SAndroid Build Coastguard Worker     SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, int sacHeaderLen,
444*e5436536SAndroid Build Coastguard Worker     AUDIO_OBJECT_TYPE coreCodec) {
445*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
446*e5436536SAndroid Build Coastguard Worker   int i;
447*e5436536SAndroid Build Coastguard Worker   int bsSamplingFreqIndex;
448*e5436536SAndroid Build Coastguard Worker   int bsFreqRes, b3DaudioMode = 0;
449*e5436536SAndroid Build Coastguard Worker   int numHeaderBits;
450*e5436536SAndroid Build Coastguard Worker   int cfgStartPos, bitsAvailable;
451*e5436536SAndroid Build Coastguard Worker 
452*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pSpatialSpecificConfig, sizeof(SPATIAL_SPECIFIC_CONFIG));
453*e5436536SAndroid Build Coastguard Worker 
454*e5436536SAndroid Build Coastguard Worker   cfgStartPos = FDKgetValidBits(bitstream);
455*e5436536SAndroid Build Coastguard Worker   /* It might be that we do not know the SSC length beforehand. */
456*e5436536SAndroid Build Coastguard Worker   if (sacHeaderLen == 0) {
457*e5436536SAndroid Build Coastguard Worker     bitsAvailable = cfgStartPos;
458*e5436536SAndroid Build Coastguard Worker   } else {
459*e5436536SAndroid Build Coastguard Worker     bitsAvailable = 8 * sacHeaderLen;
460*e5436536SAndroid Build Coastguard Worker     if (bitsAvailable > cfgStartPos) {
461*e5436536SAndroid Build Coastguard Worker       err = MPS_PARSE_ERROR;
462*e5436536SAndroid Build Coastguard Worker       goto bail;
463*e5436536SAndroid Build Coastguard Worker     }
464*e5436536SAndroid Build Coastguard Worker   }
465*e5436536SAndroid Build Coastguard Worker 
466*e5436536SAndroid Build Coastguard Worker   bsSamplingFreqIndex = FDKreadBits(bitstream, 4);
467*e5436536SAndroid Build Coastguard Worker 
468*e5436536SAndroid Build Coastguard Worker   if (bsSamplingFreqIndex == 15) {
469*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->samplingFreq = FDKreadBits(bitstream, 24);
470*e5436536SAndroid Build Coastguard Worker   } else {
471*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->samplingFreq =
472*e5436536SAndroid Build Coastguard Worker         samplingFreqTable[bsSamplingFreqIndex];
473*e5436536SAndroid Build Coastguard Worker     if (pSpatialSpecificConfig->samplingFreq == 0) {
474*e5436536SAndroid Build Coastguard Worker       err = MPS_PARSE_ERROR;
475*e5436536SAndroid Build Coastguard Worker       goto bail;
476*e5436536SAndroid Build Coastguard Worker     }
477*e5436536SAndroid Build Coastguard Worker   }
478*e5436536SAndroid Build Coastguard Worker 
479*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->nTimeSlots = FDKreadBits(bitstream, 5) + 1;
480*e5436536SAndroid Build Coastguard Worker   if ((pSpatialSpecificConfig->nTimeSlots < 1) ||
481*e5436536SAndroid Build Coastguard Worker       (pSpatialSpecificConfig->nTimeSlots > MAX_TIME_SLOTS)) {
482*e5436536SAndroid Build Coastguard Worker     err = MPS_PARSE_ERROR;
483*e5436536SAndroid Build Coastguard Worker     goto bail;
484*e5436536SAndroid Build Coastguard Worker   }
485*e5436536SAndroid Build Coastguard Worker 
486*e5436536SAndroid Build Coastguard Worker   bsFreqRes = FDKreadBits(bitstream, 3);
487*e5436536SAndroid Build Coastguard Worker 
488*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->freqRes =
489*e5436536SAndroid Build Coastguard Worker       (SPATIALDEC_FREQ_RES)freqResTable_LD[bsFreqRes];
490*e5436536SAndroid Build Coastguard Worker 
491*e5436536SAndroid Build Coastguard Worker   {
492*e5436536SAndroid Build Coastguard Worker     UINT treeConfig = FDKreadBits(bitstream, 4);
493*e5436536SAndroid Build Coastguard Worker 
494*e5436536SAndroid Build Coastguard Worker     switch (treeConfig) {
495*e5436536SAndroid Build Coastguard Worker       case SPATIALDEC_MODE_RSVD7:
496*e5436536SAndroid Build Coastguard Worker         pSpatialSpecificConfig->treeConfig = (SPATIALDEC_TREE_CONFIG)treeConfig;
497*e5436536SAndroid Build Coastguard Worker         break;
498*e5436536SAndroid Build Coastguard Worker       default:
499*e5436536SAndroid Build Coastguard Worker         err = MPS_UNSUPPORTED_CONFIG;
500*e5436536SAndroid Build Coastguard Worker         goto bail;
501*e5436536SAndroid Build Coastguard Worker     }
502*e5436536SAndroid Build Coastguard Worker   }
503*e5436536SAndroid Build Coastguard Worker 
504*e5436536SAndroid Build Coastguard Worker   {
505*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nOttBoxes =
506*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numOttBoxes;
507*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nTttBoxes =
508*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numTttBoxes;
509*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nInputChannels =
510*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numInputChannels;
511*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nOutputChannels =
512*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numOutputChannels;
513*e5436536SAndroid Build Coastguard Worker   }
514*e5436536SAndroid Build Coastguard Worker 
515*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->quantMode =
516*e5436536SAndroid Build Coastguard Worker       (SPATIALDEC_QUANT_MODE)FDKreadBits(bitstream, 2);
517*e5436536SAndroid Build Coastguard Worker 
518*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bArbitraryDownmix = FDKreadBits(bitstream, 1);
519*e5436536SAndroid Build Coastguard Worker 
520*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bsFixedGainDMX =
521*e5436536SAndroid Build Coastguard Worker       (SPATIALDEC_FIXED_GAINS)FDKreadBits(bitstream, 3);
522*e5436536SAndroid Build Coastguard Worker 
523*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->tempShapeConfig =
524*e5436536SAndroid Build Coastguard Worker       (SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2);
525*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->tempShapeConfig > 2) {
526*e5436536SAndroid Build Coastguard Worker     return MPS_PARSE_ERROR; /* reserved value */
527*e5436536SAndroid Build Coastguard Worker   }
528*e5436536SAndroid Build Coastguard Worker 
529*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->decorrConfig =
530*e5436536SAndroid Build Coastguard Worker       (SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2);
531*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->decorrConfig > 2) {
532*e5436536SAndroid Build Coastguard Worker     return MPS_PARSE_ERROR; /* reserved value */
533*e5436536SAndroid Build Coastguard Worker   }
534*e5436536SAndroid Build Coastguard Worker 
535*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
536*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->OttConfig[i].nOttBands = 0;
537*e5436536SAndroid Build Coastguard Worker   }
538*e5436536SAndroid Build Coastguard Worker 
539*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pSpatialSpecificConfig->nTttBoxes; i++) {
540*e5436536SAndroid Build Coastguard Worker     int bTttDualMode = FDKreadBits(bitstream, 1);
541*e5436536SAndroid Build Coastguard Worker     FDKreadBits(bitstream, 3); /* not supported */
542*e5436536SAndroid Build Coastguard Worker 
543*e5436536SAndroid Build Coastguard Worker     if (bTttDualMode) {
544*e5436536SAndroid Build Coastguard Worker       FDKreadBits(bitstream, 8); /* not supported */
545*e5436536SAndroid Build Coastguard Worker     }
546*e5436536SAndroid Build Coastguard Worker   }
547*e5436536SAndroid Build Coastguard Worker 
548*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->tempShapeConfig == 2) {
549*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->envQuantMode = FDKreadBits(bitstream, 1);
550*e5436536SAndroid Build Coastguard Worker   }
551*e5436536SAndroid Build Coastguard Worker 
552*e5436536SAndroid Build Coastguard Worker   if (b3DaudioMode) {
553*e5436536SAndroid Build Coastguard Worker     if (FDKreadBits(bitstream, 2) == 0) { /* b3DaudioHRTFset ? */
554*e5436536SAndroid Build Coastguard Worker       int hc;
555*e5436536SAndroid Build Coastguard Worker       int HRTFnumBand;
556*e5436536SAndroid Build Coastguard Worker       int HRTFfreqRes = FDKreadBits(bitstream, 3);
557*e5436536SAndroid Build Coastguard Worker       int HRTFnumChan = FDKreadBits(bitstream, 4);
558*e5436536SAndroid Build Coastguard Worker       int HRTFasymmetric = FDKreadBits(bitstream, 1);
559*e5436536SAndroid Build Coastguard Worker 
560*e5436536SAndroid Build Coastguard Worker       HRTFnumBand = freqResTable_LD[HRTFfreqRes];
561*e5436536SAndroid Build Coastguard Worker 
562*e5436536SAndroid Build Coastguard Worker       for (hc = 0; hc < HRTFnumChan; hc++) {
563*e5436536SAndroid Build Coastguard Worker         FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFlevelLeft[hc][hb] */
564*e5436536SAndroid Build Coastguard Worker         if (HRTFasymmetric) {
565*e5436536SAndroid Build Coastguard Worker           FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFlevelRight[hc][hb] */
566*e5436536SAndroid Build Coastguard Worker         }
567*e5436536SAndroid Build Coastguard Worker         if (FDKreadBits(bitstream, 1)) {          /* HRTFphase[hc] ? */
568*e5436536SAndroid Build Coastguard Worker           FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFphaseLR[hc][hb] */
569*e5436536SAndroid Build Coastguard Worker         }
570*e5436536SAndroid Build Coastguard Worker         if (FDKreadBits(bitstream, 1)) {          /* HRTFicc[hc] ? */
571*e5436536SAndroid Build Coastguard Worker           FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFiccLR[hc][hb] */
572*e5436536SAndroid Build Coastguard Worker         }
573*e5436536SAndroid Build Coastguard Worker       }
574*e5436536SAndroid Build Coastguard Worker     }
575*e5436536SAndroid Build Coastguard Worker   }
576*e5436536SAndroid Build Coastguard Worker 
577*e5436536SAndroid Build Coastguard Worker   FDKbyteAlign(bitstream,
578*e5436536SAndroid Build Coastguard Worker                cfgStartPos); /* ISO/IEC FDIS 23003-1: 5.2. ... byte alignment
579*e5436536SAndroid Build Coastguard Worker                                 with respect to the beginning of the syntactic
580*e5436536SAndroid Build Coastguard Worker                                 element in which ByteAlign() occurs. */
581*e5436536SAndroid Build Coastguard Worker 
582*e5436536SAndroid Build Coastguard Worker   numHeaderBits = cfgStartPos - (INT)FDKgetValidBits(bitstream);
583*e5436536SAndroid Build Coastguard Worker   bitsAvailable -= numHeaderBits;
584*e5436536SAndroid Build Coastguard Worker   if (bitsAvailable < 0) {
585*e5436536SAndroid Build Coastguard Worker     err = MPS_PARSE_ERROR;
586*e5436536SAndroid Build Coastguard Worker     goto bail;
587*e5436536SAndroid Build Coastguard Worker   }
588*e5436536SAndroid Build Coastguard Worker 
589*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->sacExtCnt = 0;
590*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bResidualCoding = 0;
591*e5436536SAndroid Build Coastguard Worker 
592*e5436536SAndroid Build Coastguard Worker   err = SpatialDecParseExtensionConfig(
593*e5436536SAndroid Build Coastguard Worker       bitstream, pSpatialSpecificConfig, pSpatialSpecificConfig->nOttBoxes,
594*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->nTttBoxes,
595*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->nOutputChannels, bitsAvailable);
596*e5436536SAndroid Build Coastguard Worker 
597*e5436536SAndroid Build Coastguard Worker   FDKbyteAlign(
598*e5436536SAndroid Build Coastguard Worker       bitstream,
599*e5436536SAndroid Build Coastguard Worker       cfgStartPos); /* Same alignment anchor as above because
600*e5436536SAndroid Build Coastguard Worker                        SpatialExtensionConfig() always reads full bytes */
601*e5436536SAndroid Build Coastguard Worker 
602*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->coreCodec = coreCodec;
603*e5436536SAndroid Build Coastguard Worker 
604*e5436536SAndroid Build Coastguard Worker   SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, UPMIXTYPE_NORMAL);
605*e5436536SAndroid Build Coastguard Worker 
606*e5436536SAndroid Build Coastguard Worker bail:
607*e5436536SAndroid Build Coastguard Worker   if (sacHeaderLen > 0) {
608*e5436536SAndroid Build Coastguard Worker     /* If the config is of known length then assure that the
609*e5436536SAndroid Build Coastguard Worker        bitbuffer is exactly at its end when leaving the function. */
610*e5436536SAndroid Build Coastguard Worker     FDKpushBiDirectional(
611*e5436536SAndroid Build Coastguard Worker         bitstream,
612*e5436536SAndroid Build Coastguard Worker         (sacHeaderLen * 8) - (cfgStartPos - (INT)FDKgetValidBits(bitstream)));
613*e5436536SAndroid Build Coastguard Worker   }
614*e5436536SAndroid Build Coastguard Worker 
615*e5436536SAndroid Build Coastguard Worker   return err;
616*e5436536SAndroid Build Coastguard Worker }
617*e5436536SAndroid Build Coastguard Worker 
SpatialDecDefaultSpecificConfig(SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig,AUDIO_OBJECT_TYPE coreCodec,int samplingFreq,int nTimeSlots,int sacDecoderLevel,int isBlind,int numCoreChannels)618*e5436536SAndroid Build Coastguard Worker int SpatialDecDefaultSpecificConfig(
619*e5436536SAndroid Build Coastguard Worker     SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
620*e5436536SAndroid Build Coastguard Worker     AUDIO_OBJECT_TYPE coreCodec, int samplingFreq, int nTimeSlots,
621*e5436536SAndroid Build Coastguard Worker     int sacDecoderLevel, int isBlind, int numCoreChannels)
622*e5436536SAndroid Build Coastguard Worker 
623*e5436536SAndroid Build Coastguard Worker {
624*e5436536SAndroid Build Coastguard Worker   int err = MPS_OK;
625*e5436536SAndroid Build Coastguard Worker   int i;
626*e5436536SAndroid Build Coastguard Worker 
627*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(coreCodec != AOT_NONE);
628*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(nTimeSlots > 0);
629*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(samplingFreq > 0);
630*e5436536SAndroid Build Coastguard Worker 
631*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->coreCodec = coreCodec;
632*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->samplingFreq = samplingFreq;
633*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->nTimeSlots = nTimeSlots;
634*e5436536SAndroid Build Coastguard Worker   if ((pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_ELD) ||
635*e5436536SAndroid Build Coastguard Worker       (pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_LD))
636*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->freqRes = SPATIALDEC_FREQ_RES_23;
637*e5436536SAndroid Build Coastguard Worker   else
638*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->freqRes = SPATIALDEC_FREQ_RES_28;
639*e5436536SAndroid Build Coastguard Worker 
640*e5436536SAndroid Build Coastguard Worker   {
641*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->treeConfig =
642*e5436536SAndroid Build Coastguard Worker         SPATIALDEC_MODE_RSVD7; /* 212  configuration */
643*e5436536SAndroid Build Coastguard Worker   }
644*e5436536SAndroid Build Coastguard Worker 
645*e5436536SAndroid Build Coastguard Worker   {
646*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nOttBoxes =
647*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numOttBoxes;
648*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nInputChannels =
649*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numInputChannels;
650*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->nOutputChannels =
651*e5436536SAndroid Build Coastguard Worker         treePropertyTable[pSpatialSpecificConfig->treeConfig].numOutputChannels;
652*e5436536SAndroid Build Coastguard Worker   }
653*e5436536SAndroid Build Coastguard Worker 
654*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->quantMode = SPATIALDEC_QUANT_FINE_DEF;
655*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bArbitraryDownmix = 0;
656*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->bResidualCoding = 0;
657*e5436536SAndroid Build Coastguard Worker   if ((pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_ELD) ||
658*e5436536SAndroid Build Coastguard Worker       (pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_LD))
659*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bsFixedGainDMX = SPATIALDEC_GAIN_RSVD2;
660*e5436536SAndroid Build Coastguard Worker   else
661*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->bsFixedGainDMX = SPATIALDEC_GAIN_MODE0;
662*e5436536SAndroid Build Coastguard Worker 
663*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->tempShapeConfig = SPATIALDEC_TS_TPNOWHITE;
664*e5436536SAndroid Build Coastguard Worker   pSpatialSpecificConfig->decorrConfig = SPATIALDEC_DECORR_MODE0;
665*e5436536SAndroid Build Coastguard Worker 
666*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
667*e5436536SAndroid Build Coastguard Worker     pSpatialSpecificConfig->OttConfig[i].nOttBands = 0;
668*e5436536SAndroid Build Coastguard Worker   }
669*e5436536SAndroid Build Coastguard Worker 
670*e5436536SAndroid Build Coastguard Worker   return err;
671*e5436536SAndroid Build Coastguard Worker }
672*e5436536SAndroid Build Coastguard Worker 
673*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
674*e5436536SAndroid Build Coastguard Worker  Functionname: coarse2fine
675*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
676*e5436536SAndroid Build Coastguard Worker 
677*e5436536SAndroid Build Coastguard Worker  Description:
678*e5436536SAndroid Build Coastguard Worker    Parameter index mapping from coarse to fine quantization
679*e5436536SAndroid Build Coastguard Worker 
680*e5436536SAndroid Build Coastguard Worker  Arguments:
681*e5436536SAndroid Build Coastguard Worker 
682*e5436536SAndroid Build Coastguard Worker Input:
683*e5436536SAndroid Build Coastguard Worker 
684*e5436536SAndroid Build Coastguard Worker Output:
685*e5436536SAndroid Build Coastguard Worker 
686*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
coarse2fine(SCHAR * data,DATA_TYPE dataType,int startBand,int numBands)687*e5436536SAndroid Build Coastguard Worker static void coarse2fine(SCHAR *data, DATA_TYPE dataType, int startBand,
688*e5436536SAndroid Build Coastguard Worker                         int numBands) {
689*e5436536SAndroid Build Coastguard Worker   int i;
690*e5436536SAndroid Build Coastguard Worker 
691*e5436536SAndroid Build Coastguard Worker   for (i = startBand; i < startBand + numBands; i++) {
692*e5436536SAndroid Build Coastguard Worker     data[i] <<= 1;
693*e5436536SAndroid Build Coastguard Worker   }
694*e5436536SAndroid Build Coastguard Worker 
695*e5436536SAndroid Build Coastguard Worker   if (dataType == t_CLD) {
696*e5436536SAndroid Build Coastguard Worker     for (i = startBand; i < startBand + numBands; i++) {
697*e5436536SAndroid Build Coastguard Worker       if (data[i] == -14)
698*e5436536SAndroid Build Coastguard Worker         data[i] = -15;
699*e5436536SAndroid Build Coastguard Worker       else if (data[i] == 14)
700*e5436536SAndroid Build Coastguard Worker         data[i] = 15;
701*e5436536SAndroid Build Coastguard Worker     }
702*e5436536SAndroid Build Coastguard Worker   }
703*e5436536SAndroid Build Coastguard Worker }
704*e5436536SAndroid Build Coastguard Worker 
705*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
706*e5436536SAndroid Build Coastguard Worker  Functionname: fine2coarse
707*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
708*e5436536SAndroid Build Coastguard Worker 
709*e5436536SAndroid Build Coastguard Worker  Description:
710*e5436536SAndroid Build Coastguard Worker    Parameter index mapping from fine to coarse quantization
711*e5436536SAndroid Build Coastguard Worker 
712*e5436536SAndroid Build Coastguard Worker  Arguments:
713*e5436536SAndroid Build Coastguard Worker 
714*e5436536SAndroid Build Coastguard Worker Input:
715*e5436536SAndroid Build Coastguard Worker 
716*e5436536SAndroid Build Coastguard Worker Output:
717*e5436536SAndroid Build Coastguard Worker 
718*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
fine2coarse(SCHAR * data,DATA_TYPE dataType,int startBand,int numBands)719*e5436536SAndroid Build Coastguard Worker static void fine2coarse(SCHAR *data, DATA_TYPE dataType, int startBand,
720*e5436536SAndroid Build Coastguard Worker                         int numBands) {
721*e5436536SAndroid Build Coastguard Worker   int i;
722*e5436536SAndroid Build Coastguard Worker 
723*e5436536SAndroid Build Coastguard Worker   for (i = startBand; i < startBand + numBands; i++) {
724*e5436536SAndroid Build Coastguard Worker     /* Note: the if cases below actually make a difference (negative values) */
725*e5436536SAndroid Build Coastguard Worker     if (dataType == t_CLD)
726*e5436536SAndroid Build Coastguard Worker       data[i] /= 2;
727*e5436536SAndroid Build Coastguard Worker     else
728*e5436536SAndroid Build Coastguard Worker       data[i] >>= 1;
729*e5436536SAndroid Build Coastguard Worker   }
730*e5436536SAndroid Build Coastguard Worker }
731*e5436536SAndroid Build Coastguard Worker 
732*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
733*e5436536SAndroid Build Coastguard Worker  Functionname: getStrideMap
734*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
735*e5436536SAndroid Build Coastguard Worker 
736*e5436536SAndroid Build Coastguard Worker  Description:
737*e5436536SAndroid Build Coastguard Worker    Index Mapping accroding to pbStrides
738*e5436536SAndroid Build Coastguard Worker 
739*e5436536SAndroid Build Coastguard Worker  Arguments:
740*e5436536SAndroid Build Coastguard Worker 
741*e5436536SAndroid Build Coastguard Worker Input:
742*e5436536SAndroid Build Coastguard Worker 
743*e5436536SAndroid Build Coastguard Worker Output:
744*e5436536SAndroid Build Coastguard Worker 
745*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
getStrideMap(int freqResStride,int startBand,int stopBand,int * aStrides)746*e5436536SAndroid Build Coastguard Worker static int getStrideMap(int freqResStride, int startBand, int stopBand,
747*e5436536SAndroid Build Coastguard Worker                         int *aStrides) {
748*e5436536SAndroid Build Coastguard Worker   int i, pb, pbStride, dataBands, strOffset;
749*e5436536SAndroid Build Coastguard Worker 
750*e5436536SAndroid Build Coastguard Worker   pbStride = pbStrideTable[freqResStride];
751*e5436536SAndroid Build Coastguard Worker   dataBands = (stopBand - startBand - 1) / pbStride + 1;
752*e5436536SAndroid Build Coastguard Worker 
753*e5436536SAndroid Build Coastguard Worker   aStrides[0] = startBand;
754*e5436536SAndroid Build Coastguard Worker   for (pb = 1; pb <= dataBands; pb++) {
755*e5436536SAndroid Build Coastguard Worker     aStrides[pb] = aStrides[pb - 1] + pbStride;
756*e5436536SAndroid Build Coastguard Worker   }
757*e5436536SAndroid Build Coastguard Worker   strOffset = 0;
758*e5436536SAndroid Build Coastguard Worker   while (aStrides[dataBands] > stopBand) {
759*e5436536SAndroid Build Coastguard Worker     if (strOffset < dataBands) strOffset++;
760*e5436536SAndroid Build Coastguard Worker     for (i = strOffset; i <= dataBands; i++) {
761*e5436536SAndroid Build Coastguard Worker       aStrides[i]--;
762*e5436536SAndroid Build Coastguard Worker     }
763*e5436536SAndroid Build Coastguard Worker   }
764*e5436536SAndroid Build Coastguard Worker 
765*e5436536SAndroid Build Coastguard Worker   return dataBands;
766*e5436536SAndroid Build Coastguard Worker }
767*e5436536SAndroid Build Coastguard Worker 
768*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
769*e5436536SAndroid Build Coastguard Worker  Functionname: ecDataDec
770*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
771*e5436536SAndroid Build Coastguard Worker 
772*e5436536SAndroid Build Coastguard Worker  Description:
773*e5436536SAndroid Build Coastguard Worker    Do delta decoding and dequantization
774*e5436536SAndroid Build Coastguard Worker 
775*e5436536SAndroid Build Coastguard Worker  Arguments:
776*e5436536SAndroid Build Coastguard Worker 
777*e5436536SAndroid Build Coastguard Worker Input:
778*e5436536SAndroid Build Coastguard Worker 
779*e5436536SAndroid Build Coastguard Worker Output:
780*e5436536SAndroid Build Coastguard Worker 
781*e5436536SAndroid Build Coastguard Worker 
782*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
783*e5436536SAndroid Build Coastguard Worker 
ecDataDec(const SPATIAL_BS_FRAME * frame,UINT syntaxFlags,HANDLE_FDK_BITSTREAM bitstream,LOSSLESSDATA * const llData,SCHAR (* data)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],SCHAR ** lastdata,int datatype,int boxIdx,int startBand,int stopBand,SCHAR defaultValue)784*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR ecDataDec(
785*e5436536SAndroid Build Coastguard Worker     const SPATIAL_BS_FRAME *frame, UINT syntaxFlags,
786*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream, LOSSLESSDATA *const llData,
787*e5436536SAndroid Build Coastguard Worker     SCHAR (*data)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS], SCHAR **lastdata,
788*e5436536SAndroid Build Coastguard Worker     int datatype, int boxIdx, int startBand, int stopBand, SCHAR defaultValue) {
789*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
790*e5436536SAndroid Build Coastguard Worker   int i, j, pb, dataSets, setIdx, bsDataPair, dataBands, oldQuantCoarseXXX;
791*e5436536SAndroid Build Coastguard Worker   INT aStrides[MAX_PARAMETER_BANDS + 1] = {0};
792*e5436536SAndroid Build Coastguard Worker 
793*e5436536SAndroid Build Coastguard Worker   dataSets = 0;
794*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < frame->numParameterSets; i++) {
795*e5436536SAndroid Build Coastguard Worker     llData->bsXXXDataMode[i] = (SCHAR)FDKreadBits(bitstream, 2);
796*e5436536SAndroid Build Coastguard Worker 
797*e5436536SAndroid Build Coastguard Worker     if ((frame->bsIndependencyFlag == 1) && (i == 0) &&
798*e5436536SAndroid Build Coastguard Worker         (llData->bsXXXDataMode[i] == 1 ||
799*e5436536SAndroid Build Coastguard Worker          llData->bsXXXDataMode[i] == 2)) { /* This check catches bitstreams
800*e5436536SAndroid Build Coastguard Worker                                               generated by older encoder that
801*e5436536SAndroid Build Coastguard Worker                                               cause trouble */
802*e5436536SAndroid Build Coastguard Worker       return MPS_PARSE_ERROR;
803*e5436536SAndroid Build Coastguard Worker     }
804*e5436536SAndroid Build Coastguard Worker     if ((i >= frame->numParameterSets - 1) &&
805*e5436536SAndroid Build Coastguard Worker         (llData->bsXXXDataMode[i] ==
806*e5436536SAndroid Build Coastguard Worker          2)) { /* The interpolation mode must not be active for the last
807*e5436536SAndroid Build Coastguard Worker                   parameter set */
808*e5436536SAndroid Build Coastguard Worker       return MPS_PARSE_ERROR;
809*e5436536SAndroid Build Coastguard Worker     }
810*e5436536SAndroid Build Coastguard Worker 
811*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 3) {
812*e5436536SAndroid Build Coastguard Worker       dataSets++;
813*e5436536SAndroid Build Coastguard Worker     }
814*e5436536SAndroid Build Coastguard Worker   }
815*e5436536SAndroid Build Coastguard Worker 
816*e5436536SAndroid Build Coastguard Worker   setIdx = 0;
817*e5436536SAndroid Build Coastguard Worker   bsDataPair = 0;
818*e5436536SAndroid Build Coastguard Worker   oldQuantCoarseXXX = llData->state->bsQuantCoarseXXXprevParse;
819*e5436536SAndroid Build Coastguard Worker 
820*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < frame->numParameterSets; i++) {
821*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 0) {
822*e5436536SAndroid Build Coastguard Worker       for (pb = startBand; pb < stopBand; pb++) {
823*e5436536SAndroid Build Coastguard Worker         lastdata[boxIdx][pb] = defaultValue;
824*e5436536SAndroid Build Coastguard Worker       }
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker       oldQuantCoarseXXX = 0;
827*e5436536SAndroid Build Coastguard Worker     }
828*e5436536SAndroid Build Coastguard Worker 
829*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 3) {
830*e5436536SAndroid Build Coastguard Worker       if (bsDataPair) {
831*e5436536SAndroid Build Coastguard Worker         bsDataPair = 0;
832*e5436536SAndroid Build Coastguard Worker       } else {
833*e5436536SAndroid Build Coastguard Worker         bsDataPair = FDKreadBits(bitstream, 1);
834*e5436536SAndroid Build Coastguard Worker         llData->bsQuantCoarseXXX[setIdx] = (UCHAR)FDKreadBits(bitstream, 1);
835*e5436536SAndroid Build Coastguard Worker         llData->bsFreqResStrideXXX[setIdx] = (UCHAR)FDKreadBits(bitstream, 2);
836*e5436536SAndroid Build Coastguard Worker 
837*e5436536SAndroid Build Coastguard Worker         if (llData->bsQuantCoarseXXX[setIdx] != oldQuantCoarseXXX) {
838*e5436536SAndroid Build Coastguard Worker           if (oldQuantCoarseXXX) {
839*e5436536SAndroid Build Coastguard Worker             coarse2fine(lastdata[boxIdx], (DATA_TYPE)datatype, startBand,
840*e5436536SAndroid Build Coastguard Worker                         stopBand - startBand);
841*e5436536SAndroid Build Coastguard Worker           } else {
842*e5436536SAndroid Build Coastguard Worker             fine2coarse(lastdata[boxIdx], (DATA_TYPE)datatype, startBand,
843*e5436536SAndroid Build Coastguard Worker                         stopBand - startBand);
844*e5436536SAndroid Build Coastguard Worker           }
845*e5436536SAndroid Build Coastguard Worker         }
846*e5436536SAndroid Build Coastguard Worker 
847*e5436536SAndroid Build Coastguard Worker         dataBands = getStrideMap(llData->bsFreqResStrideXXX[setIdx], startBand,
848*e5436536SAndroid Build Coastguard Worker                                  stopBand, aStrides);
849*e5436536SAndroid Build Coastguard Worker 
850*e5436536SAndroid Build Coastguard Worker         for (pb = 0; pb < dataBands; pb++) {
851*e5436536SAndroid Build Coastguard Worker           lastdata[boxIdx][startBand + pb] = lastdata[boxIdx][aStrides[pb]];
852*e5436536SAndroid Build Coastguard Worker         }
853*e5436536SAndroid Build Coastguard Worker 
854*e5436536SAndroid Build Coastguard Worker         if (boxIdx > MAX_NUM_OTT) return MPS_INVALID_BOXIDX;
855*e5436536SAndroid Build Coastguard Worker         if ((setIdx + bsDataPair) > MAX_PARAMETER_SETS)
856*e5436536SAndroid Build Coastguard Worker           return MPS_INVALID_SETIDX;
857*e5436536SAndroid Build Coastguard Worker 
858*e5436536SAndroid Build Coastguard Worker         /* DECODER_TYPE defined in FDK_tools */
859*e5436536SAndroid Build Coastguard Worker         DECODER_TYPE this_decoder_type = SAC_DECODER;
860*e5436536SAndroid Build Coastguard Worker         if (syntaxFlags & (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) {
861*e5436536SAndroid Build Coastguard Worker           this_decoder_type = USAC_DECODER;
862*e5436536SAndroid Build Coastguard Worker         } else if (syntaxFlags & SACDEC_SYNTAX_LD) {
863*e5436536SAndroid Build Coastguard Worker           this_decoder_type = SAOC_DECODER;
864*e5436536SAndroid Build Coastguard Worker         }
865*e5436536SAndroid Build Coastguard Worker 
866*e5436536SAndroid Build Coastguard Worker         err = (SACDEC_ERROR)EcDataPairDec(
867*e5436536SAndroid Build Coastguard Worker             this_decoder_type, bitstream, data[boxIdx][setIdx + 0],
868*e5436536SAndroid Build Coastguard Worker             data[boxIdx][setIdx + 1], lastdata[boxIdx], (DATA_TYPE)datatype,
869*e5436536SAndroid Build Coastguard Worker             startBand, dataBands, bsDataPair, llData->bsQuantCoarseXXX[setIdx],
870*e5436536SAndroid Build Coastguard Worker             !(frame->bsIndependencyFlag && (i == 0)) || (setIdx > 0));
871*e5436536SAndroid Build Coastguard Worker         if (err != MPS_OK) goto bail;
872*e5436536SAndroid Build Coastguard Worker 
873*e5436536SAndroid Build Coastguard Worker         if (datatype == t_IPD) {
874*e5436536SAndroid Build Coastguard Worker           const SCHAR mask = (llData->bsQuantCoarseXXX[setIdx]) ? 7 : 15;
875*e5436536SAndroid Build Coastguard Worker           for (pb = 0; pb < dataBands; pb++) {
876*e5436536SAndroid Build Coastguard Worker             for (j = aStrides[pb]; j < aStrides[pb + 1]; j++) {
877*e5436536SAndroid Build Coastguard Worker               lastdata[boxIdx][j] =
878*e5436536SAndroid Build Coastguard Worker                   data[boxIdx][setIdx + bsDataPair][startBand + pb] & mask;
879*e5436536SAndroid Build Coastguard Worker             }
880*e5436536SAndroid Build Coastguard Worker           }
881*e5436536SAndroid Build Coastguard Worker         } else {
882*e5436536SAndroid Build Coastguard Worker           for (pb = 0; pb < dataBands; pb++) {
883*e5436536SAndroid Build Coastguard Worker             for (j = aStrides[pb]; j < aStrides[pb + 1]; j++) {
884*e5436536SAndroid Build Coastguard Worker               lastdata[boxIdx][j] =
885*e5436536SAndroid Build Coastguard Worker                   data[boxIdx][setIdx + bsDataPair][startBand + pb];
886*e5436536SAndroid Build Coastguard Worker             }
887*e5436536SAndroid Build Coastguard Worker           }
888*e5436536SAndroid Build Coastguard Worker         }
889*e5436536SAndroid Build Coastguard Worker 
890*e5436536SAndroid Build Coastguard Worker         oldQuantCoarseXXX = llData->bsQuantCoarseXXX[setIdx];
891*e5436536SAndroid Build Coastguard Worker 
892*e5436536SAndroid Build Coastguard Worker         if (bsDataPair) {
893*e5436536SAndroid Build Coastguard Worker           llData->bsQuantCoarseXXX[setIdx + 1] =
894*e5436536SAndroid Build Coastguard Worker               llData->bsQuantCoarseXXX[setIdx];
895*e5436536SAndroid Build Coastguard Worker           llData->bsFreqResStrideXXX[setIdx + 1] =
896*e5436536SAndroid Build Coastguard Worker               llData->bsFreqResStrideXXX[setIdx];
897*e5436536SAndroid Build Coastguard Worker         }
898*e5436536SAndroid Build Coastguard Worker         setIdx += bsDataPair + 1;
899*e5436536SAndroid Build Coastguard Worker       } /* !bsDataPair */
900*e5436536SAndroid Build Coastguard Worker     }   /* llData->bsXXXDataMode[i] == 3 */
901*e5436536SAndroid Build Coastguard Worker   }
902*e5436536SAndroid Build Coastguard Worker 
903*e5436536SAndroid Build Coastguard Worker   llData->state->bsQuantCoarseXXXprevParse = oldQuantCoarseXXX;
904*e5436536SAndroid Build Coastguard Worker 
905*e5436536SAndroid Build Coastguard Worker bail:
906*e5436536SAndroid Build Coastguard Worker   return err;
907*e5436536SAndroid Build Coastguard Worker }
908*e5436536SAndroid Build Coastguard Worker 
909*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
910*e5436536SAndroid Build Coastguard Worker  Functionname: parseArbitraryDownmixData
911*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
912*e5436536SAndroid Build Coastguard Worker 
913*e5436536SAndroid Build Coastguard Worker  Description:
914*e5436536SAndroid Build Coastguard Worker 
915*e5436536SAndroid Build Coastguard Worker  Arguments:
916*e5436536SAndroid Build Coastguard Worker 
917*e5436536SAndroid Build Coastguard Worker  Return:
918*e5436536SAndroid Build Coastguard Worker 
919*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
parseArbitraryDownmixData(spatialDec * self,const SPATIAL_SPECIFIC_CONFIG * pSSC,const UINT syntaxFlags,const SPATIAL_BS_FRAME * frame,HANDLE_FDK_BITSTREAM bitstream)920*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR parseArbitraryDownmixData(
921*e5436536SAndroid Build Coastguard Worker     spatialDec *self, const SPATIAL_SPECIFIC_CONFIG *pSSC,
922*e5436536SAndroid Build Coastguard Worker     const UINT syntaxFlags, const SPATIAL_BS_FRAME *frame,
923*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream) {
924*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
925*e5436536SAndroid Build Coastguard Worker   int ch;
926*e5436536SAndroid Build Coastguard Worker   int offset = pSSC->nOttBoxes;
927*e5436536SAndroid Build Coastguard Worker 
928*e5436536SAndroid Build Coastguard Worker   /* CLD (arbitrary down-mix gains) */
929*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < pSSC->nInputChannels; ch++) {
930*e5436536SAndroid Build Coastguard Worker     err = ecDataDec(frame, syntaxFlags, bitstream,
931*e5436536SAndroid Build Coastguard Worker                     &frame->CLDLosslessData[offset + ch],
932*e5436536SAndroid Build Coastguard Worker                     frame->cmpArbdmxGainIdx, self->cmpArbdmxGainIdxPrev, t_CLD,
933*e5436536SAndroid Build Coastguard Worker                     ch, 0, pSSC->freqRes, arbdmxGainDefault);
934*e5436536SAndroid Build Coastguard Worker     if (err != MPS_OK) return err;
935*e5436536SAndroid Build Coastguard Worker   }
936*e5436536SAndroid Build Coastguard Worker 
937*e5436536SAndroid Build Coastguard Worker   return err;
938*e5436536SAndroid Build Coastguard Worker 
939*e5436536SAndroid Build Coastguard Worker } /* parseArbitraryDownmixData */
940*e5436536SAndroid Build Coastguard Worker 
941*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
942*e5436536SAndroid Build Coastguard Worker  Functionname: SpatialDecParseFrame
943*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
944*e5436536SAndroid Build Coastguard Worker 
945*e5436536SAndroid Build Coastguard Worker  Description:
946*e5436536SAndroid Build Coastguard Worker 
947*e5436536SAndroid Build Coastguard Worker  Arguments:
948*e5436536SAndroid Build Coastguard Worker 
949*e5436536SAndroid Build Coastguard Worker  Input:
950*e5436536SAndroid Build Coastguard Worker 
951*e5436536SAndroid Build Coastguard Worker  Output:
952*e5436536SAndroid Build Coastguard Worker 
953*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
954*e5436536SAndroid Build Coastguard Worker 
nBitsParamSlot(int i)955*e5436536SAndroid Build Coastguard Worker static int nBitsParamSlot(int i) {
956*e5436536SAndroid Build Coastguard Worker   int bitsParamSlot;
957*e5436536SAndroid Build Coastguard Worker 
958*e5436536SAndroid Build Coastguard Worker   bitsParamSlot = fMax(0, DFRACT_BITS - 1 - fNormz((FIXP_DBL)i));
959*e5436536SAndroid Build Coastguard Worker   if ((1 << bitsParamSlot) < i) {
960*e5436536SAndroid Build Coastguard Worker     bitsParamSlot++;
961*e5436536SAndroid Build Coastguard Worker   }
962*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT((bitsParamSlot >= 0) && (bitsParamSlot <= 32));
963*e5436536SAndroid Build Coastguard Worker 
964*e5436536SAndroid Build Coastguard Worker   return bitsParamSlot;
965*e5436536SAndroid Build Coastguard Worker }
966*e5436536SAndroid Build Coastguard Worker 
SpatialDecParseFrameData(spatialDec_struct * self,SPATIAL_BS_FRAME * frame,HANDLE_FDK_BITSTREAM bitstream,const SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig,UPMIXTYPE upmixType,int fGlobalIndependencyFlag)967*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecParseFrameData(
968*e5436536SAndroid Build Coastguard Worker     spatialDec_struct *self, SPATIAL_BS_FRAME *frame,
969*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bitstream,
970*e5436536SAndroid Build Coastguard Worker     const SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, UPMIXTYPE upmixType,
971*e5436536SAndroid Build Coastguard Worker     int fGlobalIndependencyFlag) {
972*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
973*e5436536SAndroid Build Coastguard Worker   int bsFramingType, dataBands, ps, pg, i;
974*e5436536SAndroid Build Coastguard Worker   int pb;
975*e5436536SAndroid Build Coastguard Worker   int numTempShapeChan = 0;
976*e5436536SAndroid Build Coastguard Worker   int bsNumOutputChannels =
977*e5436536SAndroid Build Coastguard Worker       treePropertyTable[pSpatialSpecificConfig->treeConfig]
978*e5436536SAndroid Build Coastguard Worker           .numOutputChannels; /* CAUTION: Maybe different to
979*e5436536SAndroid Build Coastguard Worker                                  pSpatialSpecificConfig->treeConfig in some
980*e5436536SAndroid Build Coastguard Worker                                  modes! */
981*e5436536SAndroid Build Coastguard Worker   int paramSetErr = 0;
982*e5436536SAndroid Build Coastguard Worker   UINT alignAnchor = FDKgetValidBits(
983*e5436536SAndroid Build Coastguard Worker       bitstream); /* Anchor for ByteAlign() function. See comment below. */
984*e5436536SAndroid Build Coastguard Worker   UINT syntaxFlags;
985*e5436536SAndroid Build Coastguard Worker 
986*e5436536SAndroid Build Coastguard Worker   syntaxFlags = pSpatialSpecificConfig->syntaxFlags;
987*e5436536SAndroid Build Coastguard Worker 
988*e5436536SAndroid Build Coastguard Worker   if ((syntaxFlags & (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
989*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->bsHighRateMode == 0) {
990*e5436536SAndroid Build Coastguard Worker     bsFramingType = 0; /* fixed framing */
991*e5436536SAndroid Build Coastguard Worker     frame->numParameterSets = 1;
992*e5436536SAndroid Build Coastguard Worker   } else {
993*e5436536SAndroid Build Coastguard Worker     bsFramingType = FDKreadBits(bitstream, 1);
994*e5436536SAndroid Build Coastguard Worker     if (syntaxFlags & SACDEC_SYNTAX_LD)
995*e5436536SAndroid Build Coastguard Worker       frame->numParameterSets = FDKreadBits(bitstream, 1) + 1;
996*e5436536SAndroid Build Coastguard Worker     else
997*e5436536SAndroid Build Coastguard Worker       frame->numParameterSets = FDKreadBits(bitstream, 3) + 1;
998*e5436536SAndroid Build Coastguard Worker   }
999*e5436536SAndroid Build Coastguard Worker 
1000*e5436536SAndroid Build Coastguard Worker   /* Any error after this line shall trigger parameter invalidation at bail
1001*e5436536SAndroid Build Coastguard Worker    * label. */
1002*e5436536SAndroid Build Coastguard Worker   paramSetErr = 1;
1003*e5436536SAndroid Build Coastguard Worker 
1004*e5436536SAndroid Build Coastguard Worker   if (frame->numParameterSets >= MAX_PARAMETER_SETS) {
1005*e5436536SAndroid Build Coastguard Worker     goto bail;
1006*e5436536SAndroid Build Coastguard Worker   }
1007*e5436536SAndroid Build Coastguard Worker 
1008*e5436536SAndroid Build Coastguard Worker   /* Basic config check. */
1009*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->nInputChannels <= 0 ||
1010*e5436536SAndroid Build Coastguard Worker       pSpatialSpecificConfig->nOutputChannels <= 0) {
1011*e5436536SAndroid Build Coastguard Worker     err = MPS_UNSUPPORTED_CONFIG;
1012*e5436536SAndroid Build Coastguard Worker     goto bail;
1013*e5436536SAndroid Build Coastguard Worker   }
1014*e5436536SAndroid Build Coastguard Worker 
1015*e5436536SAndroid Build Coastguard Worker   if (bsFramingType) {
1016*e5436536SAndroid Build Coastguard Worker     int prevParamSlot = -1;
1017*e5436536SAndroid Build Coastguard Worker     int bitsParamSlot;
1018*e5436536SAndroid Build Coastguard Worker 
1019*e5436536SAndroid Build Coastguard Worker     {
1020*e5436536SAndroid Build Coastguard Worker       bitsParamSlot = nBitsParamSlot(pSpatialSpecificConfig->nTimeSlots);
1021*e5436536SAndroid Build Coastguard Worker 
1022*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < frame->numParameterSets; i++) {
1023*e5436536SAndroid Build Coastguard Worker         frame->paramSlot[i] = FDKreadBits(bitstream, bitsParamSlot);
1024*e5436536SAndroid Build Coastguard Worker         /* Sanity check */
1025*e5436536SAndroid Build Coastguard Worker         if ((frame->paramSlot[i] <= prevParamSlot) ||
1026*e5436536SAndroid Build Coastguard Worker             (frame->paramSlot[i] >= pSpatialSpecificConfig->nTimeSlots)) {
1027*e5436536SAndroid Build Coastguard Worker           err = MPS_PARSE_ERROR;
1028*e5436536SAndroid Build Coastguard Worker           goto bail;
1029*e5436536SAndroid Build Coastguard Worker         }
1030*e5436536SAndroid Build Coastguard Worker         prevParamSlot = frame->paramSlot[i];
1031*e5436536SAndroid Build Coastguard Worker       }
1032*e5436536SAndroid Build Coastguard Worker     }
1033*e5436536SAndroid Build Coastguard Worker   } else {
1034*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < frame->numParameterSets; i++) {
1035*e5436536SAndroid Build Coastguard Worker       frame->paramSlot[i] = ((pSpatialSpecificConfig->nTimeSlots * (i + 1)) /
1036*e5436536SAndroid Build Coastguard Worker                              frame->numParameterSets) -
1037*e5436536SAndroid Build Coastguard Worker                             1;
1038*e5436536SAndroid Build Coastguard Worker     }
1039*e5436536SAndroid Build Coastguard Worker   }
1040*e5436536SAndroid Build Coastguard Worker 
1041*e5436536SAndroid Build Coastguard Worker   if ((syntaxFlags & (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
1042*e5436536SAndroid Build Coastguard Worker       fGlobalIndependencyFlag) {
1043*e5436536SAndroid Build Coastguard Worker     frame->bsIndependencyFlag = 1;
1044*e5436536SAndroid Build Coastguard Worker   } else {
1045*e5436536SAndroid Build Coastguard Worker     frame->bsIndependencyFlag = (UCHAR)FDKreadBits(bitstream, 1);
1046*e5436536SAndroid Build Coastguard Worker   }
1047*e5436536SAndroid Build Coastguard Worker 
1048*e5436536SAndroid Build Coastguard Worker   /*
1049*e5436536SAndroid Build Coastguard Worker    * OttData()
1050*e5436536SAndroid Build Coastguard Worker    */
1051*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
1052*e5436536SAndroid Build Coastguard Worker     err = ecDataDec(frame, syntaxFlags, bitstream, &frame->CLDLosslessData[i],
1053*e5436536SAndroid Build Coastguard Worker                     frame->cmpOttCLDidx, self->cmpOttCLDidxPrev, t_CLD, i, 0,
1054*e5436536SAndroid Build Coastguard Worker                     pSpatialSpecificConfig->bitstreamOttBands[i],
1055*e5436536SAndroid Build Coastguard Worker                     pSpatialSpecificConfig->ottCLDdefault[i]);
1056*e5436536SAndroid Build Coastguard Worker     if (err != MPS_OK) {
1057*e5436536SAndroid Build Coastguard Worker       goto bail;
1058*e5436536SAndroid Build Coastguard Worker     }
1059*e5436536SAndroid Build Coastguard Worker   } /* i < numOttBoxes */
1060*e5436536SAndroid Build Coastguard Worker 
1061*e5436536SAndroid Build Coastguard Worker   {
1062*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
1063*e5436536SAndroid Build Coastguard Worker       err = ecDataDec(frame, syntaxFlags, bitstream, &frame->ICCLosslessData[i],
1064*e5436536SAndroid Build Coastguard Worker                       frame->cmpOttICCidx, self->cmpOttICCidxPrev, t_ICC, i, 0,
1065*e5436536SAndroid Build Coastguard Worker                       pSpatialSpecificConfig->bitstreamOttBands[i], ICCdefault);
1066*e5436536SAndroid Build Coastguard Worker       if (err != MPS_OK) {
1067*e5436536SAndroid Build Coastguard Worker         goto bail;
1068*e5436536SAndroid Build Coastguard Worker       }
1069*e5436536SAndroid Build Coastguard Worker     } /* i < numOttBoxes */
1070*e5436536SAndroid Build Coastguard Worker   }   /* !oneICC */
1071*e5436536SAndroid Build Coastguard Worker 
1072*e5436536SAndroid Build Coastguard Worker   if ((pSpatialSpecificConfig->treeConfig == SPATIALDEC_MODE_RSVD7) &&
1073*e5436536SAndroid Build Coastguard Worker       (pSpatialSpecificConfig->bsPhaseCoding)) {
1074*e5436536SAndroid Build Coastguard Worker     frame->phaseMode = FDKreadBits(bitstream, 1);
1075*e5436536SAndroid Build Coastguard Worker 
1076*e5436536SAndroid Build Coastguard Worker     if (frame->phaseMode == 0) {
1077*e5436536SAndroid Build Coastguard Worker       for (pb = 0; pb < pSpatialSpecificConfig->numOttBandsIPD; pb++) {
1078*e5436536SAndroid Build Coastguard Worker         self->cmpOttIPDidxPrev[0][pb] = 0;
1079*e5436536SAndroid Build Coastguard Worker         for (i = 0; i < frame->numParameterSets; i++) {
1080*e5436536SAndroid Build Coastguard Worker           frame->cmpOttIPDidx[0][i][pb] = 0;
1081*e5436536SAndroid Build Coastguard Worker           // frame->ottIPDidx[0][i][pb] = 0;
1082*e5436536SAndroid Build Coastguard Worker         }
1083*e5436536SAndroid Build Coastguard Worker         /* self->ottIPDidxPrev[0][pb] = 0; */
1084*e5436536SAndroid Build Coastguard Worker       }
1085*e5436536SAndroid Build Coastguard Worker       frame->OpdSmoothingMode = 0;
1086*e5436536SAndroid Build Coastguard Worker     } else {
1087*e5436536SAndroid Build Coastguard Worker       frame->OpdSmoothingMode = FDKreadBits(bitstream, 1);
1088*e5436536SAndroid Build Coastguard Worker       err = ecDataDec(frame, syntaxFlags, bitstream, &frame->IPDLosslessData[0],
1089*e5436536SAndroid Build Coastguard Worker                       frame->cmpOttIPDidx, self->cmpOttIPDidxPrev, t_IPD, 0, 0,
1090*e5436536SAndroid Build Coastguard Worker                       pSpatialSpecificConfig->numOttBandsIPD, IPDdefault);
1091*e5436536SAndroid Build Coastguard Worker       if (err != MPS_OK) {
1092*e5436536SAndroid Build Coastguard Worker         goto bail;
1093*e5436536SAndroid Build Coastguard Worker       }
1094*e5436536SAndroid Build Coastguard Worker     }
1095*e5436536SAndroid Build Coastguard Worker   }
1096*e5436536SAndroid Build Coastguard Worker 
1097*e5436536SAndroid Build Coastguard Worker   /*
1098*e5436536SAndroid Build Coastguard Worker    * SmgData()
1099*e5436536SAndroid Build Coastguard Worker    */
1100*e5436536SAndroid Build Coastguard Worker 
1101*e5436536SAndroid Build Coastguard Worker   {
1102*e5436536SAndroid Build Coastguard Worker     if (!pSpatialSpecificConfig->bsHighRateMode &&
1103*e5436536SAndroid Build Coastguard Worker         (syntaxFlags & SACDEC_SYNTAX_USAC)) {
1104*e5436536SAndroid Build Coastguard Worker       for (ps = 0; ps < frame->numParameterSets; ps++) {
1105*e5436536SAndroid Build Coastguard Worker         frame->bsSmoothMode[ps] = 0;
1106*e5436536SAndroid Build Coastguard Worker       }
1107*e5436536SAndroid Build Coastguard Worker     } else {
1108*e5436536SAndroid Build Coastguard Worker       for (ps = 0; ps < frame->numParameterSets; ps++) {
1109*e5436536SAndroid Build Coastguard Worker         frame->bsSmoothMode[ps] = (UCHAR)FDKreadBits(bitstream, 2);
1110*e5436536SAndroid Build Coastguard Worker         if (frame->bsSmoothMode[ps] >= 2) {
1111*e5436536SAndroid Build Coastguard Worker           frame->bsSmoothTime[ps] = (UCHAR)FDKreadBits(bitstream, 2);
1112*e5436536SAndroid Build Coastguard Worker         }
1113*e5436536SAndroid Build Coastguard Worker         if (frame->bsSmoothMode[ps] == 3) {
1114*e5436536SAndroid Build Coastguard Worker           frame->bsFreqResStrideSmg[ps] = (UCHAR)FDKreadBits(bitstream, 2);
1115*e5436536SAndroid Build Coastguard Worker           dataBands = (pSpatialSpecificConfig->freqRes - 1) /
1116*e5436536SAndroid Build Coastguard Worker                           pbStrideTable[frame->bsFreqResStrideSmg[ps]] +
1117*e5436536SAndroid Build Coastguard Worker                       1;
1118*e5436536SAndroid Build Coastguard Worker           for (pg = 0; pg < dataBands; pg++) {
1119*e5436536SAndroid Build Coastguard Worker             frame->bsSmgData[ps][pg] = (UCHAR)FDKreadBits(bitstream, 1);
1120*e5436536SAndroid Build Coastguard Worker           }
1121*e5436536SAndroid Build Coastguard Worker         }
1122*e5436536SAndroid Build Coastguard Worker       } /* ps < numParameterSets */
1123*e5436536SAndroid Build Coastguard Worker     }
1124*e5436536SAndroid Build Coastguard Worker   }
1125*e5436536SAndroid Build Coastguard Worker 
1126*e5436536SAndroid Build Coastguard Worker   /*
1127*e5436536SAndroid Build Coastguard Worker    * TempShapeData()
1128*e5436536SAndroid Build Coastguard Worker    */
1129*e5436536SAndroid Build Coastguard Worker   if ((pSpatialSpecificConfig->tempShapeConfig == 3) &&
1130*e5436536SAndroid Build Coastguard Worker       (syntaxFlags & SACDEC_SYNTAX_USAC)) {
1131*e5436536SAndroid Build Coastguard Worker     int TsdErr;
1132*e5436536SAndroid Build Coastguard Worker     TsdErr = TsdRead(bitstream, pSpatialSpecificConfig->nTimeSlots,
1133*e5436536SAndroid Build Coastguard Worker                      &frame->TsdData[0]);
1134*e5436536SAndroid Build Coastguard Worker     if (TsdErr) {
1135*e5436536SAndroid Build Coastguard Worker       err = MPS_PARSE_ERROR;
1136*e5436536SAndroid Build Coastguard Worker       goto bail;
1137*e5436536SAndroid Build Coastguard Worker     }
1138*e5436536SAndroid Build Coastguard Worker   } else {
1139*e5436536SAndroid Build Coastguard Worker     frame->TsdData[0].bsTsdEnable = 0;
1140*e5436536SAndroid Build Coastguard Worker   }
1141*e5436536SAndroid Build Coastguard Worker 
1142*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < bsNumOutputChannels; i++) {
1143*e5436536SAndroid Build Coastguard Worker     frame->tempShapeEnableChannelSTP[i] = 0;
1144*e5436536SAndroid Build Coastguard Worker     frame->tempShapeEnableChannelGES[i] = 0;
1145*e5436536SAndroid Build Coastguard Worker   }
1146*e5436536SAndroid Build Coastguard Worker 
1147*e5436536SAndroid Build Coastguard Worker   if ((pSpatialSpecificConfig->tempShapeConfig == 1) ||
1148*e5436536SAndroid Build Coastguard Worker       (pSpatialSpecificConfig->tempShapeConfig == 2)) {
1149*e5436536SAndroid Build Coastguard Worker     int bsTempShapeEnable = FDKreadBits(bitstream, 1);
1150*e5436536SAndroid Build Coastguard Worker     if (bsTempShapeEnable) {
1151*e5436536SAndroid Build Coastguard Worker       numTempShapeChan =
1152*e5436536SAndroid Build Coastguard Worker           tempShapeChanTable[pSpatialSpecificConfig->tempShapeConfig - 1]
1153*e5436536SAndroid Build Coastguard Worker                             [pSpatialSpecificConfig->treeConfig];
1154*e5436536SAndroid Build Coastguard Worker       switch (pSpatialSpecificConfig->tempShapeConfig) {
1155*e5436536SAndroid Build Coastguard Worker         case 1: /* STP */
1156*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < numTempShapeChan; i++) {
1157*e5436536SAndroid Build Coastguard Worker             int stpEnable = FDKreadBits(bitstream, 1);
1158*e5436536SAndroid Build Coastguard Worker             frame->tempShapeEnableChannelSTP[i] = stpEnable;
1159*e5436536SAndroid Build Coastguard Worker           }
1160*e5436536SAndroid Build Coastguard Worker           break;
1161*e5436536SAndroid Build Coastguard Worker         case 2: /* GES */
1162*e5436536SAndroid Build Coastguard Worker         {
1163*e5436536SAndroid Build Coastguard Worker           UCHAR gesChannelEnable[MAX_OUTPUT_CHANNELS];
1164*e5436536SAndroid Build Coastguard Worker 
1165*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < numTempShapeChan; i++) {
1166*e5436536SAndroid Build Coastguard Worker             gesChannelEnable[i] = (UCHAR)FDKreadBits(bitstream, 1);
1167*e5436536SAndroid Build Coastguard Worker             frame->tempShapeEnableChannelGES[i] = gesChannelEnable[i];
1168*e5436536SAndroid Build Coastguard Worker           }
1169*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < numTempShapeChan; i++) {
1170*e5436536SAndroid Build Coastguard Worker             if (gesChannelEnable[i]) {
1171*e5436536SAndroid Build Coastguard Worker               int envShapeData_tmp[MAX_TIME_SLOTS];
1172*e5436536SAndroid Build Coastguard Worker               if (huff_dec_reshape(bitstream, envShapeData_tmp,
1173*e5436536SAndroid Build Coastguard Worker                                    pSpatialSpecificConfig->nTimeSlots) != 0) {
1174*e5436536SAndroid Build Coastguard Worker                 err = MPS_PARSE_ERROR;
1175*e5436536SAndroid Build Coastguard Worker                 goto bail;
1176*e5436536SAndroid Build Coastguard Worker               }
1177*e5436536SAndroid Build Coastguard Worker               for (int ts = 0; ts < pSpatialSpecificConfig->nTimeSlots; ts++) {
1178*e5436536SAndroid Build Coastguard Worker                 if (!(envShapeData_tmp[ts] >= 0) &&
1179*e5436536SAndroid Build Coastguard Worker                     (envShapeData_tmp[ts] <= 4)) {
1180*e5436536SAndroid Build Coastguard Worker                   err = MPS_PARSE_ERROR;
1181*e5436536SAndroid Build Coastguard Worker                   goto bail;
1182*e5436536SAndroid Build Coastguard Worker                 }
1183*e5436536SAndroid Build Coastguard Worker                 frame->bsEnvShapeData[i][ts] = (UCHAR)envShapeData_tmp[ts];
1184*e5436536SAndroid Build Coastguard Worker               }
1185*e5436536SAndroid Build Coastguard Worker             }
1186*e5436536SAndroid Build Coastguard Worker           }
1187*e5436536SAndroid Build Coastguard Worker         } break;
1188*e5436536SAndroid Build Coastguard Worker         default:
1189*e5436536SAndroid Build Coastguard Worker           err = MPS_INVALID_TEMPSHAPE;
1190*e5436536SAndroid Build Coastguard Worker           goto bail;
1191*e5436536SAndroid Build Coastguard Worker       }
1192*e5436536SAndroid Build Coastguard Worker     } /* bsTempShapeEnable */
1193*e5436536SAndroid Build Coastguard Worker   }   /* pSpatialSpecificConfig->tempShapeConfig != 0 */
1194*e5436536SAndroid Build Coastguard Worker 
1195*e5436536SAndroid Build Coastguard Worker   if (pSpatialSpecificConfig->bArbitraryDownmix != 0) {
1196*e5436536SAndroid Build Coastguard Worker     err = parseArbitraryDownmixData(self, pSpatialSpecificConfig, syntaxFlags,
1197*e5436536SAndroid Build Coastguard Worker                                     frame, bitstream);
1198*e5436536SAndroid Build Coastguard Worker     if (err != MPS_OK) goto bail;
1199*e5436536SAndroid Build Coastguard Worker   }
1200*e5436536SAndroid Build Coastguard Worker 
1201*e5436536SAndroid Build Coastguard Worker   if (1 && (!(syntaxFlags & (SACDEC_SYNTAX_USAC)))) {
1202*e5436536SAndroid Build Coastguard Worker     FDKbyteAlign(bitstream,
1203*e5436536SAndroid Build Coastguard Worker                  alignAnchor); /* ISO/IEC FDIS 23003-1: 5.2. ... byte alignment
1204*e5436536SAndroid Build Coastguard Worker                                   with respect to the beginning of the syntactic
1205*e5436536SAndroid Build Coastguard Worker                                   element in which ByteAlign() occurs. */
1206*e5436536SAndroid Build Coastguard Worker   }
1207*e5436536SAndroid Build Coastguard Worker 
1208*e5436536SAndroid Build Coastguard Worker bail:
1209*e5436536SAndroid Build Coastguard Worker   if (err != MPS_OK && paramSetErr != 0) {
1210*e5436536SAndroid Build Coastguard Worker     /* Since the parameter set data has already been written to the instance we
1211*e5436536SAndroid Build Coastguard Worker      * need to ... */
1212*e5436536SAndroid Build Coastguard Worker     frame->numParameterSets = 0; /* ... signal that it is corrupt ... */
1213*e5436536SAndroid Build Coastguard Worker   }
1214*e5436536SAndroid Build Coastguard Worker 
1215*e5436536SAndroid Build Coastguard Worker   return err;
1216*e5436536SAndroid Build Coastguard Worker 
1217*e5436536SAndroid Build Coastguard Worker } /* SpatialDecParseFrame */
1218*e5436536SAndroid Build Coastguard Worker 
1219*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1220*e5436536SAndroid Build Coastguard Worker  Functionname: createMapping
1221*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1222*e5436536SAndroid Build Coastguard Worker 
1223*e5436536SAndroid Build Coastguard Worker  Description:
1224*e5436536SAndroid Build Coastguard Worker 
1225*e5436536SAndroid Build Coastguard Worker  Arguments:
1226*e5436536SAndroid Build Coastguard Worker 
1227*e5436536SAndroid Build Coastguard Worker  Return:
1228*e5436536SAndroid Build Coastguard Worker 
1229*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
createMapping(int aMap[MAX_PARAMETER_BANDS+1],int startBand,int stopBand,int stride)1230*e5436536SAndroid Build Coastguard Worker static void createMapping(int aMap[MAX_PARAMETER_BANDS + 1], int startBand,
1231*e5436536SAndroid Build Coastguard Worker                           int stopBand, int stride) {
1232*e5436536SAndroid Build Coastguard Worker   int inBands, outBands, bandsAchived, bandsDiff, incr, k, i;
1233*e5436536SAndroid Build Coastguard Worker   int vDk[MAX_PARAMETER_BANDS + 1];
1234*e5436536SAndroid Build Coastguard Worker   inBands = stopBand - startBand;
1235*e5436536SAndroid Build Coastguard Worker   outBands = (inBands - 1) / stride + 1;
1236*e5436536SAndroid Build Coastguard Worker 
1237*e5436536SAndroid Build Coastguard Worker   if (outBands < 1) {
1238*e5436536SAndroid Build Coastguard Worker     outBands = 1;
1239*e5436536SAndroid Build Coastguard Worker   }
1240*e5436536SAndroid Build Coastguard Worker 
1241*e5436536SAndroid Build Coastguard Worker   bandsAchived = outBands * stride;
1242*e5436536SAndroid Build Coastguard Worker   bandsDiff = inBands - bandsAchived;
1243*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < outBands; i++) {
1244*e5436536SAndroid Build Coastguard Worker     vDk[i] = stride;
1245*e5436536SAndroid Build Coastguard Worker   }
1246*e5436536SAndroid Build Coastguard Worker 
1247*e5436536SAndroid Build Coastguard Worker   if (bandsDiff > 0) {
1248*e5436536SAndroid Build Coastguard Worker     incr = -1;
1249*e5436536SAndroid Build Coastguard Worker     k = outBands - 1;
1250*e5436536SAndroid Build Coastguard Worker   } else {
1251*e5436536SAndroid Build Coastguard Worker     incr = 1;
1252*e5436536SAndroid Build Coastguard Worker     k = 0;
1253*e5436536SAndroid Build Coastguard Worker   }
1254*e5436536SAndroid Build Coastguard Worker 
1255*e5436536SAndroid Build Coastguard Worker   while (bandsDiff != 0) {
1256*e5436536SAndroid Build Coastguard Worker     vDk[k] = vDk[k] - incr;
1257*e5436536SAndroid Build Coastguard Worker     k = k + incr;
1258*e5436536SAndroid Build Coastguard Worker     bandsDiff = bandsDiff + incr;
1259*e5436536SAndroid Build Coastguard Worker     if (k >= outBands) {
1260*e5436536SAndroid Build Coastguard Worker       if (bandsDiff > 0) {
1261*e5436536SAndroid Build Coastguard Worker         k = outBands - 1;
1262*e5436536SAndroid Build Coastguard Worker       } else if (bandsDiff < 0) {
1263*e5436536SAndroid Build Coastguard Worker         k = 0;
1264*e5436536SAndroid Build Coastguard Worker       }
1265*e5436536SAndroid Build Coastguard Worker     }
1266*e5436536SAndroid Build Coastguard Worker   }
1267*e5436536SAndroid Build Coastguard Worker   aMap[0] = startBand;
1268*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < outBands; i++) {
1269*e5436536SAndroid Build Coastguard Worker     aMap[i + 1] = aMap[i] + vDk[i];
1270*e5436536SAndroid Build Coastguard Worker   }
1271*e5436536SAndroid Build Coastguard Worker } /* createMapping */
1272*e5436536SAndroid Build Coastguard Worker 
1273*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1274*e5436536SAndroid Build Coastguard Worker  Functionname: mapFrequency
1275*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1276*e5436536SAndroid Build Coastguard Worker 
1277*e5436536SAndroid Build Coastguard Worker  Description:
1278*e5436536SAndroid Build Coastguard Worker 
1279*e5436536SAndroid Build Coastguard Worker  Arguments:
1280*e5436536SAndroid Build Coastguard Worker 
1281*e5436536SAndroid Build Coastguard Worker  Return:
1282*e5436536SAndroid Build Coastguard Worker 
1283*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
mapFrequency(const SCHAR * pInput,SCHAR * pOutput,int * pMap,int dataBands)1284*e5436536SAndroid Build Coastguard Worker static void mapFrequency(const SCHAR *pInput, /* Input */
1285*e5436536SAndroid Build Coastguard Worker                          SCHAR *pOutput,      /* Output */
1286*e5436536SAndroid Build Coastguard Worker                          int *pMap,           /* Mapping function */
1287*e5436536SAndroid Build Coastguard Worker                          int dataBands)       /* Number of data Bands */
1288*e5436536SAndroid Build Coastguard Worker {
1289*e5436536SAndroid Build Coastguard Worker   int i, j;
1290*e5436536SAndroid Build Coastguard Worker   int startBand0 = pMap[0];
1291*e5436536SAndroid Build Coastguard Worker 
1292*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < dataBands; i++) {
1293*e5436536SAndroid Build Coastguard Worker     int startBand, stopBand, value;
1294*e5436536SAndroid Build Coastguard Worker 
1295*e5436536SAndroid Build Coastguard Worker     value = pInput[i + startBand0];
1296*e5436536SAndroid Build Coastguard Worker 
1297*e5436536SAndroid Build Coastguard Worker     startBand = pMap[i];
1298*e5436536SAndroid Build Coastguard Worker     stopBand = pMap[i + 1];
1299*e5436536SAndroid Build Coastguard Worker     for (j = startBand; j < stopBand; j++) {
1300*e5436536SAndroid Build Coastguard Worker       pOutput[j] = value;
1301*e5436536SAndroid Build Coastguard Worker     }
1302*e5436536SAndroid Build Coastguard Worker   }
1303*e5436536SAndroid Build Coastguard Worker }
1304*e5436536SAndroid Build Coastguard Worker 
1305*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1306*e5436536SAndroid Build Coastguard Worker  Functionname: deq
1307*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1308*e5436536SAndroid Build Coastguard Worker 
1309*e5436536SAndroid Build Coastguard Worker  Description:
1310*e5436536SAndroid Build Coastguard Worker 
1311*e5436536SAndroid Build Coastguard Worker  Arguments:
1312*e5436536SAndroid Build Coastguard Worker 
1313*e5436536SAndroid Build Coastguard Worker  Return:
1314*e5436536SAndroid Build Coastguard Worker 
1315*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
deqIdx(int value,int paramType)1316*e5436536SAndroid Build Coastguard Worker static int deqIdx(int value, int paramType) {
1317*e5436536SAndroid Build Coastguard Worker   int idx = -1;
1318*e5436536SAndroid Build Coastguard Worker 
1319*e5436536SAndroid Build Coastguard Worker   switch (paramType) {
1320*e5436536SAndroid Build Coastguard Worker     case t_CLD:
1321*e5436536SAndroid Build Coastguard Worker       if (((value + 15) >= 0) && ((value + 15) < 31)) {
1322*e5436536SAndroid Build Coastguard Worker         idx = (value + 15);
1323*e5436536SAndroid Build Coastguard Worker       }
1324*e5436536SAndroid Build Coastguard Worker       break;
1325*e5436536SAndroid Build Coastguard Worker 
1326*e5436536SAndroid Build Coastguard Worker     case t_ICC:
1327*e5436536SAndroid Build Coastguard Worker       if ((value >= 0) && (value < 8)) {
1328*e5436536SAndroid Build Coastguard Worker         idx = value;
1329*e5436536SAndroid Build Coastguard Worker       }
1330*e5436536SAndroid Build Coastguard Worker       break;
1331*e5436536SAndroid Build Coastguard Worker 
1332*e5436536SAndroid Build Coastguard Worker     case t_IPD:
1333*e5436536SAndroid Build Coastguard Worker       /* (+/-)15 * MAX_PARAMETER_BANDS for differential coding in frequency
1334*e5436536SAndroid Build Coastguard Worker        * domain (according to rbl) */
1335*e5436536SAndroid Build Coastguard Worker       if ((value >= -420) && (value <= 420)) {
1336*e5436536SAndroid Build Coastguard Worker         idx = (value & 0xf);
1337*e5436536SAndroid Build Coastguard Worker       }
1338*e5436536SAndroid Build Coastguard Worker       break;
1339*e5436536SAndroid Build Coastguard Worker 
1340*e5436536SAndroid Build Coastguard Worker     default:
1341*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(0);
1342*e5436536SAndroid Build Coastguard Worker   }
1343*e5436536SAndroid Build Coastguard Worker 
1344*e5436536SAndroid Build Coastguard Worker   return idx;
1345*e5436536SAndroid Build Coastguard Worker }
1346*e5436536SAndroid Build Coastguard Worker 
1347*e5436536SAndroid Build Coastguard Worker   /*******************************************************************************
1348*e5436536SAndroid Build Coastguard Worker    Functionname: factorFunct
1349*e5436536SAndroid Build Coastguard Worker    *******************************************************************************
1350*e5436536SAndroid Build Coastguard Worker 
1351*e5436536SAndroid Build Coastguard Worker    Description:
1352*e5436536SAndroid Build Coastguard Worker 
1353*e5436536SAndroid Build Coastguard Worker    Arguments:
1354*e5436536SAndroid Build Coastguard Worker 
1355*e5436536SAndroid Build Coastguard Worker    Return:
1356*e5436536SAndroid Build Coastguard Worker 
1357*e5436536SAndroid Build Coastguard Worker   *******************************************************************************/
1358*e5436536SAndroid Build Coastguard Worker 
1359*e5436536SAndroid Build Coastguard Worker #define SF_IDX (7)
1360*e5436536SAndroid Build Coastguard Worker #define SF_FACTOR (3)
1361*e5436536SAndroid Build Coastguard Worker #define SCALE_FACTOR (1 << SF_FACTOR)
1362*e5436536SAndroid Build Coastguard Worker #define SCALE_CLD_C1C2 (1 << SF_CLD_C1C2)
1363*e5436536SAndroid Build Coastguard Worker 
factorFunct(FIXP_DBL ottVsTotDb,INT quantMode)1364*e5436536SAndroid Build Coastguard Worker static FIXP_DBL factorFunct(FIXP_DBL ottVsTotDb, INT quantMode) {
1365*e5436536SAndroid Build Coastguard Worker   FIXP_DBL factor;
1366*e5436536SAndroid Build Coastguard Worker 
1367*e5436536SAndroid Build Coastguard Worker   if (ottVsTotDb > FL2FXCONST_DBL(0.0)) {
1368*e5436536SAndroid Build Coastguard Worker     ottVsTotDb = FL2FXCONST_DBL(0.0);
1369*e5436536SAndroid Build Coastguard Worker   }
1370*e5436536SAndroid Build Coastguard Worker 
1371*e5436536SAndroid Build Coastguard Worker   ottVsTotDb = -ottVsTotDb;
1372*e5436536SAndroid Build Coastguard Worker 
1373*e5436536SAndroid Build Coastguard Worker   switch (quantMode) {
1374*e5436536SAndroid Build Coastguard Worker     case 0:
1375*e5436536SAndroid Build Coastguard Worker       factor = FL2FXCONST_DBL(1.0f / SCALE_FACTOR);
1376*e5436536SAndroid Build Coastguard Worker       break;
1377*e5436536SAndroid Build Coastguard Worker     case 1:
1378*e5436536SAndroid Build Coastguard Worker       if (ottVsTotDb >= FL2FXCONST_DBL(21.0f / SCALE_CLD_C1C2))
1379*e5436536SAndroid Build Coastguard Worker         factor = FL2FXCONST_DBL(5.0f / SCALE_FACTOR);
1380*e5436536SAndroid Build Coastguard Worker       else if (ottVsTotDb <= FL2FXCONST_DBL(1.0f / SCALE_CLD_C1C2))
1381*e5436536SAndroid Build Coastguard Worker         factor = FL2FXCONST_DBL(1.0f / SCALE_FACTOR);
1382*e5436536SAndroid Build Coastguard Worker       else
1383*e5436536SAndroid Build Coastguard Worker         factor = (fMult(FL2FXCONST_DBL(0.2f), ottVsTotDb) +
1384*e5436536SAndroid Build Coastguard Worker                   FL2FXCONST_DBL(0.8f / SCALE_CLD_C1C2))
1385*e5436536SAndroid Build Coastguard Worker                  << (SF_CLD_C1C2 - SF_FACTOR);
1386*e5436536SAndroid Build Coastguard Worker       break;
1387*e5436536SAndroid Build Coastguard Worker     case 2:
1388*e5436536SAndroid Build Coastguard Worker       if (ottVsTotDb >= FL2FXCONST_DBL(25.0f / SCALE_CLD_C1C2)) {
1389*e5436536SAndroid Build Coastguard Worker         FDK_ASSERT(SF_FACTOR == 3);
1390*e5436536SAndroid Build Coastguard Worker         factor = (FIXP_DBL)
1391*e5436536SAndroid Build Coastguard Worker             MAXVAL_DBL; /* avoid warning: FL2FXCONST_DBL(8.0f/SCALE_FACTOR) */
1392*e5436536SAndroid Build Coastguard Worker       } else if (ottVsTotDb <= FL2FXCONST_DBL(1.0f / SCALE_CLD_C1C2))
1393*e5436536SAndroid Build Coastguard Worker         factor = FL2FXCONST_DBL(1.0f / SCALE_FACTOR);
1394*e5436536SAndroid Build Coastguard Worker       else
1395*e5436536SAndroid Build Coastguard Worker         factor = (fMult(FL2FXCONST_DBL(7.0f / 24.0f), ottVsTotDb) +
1396*e5436536SAndroid Build Coastguard Worker                   FL2FXCONST_DBL((17.0f / 24.0f) / SCALE_CLD_C1C2))
1397*e5436536SAndroid Build Coastguard Worker                  << (SF_CLD_C1C2 - SF_FACTOR);
1398*e5436536SAndroid Build Coastguard Worker       break;
1399*e5436536SAndroid Build Coastguard Worker     default:
1400*e5436536SAndroid Build Coastguard Worker       factor = FL2FXCONST_DBL(0.0f);
1401*e5436536SAndroid Build Coastguard Worker   }
1402*e5436536SAndroid Build Coastguard Worker 
1403*e5436536SAndroid Build Coastguard Worker   return (factor);
1404*e5436536SAndroid Build Coastguard Worker }
1405*e5436536SAndroid Build Coastguard Worker 
1406*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1407*e5436536SAndroid Build Coastguard Worker  Functionname: factorCLD
1408*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1409*e5436536SAndroid Build Coastguard Worker 
1410*e5436536SAndroid Build Coastguard Worker  Description:
1411*e5436536SAndroid Build Coastguard Worker 
1412*e5436536SAndroid Build Coastguard Worker  Arguments:
1413*e5436536SAndroid Build Coastguard Worker 
1414*e5436536SAndroid Build Coastguard Worker  Return:
1415*e5436536SAndroid Build Coastguard Worker 
1416*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
factorCLD(SCHAR * idx,FIXP_DBL ottVsTotDb,FIXP_DBL * ottVsTotDb1,FIXP_DBL * ottVsTotDb2,SCHAR ottVsTotDbMode,INT quantMode)1417*e5436536SAndroid Build Coastguard Worker static void factorCLD(SCHAR *idx, FIXP_DBL ottVsTotDb, FIXP_DBL *ottVsTotDb1,
1418*e5436536SAndroid Build Coastguard Worker                       FIXP_DBL *ottVsTotDb2, SCHAR ottVsTotDbMode,
1419*e5436536SAndroid Build Coastguard Worker                       INT quantMode) {
1420*e5436536SAndroid Build Coastguard Worker   FIXP_DBL factor;
1421*e5436536SAndroid Build Coastguard Worker   FIXP_DBL cldIdxFract;
1422*e5436536SAndroid Build Coastguard Worker   INT cldIdx;
1423*e5436536SAndroid Build Coastguard Worker 
1424*e5436536SAndroid Build Coastguard Worker   factor = factorFunct(ottVsTotDb, quantMode);
1425*e5436536SAndroid Build Coastguard Worker 
1426*e5436536SAndroid Build Coastguard Worker   cldIdxFract =
1427*e5436536SAndroid Build Coastguard Worker       fMult((FIXP_DBL)((*idx) << ((DFRACT_BITS - 1) - SF_IDX)), factor);
1428*e5436536SAndroid Build Coastguard Worker   cldIdxFract += FL2FXCONST_DBL(15.5f / (1 << (SF_FACTOR + SF_IDX)));
1429*e5436536SAndroid Build Coastguard Worker   cldIdx = fixp_truncateToInt(cldIdxFract, SF_FACTOR + SF_IDX);
1430*e5436536SAndroid Build Coastguard Worker 
1431*e5436536SAndroid Build Coastguard Worker   cldIdx = fMin(cldIdx, 30);
1432*e5436536SAndroid Build Coastguard Worker   cldIdx = fMax(cldIdx, 0);
1433*e5436536SAndroid Build Coastguard Worker 
1434*e5436536SAndroid Build Coastguard Worker   *idx = cldIdx - 15;
1435*e5436536SAndroid Build Coastguard Worker 
1436*e5436536SAndroid Build Coastguard Worker   if (ottVsTotDbMode & ottVsTotDb1Activ)
1437*e5436536SAndroid Build Coastguard Worker     (*ottVsTotDb1) = ottVsTotDb + dequantCLD_c1[cldIdx];
1438*e5436536SAndroid Build Coastguard Worker 
1439*e5436536SAndroid Build Coastguard Worker   if (ottVsTotDbMode & ottVsTotDb2Activ)
1440*e5436536SAndroid Build Coastguard Worker     (*ottVsTotDb2) = ottVsTotDb + dequantCLD_c1[30 - cldIdx];
1441*e5436536SAndroid Build Coastguard Worker }
1442*e5436536SAndroid Build Coastguard Worker 
1443*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1444*e5436536SAndroid Build Coastguard Worker  Functionname: mapIndexData
1445*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1446*e5436536SAndroid Build Coastguard Worker 
1447*e5436536SAndroid Build Coastguard Worker  Description:
1448*e5436536SAndroid Build Coastguard Worker 
1449*e5436536SAndroid Build Coastguard Worker  Arguments:
1450*e5436536SAndroid Build Coastguard Worker 
1451*e5436536SAndroid Build Coastguard Worker  Return:
1452*e5436536SAndroid Build Coastguard Worker 
1453*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
mapIndexData(LOSSLESSDATA * llData,SCHAR *** outputDataIdx,SCHAR *** outputIdxData,const SCHAR (* cmpIdxData)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],SCHAR *** diffIdxData,SCHAR xttIdx,SCHAR ** idxPrev,int paramIdx,int paramType,int startBand,int stopBand,SCHAR defaultValue,int numParameterSets,const int * paramSlot,int extendFrame,int quantMode,SpatialDecConcealmentInfo * concealmentInfo,SCHAR ottVsTotDbMode,FIXP_DBL (* pOttVsTotDbIn)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],FIXP_DBL (* pOttVsTotDb1)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],FIXP_DBL (* pOttVsTotDb2)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS])1454*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR mapIndexData(
1455*e5436536SAndroid Build Coastguard Worker     LOSSLESSDATA *llData, SCHAR ***outputDataIdx, SCHAR ***outputIdxData,
1456*e5436536SAndroid Build Coastguard Worker     const SCHAR (*cmpIdxData)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
1457*e5436536SAndroid Build Coastguard Worker     SCHAR ***diffIdxData, SCHAR xttIdx, SCHAR **idxPrev, int paramIdx,
1458*e5436536SAndroid Build Coastguard Worker     int paramType, int startBand, int stopBand, SCHAR defaultValue,
1459*e5436536SAndroid Build Coastguard Worker     int numParameterSets, const int *paramSlot, int extendFrame, int quantMode,
1460*e5436536SAndroid Build Coastguard Worker     SpatialDecConcealmentInfo *concealmentInfo, SCHAR ottVsTotDbMode,
1461*e5436536SAndroid Build Coastguard Worker     FIXP_DBL (*pOttVsTotDbIn)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
1462*e5436536SAndroid Build Coastguard Worker     FIXP_DBL (*pOttVsTotDb1)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
1463*e5436536SAndroid Build Coastguard Worker     FIXP_DBL (*pOttVsTotDb2)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS]) {
1464*e5436536SAndroid Build Coastguard Worker   int aParamSlots[MAX_PARAMETER_SETS];
1465*e5436536SAndroid Build Coastguard Worker   int aInterpolate[MAX_PARAMETER_SETS] = {0};
1466*e5436536SAndroid Build Coastguard Worker 
1467*e5436536SAndroid Build Coastguard Worker   int dataSets;
1468*e5436536SAndroid Build Coastguard Worker   int aMap[MAX_PARAMETER_BANDS + 1];
1469*e5436536SAndroid Build Coastguard Worker 
1470*e5436536SAndroid Build Coastguard Worker   int setIdx, i, band, parmSlot;
1471*e5436536SAndroid Build Coastguard Worker   int dataBands;
1472*e5436536SAndroid Build Coastguard Worker   int ps, pb;
1473*e5436536SAndroid Build Coastguard Worker   int i1;
1474*e5436536SAndroid Build Coastguard Worker 
1475*e5436536SAndroid Build Coastguard Worker   if (numParameterSets > MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS;
1476*e5436536SAndroid Build Coastguard Worker 
1477*e5436536SAndroid Build Coastguard Worker   dataSets = 0;
1478*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numParameterSets; i++) {
1479*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 3) {
1480*e5436536SAndroid Build Coastguard Worker       aParamSlots[dataSets] = i;
1481*e5436536SAndroid Build Coastguard Worker       dataSets++;
1482*e5436536SAndroid Build Coastguard Worker     }
1483*e5436536SAndroid Build Coastguard Worker   }
1484*e5436536SAndroid Build Coastguard Worker 
1485*e5436536SAndroid Build Coastguard Worker   setIdx = 0;
1486*e5436536SAndroid Build Coastguard Worker 
1487*e5436536SAndroid Build Coastguard Worker   /* Main concealment stage is here: */
1488*e5436536SAndroid Build Coastguard Worker   SpatialDecConcealment_Apply(
1489*e5436536SAndroid Build Coastguard Worker       concealmentInfo, cmpIdxData[xttIdx],
1490*e5436536SAndroid Build Coastguard Worker       (diffIdxData != NULL) ? diffIdxData[xttIdx] : NULL, idxPrev[xttIdx],
1491*e5436536SAndroid Build Coastguard Worker       llData->bsXXXDataMode, startBand, stopBand, defaultValue, paramType,
1492*e5436536SAndroid Build Coastguard Worker       numParameterSets);
1493*e5436536SAndroid Build Coastguard Worker 
1494*e5436536SAndroid Build Coastguard Worker   /* Prepare data */
1495*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numParameterSets; i++) {
1496*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 0) {
1497*e5436536SAndroid Build Coastguard Worker       llData->nocmpQuantCoarseXXX[i] = 0;
1498*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1499*e5436536SAndroid Build Coastguard Worker         outputIdxData[xttIdx][i][band] = defaultValue;
1500*e5436536SAndroid Build Coastguard Worker       }
1501*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1502*e5436536SAndroid Build Coastguard Worker         idxPrev[xttIdx][band] = outputIdxData[xttIdx][i][band];
1503*e5436536SAndroid Build Coastguard Worker       }
1504*e5436536SAndroid Build Coastguard Worker       /* Because the idxPrev are also set to the defaultValue -> signalize fine
1505*e5436536SAndroid Build Coastguard Worker        */
1506*e5436536SAndroid Build Coastguard Worker       llData->state->bsQuantCoarseXXXprev = 0;
1507*e5436536SAndroid Build Coastguard Worker     }
1508*e5436536SAndroid Build Coastguard Worker 
1509*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 1) {
1510*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1511*e5436536SAndroid Build Coastguard Worker         outputIdxData[xttIdx][i][band] = idxPrev[xttIdx][band];
1512*e5436536SAndroid Build Coastguard Worker       }
1513*e5436536SAndroid Build Coastguard Worker       llData->nocmpQuantCoarseXXX[i] = llData->state->bsQuantCoarseXXXprev;
1514*e5436536SAndroid Build Coastguard Worker     }
1515*e5436536SAndroid Build Coastguard Worker 
1516*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 2) {
1517*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1518*e5436536SAndroid Build Coastguard Worker         outputIdxData[xttIdx][i][band] = idxPrev[xttIdx][band];
1519*e5436536SAndroid Build Coastguard Worker       }
1520*e5436536SAndroid Build Coastguard Worker       llData->nocmpQuantCoarseXXX[i] = llData->state->bsQuantCoarseXXXprev;
1521*e5436536SAndroid Build Coastguard Worker       aInterpolate[i] = 1;
1522*e5436536SAndroid Build Coastguard Worker     } else {
1523*e5436536SAndroid Build Coastguard Worker       aInterpolate[i] = 0;
1524*e5436536SAndroid Build Coastguard Worker     }
1525*e5436536SAndroid Build Coastguard Worker 
1526*e5436536SAndroid Build Coastguard Worker     if (llData->bsXXXDataMode[i] == 3) {
1527*e5436536SAndroid Build Coastguard Worker       int stride;
1528*e5436536SAndroid Build Coastguard Worker 
1529*e5436536SAndroid Build Coastguard Worker       parmSlot = aParamSlots[setIdx];
1530*e5436536SAndroid Build Coastguard Worker       stride = pbStrideTable[llData->bsFreqResStrideXXX[setIdx]];
1531*e5436536SAndroid Build Coastguard Worker       dataBands = (stopBand - startBand - 1) / stride + 1;
1532*e5436536SAndroid Build Coastguard Worker       createMapping(aMap, startBand, stopBand, stride);
1533*e5436536SAndroid Build Coastguard Worker       mapFrequency(&cmpIdxData[xttIdx][setIdx][0],
1534*e5436536SAndroid Build Coastguard Worker                    &outputIdxData[xttIdx][parmSlot][0], aMap, dataBands);
1535*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1536*e5436536SAndroid Build Coastguard Worker         idxPrev[xttIdx][band] = outputIdxData[xttIdx][parmSlot][band];
1537*e5436536SAndroid Build Coastguard Worker       }
1538*e5436536SAndroid Build Coastguard Worker       llData->state->bsQuantCoarseXXXprev = llData->bsQuantCoarseXXX[setIdx];
1539*e5436536SAndroid Build Coastguard Worker       llData->nocmpQuantCoarseXXX[i] = llData->bsQuantCoarseXXX[setIdx];
1540*e5436536SAndroid Build Coastguard Worker 
1541*e5436536SAndroid Build Coastguard Worker       setIdx++;
1542*e5436536SAndroid Build Coastguard Worker     }
1543*e5436536SAndroid Build Coastguard Worker     if (diffIdxData != NULL) {
1544*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1545*e5436536SAndroid Build Coastguard Worker         outputIdxData[xttIdx][i][band] += diffIdxData[xttIdx][i][band];
1546*e5436536SAndroid Build Coastguard Worker       }
1547*e5436536SAndroid Build Coastguard Worker     }
1548*e5436536SAndroid Build Coastguard Worker   } /* for( i = 0 ; i < numParameterSets; i++ ) */
1549*e5436536SAndroid Build Coastguard Worker 
1550*e5436536SAndroid Build Coastguard Worker   /* Map all coarse data to fine */
1551*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numParameterSets; i++) {
1552*e5436536SAndroid Build Coastguard Worker     if (llData->nocmpQuantCoarseXXX[i] == 1) {
1553*e5436536SAndroid Build Coastguard Worker       coarse2fine(outputIdxData[xttIdx][i], (DATA_TYPE)paramType, startBand,
1554*e5436536SAndroid Build Coastguard Worker                   stopBand - startBand);
1555*e5436536SAndroid Build Coastguard Worker       llData->nocmpQuantCoarseXXX[i] = 0;
1556*e5436536SAndroid Build Coastguard Worker     }
1557*e5436536SAndroid Build Coastguard Worker   }
1558*e5436536SAndroid Build Coastguard Worker 
1559*e5436536SAndroid Build Coastguard Worker   /* Interpolate */
1560*e5436536SAndroid Build Coastguard Worker   i1 = 0;
1561*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numParameterSets; i++) {
1562*e5436536SAndroid Build Coastguard Worker     if (aInterpolate[i] != 1) {
1563*e5436536SAndroid Build Coastguard Worker       i1 = i;
1564*e5436536SAndroid Build Coastguard Worker     } else {
1565*e5436536SAndroid Build Coastguard Worker       int xi, i2, x1, x2;
1566*e5436536SAndroid Build Coastguard Worker 
1567*e5436536SAndroid Build Coastguard Worker       for (i2 = i; i2 < numParameterSets; i2++) {
1568*e5436536SAndroid Build Coastguard Worker         if (aInterpolate[i2] != 1) break;
1569*e5436536SAndroid Build Coastguard Worker       }
1570*e5436536SAndroid Build Coastguard Worker       if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
1571*e5436536SAndroid Build Coastguard Worker 
1572*e5436536SAndroid Build Coastguard Worker       x1 = paramSlot[i1];
1573*e5436536SAndroid Build Coastguard Worker       xi = paramSlot[i];
1574*e5436536SAndroid Build Coastguard Worker       x2 = paramSlot[i2];
1575*e5436536SAndroid Build Coastguard Worker 
1576*e5436536SAndroid Build Coastguard Worker       for (band = startBand; band < stopBand; band++) {
1577*e5436536SAndroid Build Coastguard Worker         int yi, y1, y2;
1578*e5436536SAndroid Build Coastguard Worker         y1 = outputIdxData[xttIdx][i1][band];
1579*e5436536SAndroid Build Coastguard Worker         y2 = outputIdxData[xttIdx][i2][band];
1580*e5436536SAndroid Build Coastguard Worker         if (x1 != x2) {
1581*e5436536SAndroid Build Coastguard Worker           yi = y1 + (xi - x1) * (y2 - y1) / (x2 - x1);
1582*e5436536SAndroid Build Coastguard Worker         } else {
1583*e5436536SAndroid Build Coastguard Worker           yi = y1 /*+ (xi-x1)*(y2-y1)/1e-12*/;
1584*e5436536SAndroid Build Coastguard Worker         }
1585*e5436536SAndroid Build Coastguard Worker         outputIdxData[xttIdx][i][band] = yi;
1586*e5436536SAndroid Build Coastguard Worker       }
1587*e5436536SAndroid Build Coastguard Worker     }
1588*e5436536SAndroid Build Coastguard Worker   } /* for( i = 0 ; i < numParameterSets; i++ ) */
1589*e5436536SAndroid Build Coastguard Worker 
1590*e5436536SAndroid Build Coastguard Worker   /* Dequantize data and apply factorCLD if necessary */
1591*e5436536SAndroid Build Coastguard Worker   for (ps = 0; ps < numParameterSets; ps++) {
1592*e5436536SAndroid Build Coastguard Worker     if (quantMode && (paramType == t_CLD)) {
1593*e5436536SAndroid Build Coastguard Worker       if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
1594*e5436536SAndroid Build Coastguard Worker       if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode & ottVsTotDb1Activ))
1595*e5436536SAndroid Build Coastguard Worker         return MPS_WRONG_OTT;
1596*e5436536SAndroid Build Coastguard Worker       if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode & ottVsTotDb2Activ))
1597*e5436536SAndroid Build Coastguard Worker         return MPS_WRONG_OTT;
1598*e5436536SAndroid Build Coastguard Worker 
1599*e5436536SAndroid Build Coastguard Worker       for (pb = startBand; pb < stopBand; pb++) {
1600*e5436536SAndroid Build Coastguard Worker         factorCLD(&(outputIdxData[xttIdx][ps][pb]), (*pOttVsTotDbIn)[ps][pb],
1601*e5436536SAndroid Build Coastguard Worker                   (pOttVsTotDb1 != NULL) ? &((*pOttVsTotDb1)[ps][pb]) : NULL,
1602*e5436536SAndroid Build Coastguard Worker                   (pOttVsTotDb2 != NULL) ? &((*pOttVsTotDb2)[ps][pb]) : NULL,
1603*e5436536SAndroid Build Coastguard Worker                   ottVsTotDbMode, quantMode);
1604*e5436536SAndroid Build Coastguard Worker       }
1605*e5436536SAndroid Build Coastguard Worker     }
1606*e5436536SAndroid Build Coastguard Worker 
1607*e5436536SAndroid Build Coastguard Worker     /* Dequantize data */
1608*e5436536SAndroid Build Coastguard Worker     for (band = startBand; band < stopBand; band++) {
1609*e5436536SAndroid Build Coastguard Worker       outputDataIdx[xttIdx][ps][band] =
1610*e5436536SAndroid Build Coastguard Worker           deqIdx(outputIdxData[xttIdx][ps][band], paramType);
1611*e5436536SAndroid Build Coastguard Worker       if (outputDataIdx[xttIdx][ps][band] == -1) {
1612*e5436536SAndroid Build Coastguard Worker         outputDataIdx[xttIdx][ps][band] = defaultValue;
1613*e5436536SAndroid Build Coastguard Worker       }
1614*e5436536SAndroid Build Coastguard Worker     }
1615*e5436536SAndroid Build Coastguard Worker   } /* for( i = 0 ; i < numParameterSets; i++ ) */
1616*e5436536SAndroid Build Coastguard Worker 
1617*e5436536SAndroid Build Coastguard Worker   if (extendFrame) {
1618*e5436536SAndroid Build Coastguard Worker     if (paramType == t_IPD) {
1619*e5436536SAndroid Build Coastguard Worker       llData->bsQuantCoarseXXX[numParameterSets] =
1620*e5436536SAndroid Build Coastguard Worker           llData->bsQuantCoarseXXX[numParameterSets - 1];
1621*e5436536SAndroid Build Coastguard Worker     }
1622*e5436536SAndroid Build Coastguard Worker     for (band = startBand; band < stopBand; band++) {
1623*e5436536SAndroid Build Coastguard Worker       outputDataIdx[xttIdx][numParameterSets][band] =
1624*e5436536SAndroid Build Coastguard Worker           outputDataIdx[xttIdx][numParameterSets - 1][band];
1625*e5436536SAndroid Build Coastguard Worker     }
1626*e5436536SAndroid Build Coastguard Worker   }
1627*e5436536SAndroid Build Coastguard Worker 
1628*e5436536SAndroid Build Coastguard Worker   return MPS_OK;
1629*e5436536SAndroid Build Coastguard Worker }
1630*e5436536SAndroid Build Coastguard Worker 
1631*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1632*e5436536SAndroid Build Coastguard Worker  Functionname: decodeAndMapFrameOtt
1633*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1634*e5436536SAndroid Build Coastguard Worker 
1635*e5436536SAndroid Build Coastguard Worker  Description:
1636*e5436536SAndroid Build Coastguard Worker    Do delta decoding and dequantization
1637*e5436536SAndroid Build Coastguard Worker 
1638*e5436536SAndroid Build Coastguard Worker  Arguments:
1639*e5436536SAndroid Build Coastguard Worker 
1640*e5436536SAndroid Build Coastguard Worker Input:
1641*e5436536SAndroid Build Coastguard Worker 
1642*e5436536SAndroid Build Coastguard Worker Output:
1643*e5436536SAndroid Build Coastguard Worker 
1644*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
decodeAndMapFrameOtt(HANDLE_SPATIAL_DEC self,SPATIAL_BS_FRAME * pCurBs)1645*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR decodeAndMapFrameOtt(HANDLE_SPATIAL_DEC self,
1646*e5436536SAndroid Build Coastguard Worker                                          SPATIAL_BS_FRAME *pCurBs) {
1647*e5436536SAndroid Build Coastguard Worker   int i, ottIdx;
1648*e5436536SAndroid Build Coastguard Worker   int numOttBoxes;
1649*e5436536SAndroid Build Coastguard Worker 
1650*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
1651*e5436536SAndroid Build Coastguard Worker 
1652*e5436536SAndroid Build Coastguard Worker   numOttBoxes = self->numOttBoxes;
1653*e5436536SAndroid Build Coastguard Worker 
1654*e5436536SAndroid Build Coastguard Worker   switch (self->treeConfig) {
1655*e5436536SAndroid Build Coastguard Worker     default: {
1656*e5436536SAndroid Build Coastguard Worker       if (self->quantMode != 0) {
1657*e5436536SAndroid Build Coastguard Worker         goto bail;
1658*e5436536SAndroid Build Coastguard Worker       }
1659*e5436536SAndroid Build Coastguard Worker     }
1660*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < numOttBoxes; i++) {
1661*e5436536SAndroid Build Coastguard Worker         err = mapIndexData(
1662*e5436536SAndroid Build Coastguard Worker             &pCurBs->CLDLosslessData[i], /* LOSSLESSDATA *llData,*/
1663*e5436536SAndroid Build Coastguard Worker             self->ottCLD__FDK, self->outIdxData,
1664*e5436536SAndroid Build Coastguard Worker             pCurBs
1665*e5436536SAndroid Build Coastguard Worker                 ->cmpOttCLDidx, /* int
1666*e5436536SAndroid Build Coastguard Worker                                    cmpIdxData[MAX_NUM_OTT][MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
1667*e5436536SAndroid Build Coastguard Worker                                  */
1668*e5436536SAndroid Build Coastguard Worker             NULL,               /* no differential data */
1669*e5436536SAndroid Build Coastguard Worker             i, /*  int   xttIdx,  Which ott/ttt index to use for input and
1670*e5436536SAndroid Build Coastguard Worker                   output buffers */
1671*e5436536SAndroid Build Coastguard Worker             self->ottCLDidxPrev,                        /* int
1672*e5436536SAndroid Build Coastguard Worker                                                            idxPrev[MAX_NUM_OTT][MAX_PARAMETER_BANDS],
1673*e5436536SAndroid Build Coastguard Worker                                                          */
1674*e5436536SAndroid Build Coastguard Worker             i, t_CLD, 0,                                /* int   startBand, */
1675*e5436536SAndroid Build Coastguard Worker             self->pConfigCurrent->bitstreamOttBands[i], /*  int   stopBand, */
1676*e5436536SAndroid Build Coastguard Worker             self->pConfigCurrent->ottCLDdefault[i], /* int   defaultValue, */
1677*e5436536SAndroid Build Coastguard Worker             pCurBs->numParameterSets, /* int   numParameterSets) */
1678*e5436536SAndroid Build Coastguard Worker             pCurBs->paramSlot, self->extendFrame, self->quantMode,
1679*e5436536SAndroid Build Coastguard Worker             &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
1680*e5436536SAndroid Build Coastguard Worker         if (err != MPS_OK) goto bail;
1681*e5436536SAndroid Build Coastguard Worker 
1682*e5436536SAndroid Build Coastguard Worker       } /* for(i = 0; i < numOttBoxes ; i++ ) */
1683*e5436536SAndroid Build Coastguard Worker       break;
1684*e5436536SAndroid Build Coastguard Worker   } /* case */
1685*e5436536SAndroid Build Coastguard Worker 
1686*e5436536SAndroid Build Coastguard Worker   for (ottIdx = 0; ottIdx < numOttBoxes; ottIdx++) {
1687*e5436536SAndroid Build Coastguard Worker     /* Read ICC */
1688*e5436536SAndroid Build Coastguard Worker     err = mapIndexData(
1689*e5436536SAndroid Build Coastguard Worker         &pCurBs->ICCLosslessData[ottIdx], /* LOSSLESSDATA *llData,*/
1690*e5436536SAndroid Build Coastguard Worker         self->ottICC__FDK, self->outIdxData,
1691*e5436536SAndroid Build Coastguard Worker         pCurBs
1692*e5436536SAndroid Build Coastguard Worker             ->cmpOttICCidx,  /* int
1693*e5436536SAndroid Build Coastguard Worker                                 cmpIdxData[MAX_NUM_OTT][MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
1694*e5436536SAndroid Build Coastguard Worker                               */
1695*e5436536SAndroid Build Coastguard Worker         self->ottICCdiffidx, /* differential data */
1696*e5436536SAndroid Build Coastguard Worker         ottIdx, /* int   xttIdx,  Which ott/ttt index to use for input and
1697*e5436536SAndroid Build Coastguard Worker                    output buffers */
1698*e5436536SAndroid Build Coastguard Worker         self->ottICCidxPrev, /* int   idxPrev[MAX_NUM_OTT][MAX_PARAMETER_BANDS],
1699*e5436536SAndroid Build Coastguard Worker                               */
1700*e5436536SAndroid Build Coastguard Worker         ottIdx, t_ICC, 0,    /* int   startBand, */
1701*e5436536SAndroid Build Coastguard Worker         self->pConfigCurrent->bitstreamOttBands[ottIdx], /* int   stopBand, */
1702*e5436536SAndroid Build Coastguard Worker         ICCdefault,               /* int   defaultValue, */
1703*e5436536SAndroid Build Coastguard Worker         pCurBs->numParameterSets, /* int   numParameterSets) */
1704*e5436536SAndroid Build Coastguard Worker         pCurBs->paramSlot, self->extendFrame, self->quantMode,
1705*e5436536SAndroid Build Coastguard Worker         &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
1706*e5436536SAndroid Build Coastguard Worker     if (err != MPS_OK) goto bail;
1707*e5436536SAndroid Build Coastguard Worker   } /* ottIdx */
1708*e5436536SAndroid Build Coastguard Worker 
1709*e5436536SAndroid Build Coastguard Worker   if ((self->treeConfig == TREE_212) && (self->phaseCoding)) {
1710*e5436536SAndroid Build Coastguard Worker     if (pCurBs->phaseMode == 0) {
1711*e5436536SAndroid Build Coastguard Worker       for (int pb = 0; pb < self->pConfigCurrent->numOttBandsIPD; pb++) {
1712*e5436536SAndroid Build Coastguard Worker         self->ottIPDidxPrev[0][pb] = 0;
1713*e5436536SAndroid Build Coastguard Worker       }
1714*e5436536SAndroid Build Coastguard Worker     }
1715*e5436536SAndroid Build Coastguard Worker     for (ottIdx = 0; ottIdx < numOttBoxes; ottIdx++) {
1716*e5436536SAndroid Build Coastguard Worker       err = mapIndexData(
1717*e5436536SAndroid Build Coastguard Worker           &pCurBs->IPDLosslessData[ottIdx], self->ottIPD__FDK, self->outIdxData,
1718*e5436536SAndroid Build Coastguard Worker           pCurBs->cmpOttIPDidx, NULL, ottIdx, self->ottIPDidxPrev, ottIdx,
1719*e5436536SAndroid Build Coastguard Worker           t_IPD, 0, self->numOttBandsIPD, IPDdefault, pCurBs->numParameterSets,
1720*e5436536SAndroid Build Coastguard Worker           pCurBs->paramSlot, self->extendFrame, self->quantMode,
1721*e5436536SAndroid Build Coastguard Worker           &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
1722*e5436536SAndroid Build Coastguard Worker     }
1723*e5436536SAndroid Build Coastguard Worker   }
1724*e5436536SAndroid Build Coastguard Worker 
1725*e5436536SAndroid Build Coastguard Worker bail:
1726*e5436536SAndroid Build Coastguard Worker 
1727*e5436536SAndroid Build Coastguard Worker   return MPS_OK;
1728*e5436536SAndroid Build Coastguard Worker 
1729*e5436536SAndroid Build Coastguard Worker } /* decodeAndMapFrameOtt */
1730*e5436536SAndroid Build Coastguard Worker 
1731*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1732*e5436536SAndroid Build Coastguard Worker  Functionname: decodeAndMapFrameSmg
1733*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1734*e5436536SAndroid Build Coastguard Worker 
1735*e5436536SAndroid Build Coastguard Worker  Description:
1736*e5436536SAndroid Build Coastguard Worker    Decode smoothing flags
1737*e5436536SAndroid Build Coastguard Worker 
1738*e5436536SAndroid Build Coastguard Worker  Arguments:
1739*e5436536SAndroid Build Coastguard Worker 
1740*e5436536SAndroid Build Coastguard Worker Input:
1741*e5436536SAndroid Build Coastguard Worker 
1742*e5436536SAndroid Build Coastguard Worker Output:
1743*e5436536SAndroid Build Coastguard Worker 
1744*e5436536SAndroid Build Coastguard Worker 
1745*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
decodeAndMapFrameSmg(HANDLE_SPATIAL_DEC self,const SPATIAL_BS_FRAME * frame)1746*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR decodeAndMapFrameSmg(HANDLE_SPATIAL_DEC self,
1747*e5436536SAndroid Build Coastguard Worker                                          const SPATIAL_BS_FRAME *frame) {
1748*e5436536SAndroid Build Coastguard Worker   int ps, pb, pg, pbStride, dataBands, pbStart, pbStop,
1749*e5436536SAndroid Build Coastguard Worker       aGroupToBand[MAX_PARAMETER_BANDS + 1];
1750*e5436536SAndroid Build Coastguard Worker 
1751*e5436536SAndroid Build Coastguard Worker   if (frame->numParameterSets > MAX_PARAMETER_SETS)
1752*e5436536SAndroid Build Coastguard Worker     return MPS_WRONG_PARAMETERSETS;
1753*e5436536SAndroid Build Coastguard Worker   if (self->bitstreamParameterBands > MAX_PARAMETER_BANDS)
1754*e5436536SAndroid Build Coastguard Worker     return MPS_WRONG_PARAMETERBANDS;
1755*e5436536SAndroid Build Coastguard Worker 
1756*e5436536SAndroid Build Coastguard Worker   for (ps = 0; ps < frame->numParameterSets; ps++) {
1757*e5436536SAndroid Build Coastguard Worker     switch (frame->bsSmoothMode[ps]) {
1758*e5436536SAndroid Build Coastguard Worker       case 0:
1759*e5436536SAndroid Build Coastguard Worker         self->smgTime[ps] = 256;
1760*e5436536SAndroid Build Coastguard Worker         FDKmemclear(self->smgData[ps],
1761*e5436536SAndroid Build Coastguard Worker                     self->bitstreamParameterBands * sizeof(UCHAR));
1762*e5436536SAndroid Build Coastguard Worker         break;
1763*e5436536SAndroid Build Coastguard Worker 
1764*e5436536SAndroid Build Coastguard Worker       case 1:
1765*e5436536SAndroid Build Coastguard Worker         if (ps > 0) {
1766*e5436536SAndroid Build Coastguard Worker           self->smgTime[ps] = self->smgTime[ps - 1];
1767*e5436536SAndroid Build Coastguard Worker           FDKmemcpy(self->smgData[ps], self->smgData[ps - 1],
1768*e5436536SAndroid Build Coastguard Worker                     self->bitstreamParameterBands * sizeof(UCHAR));
1769*e5436536SAndroid Build Coastguard Worker         } else {
1770*e5436536SAndroid Build Coastguard Worker           self->smgTime[ps] = self->smoothState->prevSmgTime;
1771*e5436536SAndroid Build Coastguard Worker           FDKmemcpy(self->smgData[ps], self->smoothState->prevSmgData,
1772*e5436536SAndroid Build Coastguard Worker                     self->bitstreamParameterBands * sizeof(UCHAR));
1773*e5436536SAndroid Build Coastguard Worker         }
1774*e5436536SAndroid Build Coastguard Worker         break;
1775*e5436536SAndroid Build Coastguard Worker 
1776*e5436536SAndroid Build Coastguard Worker       case 2:
1777*e5436536SAndroid Build Coastguard Worker         self->smgTime[ps] = smgTimeTable[frame->bsSmoothTime[ps]];
1778*e5436536SAndroid Build Coastguard Worker         for (pb = 0; pb < self->bitstreamParameterBands; pb++) {
1779*e5436536SAndroid Build Coastguard Worker           self->smgData[ps][pb] = 1;
1780*e5436536SAndroid Build Coastguard Worker         }
1781*e5436536SAndroid Build Coastguard Worker         break;
1782*e5436536SAndroid Build Coastguard Worker 
1783*e5436536SAndroid Build Coastguard Worker       case 3:
1784*e5436536SAndroid Build Coastguard Worker         self->smgTime[ps] = smgTimeTable[frame->bsSmoothTime[ps]];
1785*e5436536SAndroid Build Coastguard Worker         pbStride = pbStrideTable[frame->bsFreqResStrideSmg[ps]];
1786*e5436536SAndroid Build Coastguard Worker         dataBands = (self->bitstreamParameterBands - 1) / pbStride + 1;
1787*e5436536SAndroid Build Coastguard Worker         createMapping(aGroupToBand, 0, self->bitstreamParameterBands, pbStride);
1788*e5436536SAndroid Build Coastguard Worker         for (pg = 0; pg < dataBands; pg++) {
1789*e5436536SAndroid Build Coastguard Worker           pbStart = aGroupToBand[pg];
1790*e5436536SAndroid Build Coastguard Worker           pbStop = aGroupToBand[pg + 1];
1791*e5436536SAndroid Build Coastguard Worker           for (pb = pbStart; pb < pbStop; pb++) {
1792*e5436536SAndroid Build Coastguard Worker             self->smgData[ps][pb] = frame->bsSmgData[ps][pg];
1793*e5436536SAndroid Build Coastguard Worker           }
1794*e5436536SAndroid Build Coastguard Worker         }
1795*e5436536SAndroid Build Coastguard Worker         break;
1796*e5436536SAndroid Build Coastguard Worker     }
1797*e5436536SAndroid Build Coastguard Worker   }
1798*e5436536SAndroid Build Coastguard Worker 
1799*e5436536SAndroid Build Coastguard Worker   self->smoothState->prevSmgTime = self->smgTime[frame->numParameterSets - 1];
1800*e5436536SAndroid Build Coastguard Worker   FDKmemcpy(self->smoothState->prevSmgData,
1801*e5436536SAndroid Build Coastguard Worker             self->smgData[frame->numParameterSets - 1],
1802*e5436536SAndroid Build Coastguard Worker             self->bitstreamParameterBands * sizeof(UCHAR));
1803*e5436536SAndroid Build Coastguard Worker 
1804*e5436536SAndroid Build Coastguard Worker   if (self->extendFrame) {
1805*e5436536SAndroid Build Coastguard Worker     self->smgTime[frame->numParameterSets] =
1806*e5436536SAndroid Build Coastguard Worker         self->smgTime[frame->numParameterSets - 1];
1807*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(self->smgData[frame->numParameterSets],
1808*e5436536SAndroid Build Coastguard Worker               self->smgData[frame->numParameterSets - 1],
1809*e5436536SAndroid Build Coastguard Worker               self->bitstreamParameterBands * sizeof(UCHAR));
1810*e5436536SAndroid Build Coastguard Worker   }
1811*e5436536SAndroid Build Coastguard Worker 
1812*e5436536SAndroid Build Coastguard Worker   return MPS_OK;
1813*e5436536SAndroid Build Coastguard Worker }
1814*e5436536SAndroid Build Coastguard Worker 
1815*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1816*e5436536SAndroid Build Coastguard Worker  Functionname: decodeAndMapFrameArbdmx
1817*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1818*e5436536SAndroid Build Coastguard Worker 
1819*e5436536SAndroid Build Coastguard Worker  Description:
1820*e5436536SAndroid Build Coastguard Worker    Do delta decoding and dequantization
1821*e5436536SAndroid Build Coastguard Worker 
1822*e5436536SAndroid Build Coastguard Worker  Arguments:
1823*e5436536SAndroid Build Coastguard Worker 
1824*e5436536SAndroid Build Coastguard Worker Input:
1825*e5436536SAndroid Build Coastguard Worker 
1826*e5436536SAndroid Build Coastguard Worker Output:
1827*e5436536SAndroid Build Coastguard Worker 
1828*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
decodeAndMapFrameArbdmx(HANDLE_SPATIAL_DEC self,const SPATIAL_BS_FRAME * frame)1829*e5436536SAndroid Build Coastguard Worker static SACDEC_ERROR decodeAndMapFrameArbdmx(HANDLE_SPATIAL_DEC self,
1830*e5436536SAndroid Build Coastguard Worker                                             const SPATIAL_BS_FRAME *frame) {
1831*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
1832*e5436536SAndroid Build Coastguard Worker   int ch;
1833*e5436536SAndroid Build Coastguard Worker   int offset = self->numOttBoxes;
1834*e5436536SAndroid Build Coastguard Worker 
1835*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < self->numInputChannels; ch++) {
1836*e5436536SAndroid Build Coastguard Worker     err = mapIndexData(&frame->CLDLosslessData[offset + ch],
1837*e5436536SAndroid Build Coastguard Worker                        self->arbdmxGain__FDK, self->outIdxData,
1838*e5436536SAndroid Build Coastguard Worker                        frame->cmpArbdmxGainIdx, NULL, /* no differential data */
1839*e5436536SAndroid Build Coastguard Worker                        ch, self->arbdmxGainIdxPrev, offset + ch, t_CLD, 0,
1840*e5436536SAndroid Build Coastguard Worker                        self->bitstreamParameterBands,
1841*e5436536SAndroid Build Coastguard Worker                        0 /*self->arbdmxGainDefault*/, frame->numParameterSets,
1842*e5436536SAndroid Build Coastguard Worker                        frame->paramSlot, self->extendFrame, 0,
1843*e5436536SAndroid Build Coastguard Worker                        &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
1844*e5436536SAndroid Build Coastguard Worker     if (err != MPS_OK) goto bail;
1845*e5436536SAndroid Build Coastguard Worker   }
1846*e5436536SAndroid Build Coastguard Worker 
1847*e5436536SAndroid Build Coastguard Worker bail:
1848*e5436536SAndroid Build Coastguard Worker   return err;
1849*e5436536SAndroid Build Coastguard Worker } /* decodeAndMapFrameArbdmx */
1850*e5436536SAndroid Build Coastguard Worker 
1851*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1852*e5436536SAndroid Build Coastguard Worker  Functionname: SpatialDecDecodeFrame
1853*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1854*e5436536SAndroid Build Coastguard Worker 
1855*e5436536SAndroid Build Coastguard Worker  Description:
1856*e5436536SAndroid Build Coastguard Worker 
1857*e5436536SAndroid Build Coastguard Worker  Arguments:
1858*e5436536SAndroid Build Coastguard Worker 
1859*e5436536SAndroid Build Coastguard Worker  Return:
1860*e5436536SAndroid Build Coastguard Worker 
1861*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
SpatialDecDecodeFrame(spatialDec * self,SPATIAL_BS_FRAME * frame)1862*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecDecodeFrame(spatialDec *self, SPATIAL_BS_FRAME *frame) {
1863*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
1864*e5436536SAndroid Build Coastguard Worker 
1865*e5436536SAndroid Build Coastguard Worker   self->extendFrame = 0;
1866*e5436536SAndroid Build Coastguard Worker   if (frame->paramSlot[frame->numParameterSets - 1] != self->timeSlots - 1) {
1867*e5436536SAndroid Build Coastguard Worker     self->extendFrame = 1;
1868*e5436536SAndroid Build Coastguard Worker   }
1869*e5436536SAndroid Build Coastguard Worker 
1870*e5436536SAndroid Build Coastguard Worker   self->TsdTs = 0;
1871*e5436536SAndroid Build Coastguard Worker 
1872*e5436536SAndroid Build Coastguard Worker   /****** DTDF and MAP DATA ********/
1873*e5436536SAndroid Build Coastguard Worker   if ((err = decodeAndMapFrameOtt(self, frame)) != MPS_OK) goto bail;
1874*e5436536SAndroid Build Coastguard Worker 
1875*e5436536SAndroid Build Coastguard Worker   if ((err = decodeAndMapFrameSmg(self, frame)) != MPS_OK) goto bail;
1876*e5436536SAndroid Build Coastguard Worker 
1877*e5436536SAndroid Build Coastguard Worker   if (self->arbitraryDownmix != 0) {
1878*e5436536SAndroid Build Coastguard Worker     if ((err = decodeAndMapFrameArbdmx(self, frame)) != MPS_OK) goto bail;
1879*e5436536SAndroid Build Coastguard Worker   }
1880*e5436536SAndroid Build Coastguard Worker 
1881*e5436536SAndroid Build Coastguard Worker   if (self->extendFrame) {
1882*e5436536SAndroid Build Coastguard Worker     frame->numParameterSets =
1883*e5436536SAndroid Build Coastguard Worker         fixMin(MAX_PARAMETER_SETS, frame->numParameterSets + 1);
1884*e5436536SAndroid Build Coastguard Worker     frame->paramSlot[frame->numParameterSets - 1] = self->timeSlots - 1;
1885*e5436536SAndroid Build Coastguard Worker 
1886*e5436536SAndroid Build Coastguard Worker     for (int p = 0; p < frame->numParameterSets; p++) {
1887*e5436536SAndroid Build Coastguard Worker       if (frame->paramSlot[p] > self->timeSlots - 1) {
1888*e5436536SAndroid Build Coastguard Worker         frame->paramSlot[p] = self->timeSlots - 1;
1889*e5436536SAndroid Build Coastguard Worker         err = MPS_PARSE_ERROR;
1890*e5436536SAndroid Build Coastguard Worker       }
1891*e5436536SAndroid Build Coastguard Worker     }
1892*e5436536SAndroid Build Coastguard Worker     if (err != MPS_OK) {
1893*e5436536SAndroid Build Coastguard Worker       goto bail;
1894*e5436536SAndroid Build Coastguard Worker     }
1895*e5436536SAndroid Build Coastguard Worker   }
1896*e5436536SAndroid Build Coastguard Worker 
1897*e5436536SAndroid Build Coastguard Worker bail:
1898*e5436536SAndroid Build Coastguard Worker   return err;
1899*e5436536SAndroid Build Coastguard Worker } /* SpatialDecDecodeFrame() */
1900*e5436536SAndroid Build Coastguard Worker 
1901*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
1902*e5436536SAndroid Build Coastguard Worker  Functionname: SpatialDecodeHeader
1903*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
1904*e5436536SAndroid Build Coastguard Worker 
1905*e5436536SAndroid Build Coastguard Worker  Description:
1906*e5436536SAndroid Build Coastguard Worker 
1907*e5436536SAndroid Build Coastguard Worker  Arguments:
1908*e5436536SAndroid Build Coastguard Worker 
1909*e5436536SAndroid Build Coastguard Worker  Return:
1910*e5436536SAndroid Build Coastguard Worker 
1911*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
1912*e5436536SAndroid Build Coastguard Worker 
SpatialDecDecodeHeader(spatialDec * self,SPATIAL_SPECIFIC_CONFIG * pSpatialSpecificConfig)1913*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecDecodeHeader(
1914*e5436536SAndroid Build Coastguard Worker     spatialDec *self, SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig) {
1915*e5436536SAndroid Build Coastguard Worker   SACDEC_ERROR err = MPS_OK;
1916*e5436536SAndroid Build Coastguard Worker   int i;
1917*e5436536SAndroid Build Coastguard Worker 
1918*e5436536SAndroid Build Coastguard Worker   self->samplingFreq = pSpatialSpecificConfig->samplingFreq;
1919*e5436536SAndroid Build Coastguard Worker   self->timeSlots = pSpatialSpecificConfig->nTimeSlots;
1920*e5436536SAndroid Build Coastguard Worker   self->frameLength = self->timeSlots * self->qmfBands;
1921*e5436536SAndroid Build Coastguard Worker   self->bitstreamParameterBands = pSpatialSpecificConfig->freqRes;
1922*e5436536SAndroid Build Coastguard Worker 
1923*e5436536SAndroid Build Coastguard Worker   if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD)
1924*e5436536SAndroid Build Coastguard Worker     self->hybridBands = self->qmfBands;
1925*e5436536SAndroid Build Coastguard Worker   else
1926*e5436536SAndroid Build Coastguard Worker     self->hybridBands = SacGetHybridSubbands(self->qmfBands);
1927*e5436536SAndroid Build Coastguard Worker   self->tp_hybBandBorder = 12;
1928*e5436536SAndroid Build Coastguard Worker 
1929*e5436536SAndroid Build Coastguard Worker   self->numParameterBands = self->bitstreamParameterBands;
1930*e5436536SAndroid Build Coastguard Worker 
1931*e5436536SAndroid Build Coastguard Worker   if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
1932*e5436536SAndroid Build Coastguard Worker     switch (self->numParameterBands) {
1933*e5436536SAndroid Build Coastguard Worker       case 4:
1934*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_4_to_64;
1935*e5436536SAndroid Build Coastguard Worker         break;
1936*e5436536SAndroid Build Coastguard Worker       case 5:
1937*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_5_to_64;
1938*e5436536SAndroid Build Coastguard Worker         break;
1939*e5436536SAndroid Build Coastguard Worker       case 7:
1940*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_7_to_64;
1941*e5436536SAndroid Build Coastguard Worker         break;
1942*e5436536SAndroid Build Coastguard Worker       case 9:
1943*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_9_to_64;
1944*e5436536SAndroid Build Coastguard Worker         break;
1945*e5436536SAndroid Build Coastguard Worker       case 12:
1946*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_12_to_64;
1947*e5436536SAndroid Build Coastguard Worker         break;
1948*e5436536SAndroid Build Coastguard Worker       case 15:
1949*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_15_to_64;
1950*e5436536SAndroid Build Coastguard Worker         break;
1951*e5436536SAndroid Build Coastguard Worker       case 23:
1952*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_23_to_64;
1953*e5436536SAndroid Build Coastguard Worker         break;
1954*e5436536SAndroid Build Coastguard Worker       default:
1955*e5436536SAndroid Build Coastguard Worker         return MPS_INVALID_PARAMETERBANDS; /* unsupported numParameterBands */
1956*e5436536SAndroid Build Coastguard Worker     }
1957*e5436536SAndroid Build Coastguard Worker   } else {
1958*e5436536SAndroid Build Coastguard Worker     switch (self->numParameterBands) {
1959*e5436536SAndroid Build Coastguard Worker       case 4:
1960*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_4_to_71;
1961*e5436536SAndroid Build Coastguard Worker         break;
1962*e5436536SAndroid Build Coastguard Worker       case 5:
1963*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_5_to_71;
1964*e5436536SAndroid Build Coastguard Worker         break;
1965*e5436536SAndroid Build Coastguard Worker       case 7:
1966*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_7_to_71;
1967*e5436536SAndroid Build Coastguard Worker         break;
1968*e5436536SAndroid Build Coastguard Worker       case 10:
1969*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_10_to_71;
1970*e5436536SAndroid Build Coastguard Worker         break;
1971*e5436536SAndroid Build Coastguard Worker       case 14:
1972*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_14_to_71;
1973*e5436536SAndroid Build Coastguard Worker         break;
1974*e5436536SAndroid Build Coastguard Worker       case 20:
1975*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_20_to_71;
1976*e5436536SAndroid Build Coastguard Worker         break;
1977*e5436536SAndroid Build Coastguard Worker       case 28:
1978*e5436536SAndroid Build Coastguard Worker         self->kernels = kernels_28_to_71;
1979*e5436536SAndroid Build Coastguard Worker         break;
1980*e5436536SAndroid Build Coastguard Worker       default:
1981*e5436536SAndroid Build Coastguard Worker         return MPS_INVALID_PARAMETERBANDS; /* unsupported numParameterBands */
1982*e5436536SAndroid Build Coastguard Worker     }
1983*e5436536SAndroid Build Coastguard Worker   }
1984*e5436536SAndroid Build Coastguard Worker 
1985*e5436536SAndroid Build Coastguard Worker   /* create param to hyb band table */
1986*e5436536SAndroid Build Coastguard Worker   FDKmemclear(self->param2hyb, (MAX_PARAMETER_BANDS + 1) * sizeof(int));
1987*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < self->hybridBands; i++) {
1988*e5436536SAndroid Build Coastguard Worker     self->param2hyb[self->kernels[i] + 1] = i + 1;
1989*e5436536SAndroid Build Coastguard Worker   }
1990*e5436536SAndroid Build Coastguard Worker   {
1991*e5436536SAndroid Build Coastguard Worker     int pb = self->kernels[i - 1] + 2;
1992*e5436536SAndroid Build Coastguard Worker     for (; pb < (MAX_PARAMETER_BANDS + 1); pb++) {
1993*e5436536SAndroid Build Coastguard Worker       self->param2hyb[pb] = i;
1994*e5436536SAndroid Build Coastguard Worker     }
1995*e5436536SAndroid Build Coastguard Worker     for (pb = 0; pb < MAX_PARAMETER_BANDS; pb += 1) {
1996*e5436536SAndroid Build Coastguard Worker       self->kernels_width[pb] = self->param2hyb[pb + 1] - self->param2hyb[pb];
1997*e5436536SAndroid Build Coastguard Worker     }
1998*e5436536SAndroid Build Coastguard Worker   }
1999*e5436536SAndroid Build Coastguard Worker 
2000*e5436536SAndroid Build Coastguard Worker   self->treeConfig = pSpatialSpecificConfig->treeConfig;
2001*e5436536SAndroid Build Coastguard Worker 
2002*e5436536SAndroid Build Coastguard Worker   self->numOttBoxes = pSpatialSpecificConfig->nOttBoxes;
2003*e5436536SAndroid Build Coastguard Worker 
2004*e5436536SAndroid Build Coastguard Worker   self->numInputChannels = pSpatialSpecificConfig->nInputChannels;
2005*e5436536SAndroid Build Coastguard Worker 
2006*e5436536SAndroid Build Coastguard Worker   self->numOutputChannels = pSpatialSpecificConfig->nOutputChannels;
2007*e5436536SAndroid Build Coastguard Worker 
2008*e5436536SAndroid Build Coastguard Worker   self->quantMode = pSpatialSpecificConfig->quantMode;
2009*e5436536SAndroid Build Coastguard Worker 
2010*e5436536SAndroid Build Coastguard Worker   self->arbitraryDownmix = pSpatialSpecificConfig->bArbitraryDownmix;
2011*e5436536SAndroid Build Coastguard Worker 
2012*e5436536SAndroid Build Coastguard Worker   self->numM2rows = self->numOutputChannels;
2013*e5436536SAndroid Build Coastguard Worker 
2014*e5436536SAndroid Build Coastguard Worker   {
2015*e5436536SAndroid Build Coastguard Worker     self->residualCoding = 0;
2016*e5436536SAndroid Build Coastguard Worker     if (self->arbitraryDownmix == 2)
2017*e5436536SAndroid Build Coastguard Worker       self->arbitraryDownmix = 1; /* no arbitrary downmix residuals */
2018*e5436536SAndroid Build Coastguard Worker   }
2019*e5436536SAndroid Build Coastguard Worker   if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC)) {
2020*e5436536SAndroid Build Coastguard Worker     self->residualCoding = pSpatialSpecificConfig->bResidualCoding;
2021*e5436536SAndroid Build Coastguard Worker   }
2022*e5436536SAndroid Build Coastguard Worker 
2023*e5436536SAndroid Build Coastguard Worker   self->clipProtectGain__FDK =
2024*e5436536SAndroid Build Coastguard Worker       FX_CFG2FX_DBL(clipGainTable__FDK[pSpatialSpecificConfig->bsFixedGainDMX]);
2025*e5436536SAndroid Build Coastguard Worker   self->clipProtectGainSF__FDK =
2026*e5436536SAndroid Build Coastguard Worker       clipGainSFTable__FDK[pSpatialSpecificConfig->bsFixedGainDMX];
2027*e5436536SAndroid Build Coastguard Worker 
2028*e5436536SAndroid Build Coastguard Worker   self->tempShapeConfig = pSpatialSpecificConfig->tempShapeConfig;
2029*e5436536SAndroid Build Coastguard Worker 
2030*e5436536SAndroid Build Coastguard Worker   self->decorrConfig = pSpatialSpecificConfig->decorrConfig;
2031*e5436536SAndroid Build Coastguard Worker 
2032*e5436536SAndroid Build Coastguard Worker   if (self->upmixType == UPMIXTYPE_BYPASS) {
2033*e5436536SAndroid Build Coastguard Worker     self->numOutputChannels = self->numInputChannels;
2034*e5436536SAndroid Build Coastguard Worker   }
2035*e5436536SAndroid Build Coastguard Worker 
2036*e5436536SAndroid Build Coastguard Worker   self->numOutputChannelsAT = self->numOutputChannels;
2037*e5436536SAndroid Build Coastguard Worker 
2038*e5436536SAndroid Build Coastguard Worker   self->numOttBandsIPD = pSpatialSpecificConfig->numOttBandsIPD;
2039*e5436536SAndroid Build Coastguard Worker   self->phaseCoding = pSpatialSpecificConfig->bsPhaseCoding;
2040*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < self->numOttBoxes; i++) {
2041*e5436536SAndroid Build Coastguard Worker     {
2042*e5436536SAndroid Build Coastguard Worker       self->pConfigCurrent->bitstreamOttBands[i] =
2043*e5436536SAndroid Build Coastguard Worker           self->bitstreamParameterBands;
2044*e5436536SAndroid Build Coastguard Worker     }
2045*e5436536SAndroid Build Coastguard Worker     self->numOttBands[i] = self->pConfigCurrent->bitstreamOttBands[i];
2046*e5436536SAndroid Build Coastguard Worker   } /* i */
2047*e5436536SAndroid Build Coastguard Worker 
2048*e5436536SAndroid Build Coastguard Worker   if (self->residualCoding) {
2049*e5436536SAndroid Build Coastguard Worker     int numBoxes = self->numOttBoxes;
2050*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < numBoxes; i++) {
2051*e5436536SAndroid Build Coastguard Worker       self->residualPresent[i] =
2052*e5436536SAndroid Build Coastguard Worker           pSpatialSpecificConfig->ResidualConfig[i].bResidualPresent;
2053*e5436536SAndroid Build Coastguard Worker 
2054*e5436536SAndroid Build Coastguard Worker       if (self->residualPresent[i]) {
2055*e5436536SAndroid Build Coastguard Worker         self->residualBands[i] =
2056*e5436536SAndroid Build Coastguard Worker             pSpatialSpecificConfig->ResidualConfig[i].nResidualBands;
2057*e5436536SAndroid Build Coastguard Worker         /* conversion from hybrid bands to qmf bands */
2058*e5436536SAndroid Build Coastguard Worker         self->residualQMFBands[i] =
2059*e5436536SAndroid Build Coastguard Worker             fMax(self->param2hyb[self->residualBands[i]] + 3 - 10,
2060*e5436536SAndroid Build Coastguard Worker                  3); /* simplification for the lowest 10 hybrid bands */
2061*e5436536SAndroid Build Coastguard Worker       } else {
2062*e5436536SAndroid Build Coastguard Worker         self->residualBands[i] = 0;
2063*e5436536SAndroid Build Coastguard Worker         self->residualQMFBands[i] = 0;
2064*e5436536SAndroid Build Coastguard Worker       }
2065*e5436536SAndroid Build Coastguard Worker     }
2066*e5436536SAndroid Build Coastguard Worker   } /* self->residualCoding */
2067*e5436536SAndroid Build Coastguard Worker   else {
2068*e5436536SAndroid Build Coastguard Worker     int boxes = self->numOttBoxes;
2069*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < boxes; i += 1) {
2070*e5436536SAndroid Build Coastguard Worker       self->residualPresent[i] = 0;
2071*e5436536SAndroid Build Coastguard Worker       self->residualBands[i] = 0;
2072*e5436536SAndroid Build Coastguard Worker     }
2073*e5436536SAndroid Build Coastguard Worker   }
2074*e5436536SAndroid Build Coastguard Worker 
2075*e5436536SAndroid Build Coastguard Worker   switch (self->treeConfig) {
2076*e5436536SAndroid Build Coastguard Worker     case TREE_212:
2077*e5436536SAndroid Build Coastguard Worker       self->numDirektSignals = 1;
2078*e5436536SAndroid Build Coastguard Worker       self->numDecorSignals = 1;
2079*e5436536SAndroid Build Coastguard Worker       self->numXChannels = 1;
2080*e5436536SAndroid Build Coastguard Worker       if (self->arbitraryDownmix == 2) {
2081*e5436536SAndroid Build Coastguard Worker         self->numXChannels += 1;
2082*e5436536SAndroid Build Coastguard Worker       }
2083*e5436536SAndroid Build Coastguard Worker       self->numVChannels = self->numDirektSignals + self->numDecorSignals;
2084*e5436536SAndroid Build Coastguard Worker       break;
2085*e5436536SAndroid Build Coastguard Worker     default:
2086*e5436536SAndroid Build Coastguard Worker       return MPS_INVALID_TREECONFIG;
2087*e5436536SAndroid Build Coastguard Worker   }
2088*e5436536SAndroid Build Coastguard Worker 
2089*e5436536SAndroid Build Coastguard Worker   self->highRateMode = pSpatialSpecificConfig->bsHighRateMode;
2090*e5436536SAndroid Build Coastguard Worker   self->decorrType = pSpatialSpecificConfig->bsDecorrType;
2091*e5436536SAndroid Build Coastguard Worker 
2092*e5436536SAndroid Build Coastguard Worker   SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, UPMIXTYPE_NORMAL);
2093*e5436536SAndroid Build Coastguard Worker 
2094*e5436536SAndroid Build Coastguard Worker   return err;
2095*e5436536SAndroid Build Coastguard Worker }
2096*e5436536SAndroid Build Coastguard Worker 
2097*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
2098*e5436536SAndroid Build Coastguard Worker  Functionname: SpatialDecCreateBsFrame
2099*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
2100*e5436536SAndroid Build Coastguard Worker 
2101*e5436536SAndroid Build Coastguard Worker  Description: Create spatial bitstream structure
2102*e5436536SAndroid Build Coastguard Worker 
2103*e5436536SAndroid Build Coastguard Worker  Arguments:   spatialDec* self
2104*e5436536SAndroid Build Coastguard Worker               const SPATIAL_BS_FRAME **bsFrame
2105*e5436536SAndroid Build Coastguard Worker 
2106*e5436536SAndroid Build Coastguard Worker  Return:      -
2107*e5436536SAndroid Build Coastguard Worker 
2108*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
SpatialDecCreateBsFrame(SPATIAL_BS_FRAME * bsFrame,BS_LL_STATE * llState)2109*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecCreateBsFrame(SPATIAL_BS_FRAME *bsFrame,
2110*e5436536SAndroid Build Coastguard Worker                                      BS_LL_STATE *llState) {
2111*e5436536SAndroid Build Coastguard Worker   SPATIAL_BS_FRAME *pBs = bsFrame;
2112*e5436536SAndroid Build Coastguard Worker 
2113*e5436536SAndroid Build Coastguard Worker   const int maxNumOtt = MAX_NUM_OTT;
2114*e5436536SAndroid Build Coastguard Worker   const int maxNumInputChannels = MAX_INPUT_CHANNELS;
2115*e5436536SAndroid Build Coastguard Worker 
2116*e5436536SAndroid Build Coastguard Worker   FDK_ALLOCATE_MEMORY_1D_P(
2117*e5436536SAndroid Build Coastguard Worker       pBs->cmpOttIPDidx, maxNumOtt * MAX_PARAMETER_SETS * MAX_PARAMETER_BANDS,
2118*e5436536SAndroid Build Coastguard Worker       SCHAR, SCHAR(*)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS])
2119*e5436536SAndroid Build Coastguard Worker 
2120*e5436536SAndroid Build Coastguard Worker   /* Arbitrary Downmix */
2121*e5436536SAndroid Build Coastguard Worker   FDK_ALLOCATE_MEMORY_1D_P(
2122*e5436536SAndroid Build Coastguard Worker       pBs->cmpArbdmxGainIdx,
2123*e5436536SAndroid Build Coastguard Worker       maxNumInputChannels * MAX_PARAMETER_SETS * MAX_PARAMETER_BANDS, SCHAR,
2124*e5436536SAndroid Build Coastguard Worker       SCHAR(*)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS])
2125*e5436536SAndroid Build Coastguard Worker 
2126*e5436536SAndroid Build Coastguard Worker   /* Lossless control */
2127*e5436536SAndroid Build Coastguard Worker   FDK_ALLOCATE_MEMORY_1D(pBs->CLDLosslessData, MAX_NUM_PARAMETERS, LOSSLESSDATA)
2128*e5436536SAndroid Build Coastguard Worker   FDK_ALLOCATE_MEMORY_1D(pBs->ICCLosslessData, MAX_NUM_PARAMETERS, LOSSLESSDATA)
2129*e5436536SAndroid Build Coastguard Worker 
2130*e5436536SAndroid Build Coastguard Worker   FDK_ALLOCATE_MEMORY_1D(pBs->IPDLosslessData, MAX_NUM_PARAMETERS, LOSSLESSDATA)
2131*e5436536SAndroid Build Coastguard Worker 
2132*e5436536SAndroid Build Coastguard Worker   pBs->newBsData = 0;
2133*e5436536SAndroid Build Coastguard Worker   pBs->numParameterSets = 1;
2134*e5436536SAndroid Build Coastguard Worker 
2135*e5436536SAndroid Build Coastguard Worker   /* Link lossless states */
2136*e5436536SAndroid Build Coastguard Worker   for (int x = 0; x < MAX_NUM_PARAMETERS; x++) {
2137*e5436536SAndroid Build Coastguard Worker     pBs->CLDLosslessData[x].state = &llState->CLDLosslessState[x];
2138*e5436536SAndroid Build Coastguard Worker     pBs->ICCLosslessData[x].state = &llState->ICCLosslessState[x];
2139*e5436536SAndroid Build Coastguard Worker 
2140*e5436536SAndroid Build Coastguard Worker     pBs->IPDLosslessData[x].state = &llState->IPDLosslessState[x];
2141*e5436536SAndroid Build Coastguard Worker   }
2142*e5436536SAndroid Build Coastguard Worker 
2143*e5436536SAndroid Build Coastguard Worker   return MPS_OK;
2144*e5436536SAndroid Build Coastguard Worker 
2145*e5436536SAndroid Build Coastguard Worker bail:
2146*e5436536SAndroid Build Coastguard Worker   return MPS_OUTOFMEMORY;
2147*e5436536SAndroid Build Coastguard Worker }
2148*e5436536SAndroid Build Coastguard Worker 
2149*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
2150*e5436536SAndroid Build Coastguard Worker  Functionname: SpatialDecCloseBsFrame
2151*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
2152*e5436536SAndroid Build Coastguard Worker 
2153*e5436536SAndroid Build Coastguard Worker  Description: Close spatial bitstream structure
2154*e5436536SAndroid Build Coastguard Worker 
2155*e5436536SAndroid Build Coastguard Worker  Arguments:   spatialDec* self
2156*e5436536SAndroid Build Coastguard Worker 
2157*e5436536SAndroid Build Coastguard Worker  Return:      -
2158*e5436536SAndroid Build Coastguard Worker 
2159*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
SpatialDecCloseBsFrame(SPATIAL_BS_FRAME * pBs)2160*e5436536SAndroid Build Coastguard Worker void SpatialDecCloseBsFrame(SPATIAL_BS_FRAME *pBs) {
2161*e5436536SAndroid Build Coastguard Worker   if (pBs != NULL) {
2162*e5436536SAndroid Build Coastguard Worker     /* These arrays contain the compact indices, only one value per pbstride,
2163*e5436536SAndroid Build Coastguard Worker      * only paramsets actually containing data. */
2164*e5436536SAndroid Build Coastguard Worker 
2165*e5436536SAndroid Build Coastguard Worker     FDK_FREE_MEMORY_1D(pBs->cmpOttIPDidx);
2166*e5436536SAndroid Build Coastguard Worker 
2167*e5436536SAndroid Build Coastguard Worker     /* Arbitrary Downmix */
2168*e5436536SAndroid Build Coastguard Worker     FDK_FREE_MEMORY_1D(pBs->cmpArbdmxGainIdx);
2169*e5436536SAndroid Build Coastguard Worker 
2170*e5436536SAndroid Build Coastguard Worker     /* Lossless control */
2171*e5436536SAndroid Build Coastguard Worker     FDK_FREE_MEMORY_1D(pBs->IPDLosslessData);
2172*e5436536SAndroid Build Coastguard Worker     FDK_FREE_MEMORY_1D(pBs->CLDLosslessData);
2173*e5436536SAndroid Build Coastguard Worker     FDK_FREE_MEMORY_1D(pBs->ICCLosslessData);
2174*e5436536SAndroid Build Coastguard Worker   }
2175*e5436536SAndroid Build Coastguard Worker }
2176