xref: /aosp_15_r20/external/aac/libAACdec/src/rvlc.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 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** AAC decoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description:
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker /*!
104*e5436536SAndroid Build Coastguard Worker   \file
105*e5436536SAndroid Build Coastguard Worker   \brief  RVLC Decoder
106*e5436536SAndroid Build Coastguard Worker   \author Robert Weidner
107*e5436536SAndroid Build Coastguard Worker */
108*e5436536SAndroid Build Coastguard Worker 
109*e5436536SAndroid Build Coastguard Worker #include "rvlc.h"
110*e5436536SAndroid Build Coastguard Worker 
111*e5436536SAndroid Build Coastguard Worker #include "block.h"
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker #include "aac_rom.h"
114*e5436536SAndroid Build Coastguard Worker #include "rvlcbit.h"
115*e5436536SAndroid Build Coastguard Worker #include "rvlcconceal.h"
116*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr.h"
117*e5436536SAndroid Build Coastguard Worker 
118*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
119*e5436536SAndroid Build Coastguard Worker      function:     rvlcInit
120*e5436536SAndroid Build Coastguard Worker 
121*e5436536SAndroid Build Coastguard Worker      description:  init RVLC by data from channelinfo, which was decoded
122*e5436536SAndroid Build Coastguard Worker previously and set up pointers
123*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
124*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
125*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
126*e5436536SAndroid Build Coastguard Worker                    - pointer bitstream structure
127*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
128*e5436536SAndroid Build Coastguard Worker         return:    -
129*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
130*e5436536SAndroid Build Coastguard Worker */
131*e5436536SAndroid Build Coastguard Worker 
rvlcInit(CErRvlcInfo * pRvlc,CAacDecoderChannelInfo * pAacDecoderChannelInfo,HANDLE_FDK_BITSTREAM bs)132*e5436536SAndroid Build Coastguard Worker static void rvlcInit(CErRvlcInfo *pRvlc,
133*e5436536SAndroid Build Coastguard Worker                      CAacDecoderChannelInfo *pAacDecoderChannelInfo,
134*e5436536SAndroid Build Coastguard Worker                      HANDLE_FDK_BITSTREAM bs) {
135*e5436536SAndroid Build Coastguard Worker   /* RVLC common initialization part 2 of 2 */
136*e5436536SAndroid Build Coastguard Worker   SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
137*e5436536SAndroid Build Coastguard Worker   SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
138*e5436536SAndroid Build Coastguard Worker   SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
139*e5436536SAndroid Build Coastguard Worker   SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
140*e5436536SAndroid Build Coastguard Worker   int bnds;
141*e5436536SAndroid Build Coastguard Worker 
142*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = 0;
143*e5436536SAndroid Build Coastguard Worker 
144*e5436536SAndroid Build Coastguard Worker   pRvlc->numDecodedEscapeWordsEsc = 0;
145*e5436536SAndroid Build Coastguard Worker   pRvlc->numDecodedEscapeWordsFwd = 0;
146*e5436536SAndroid Build Coastguard Worker   pRvlc->numDecodedEscapeWordsBwd = 0;
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker   pRvlc->intensity_used = 0;
149*e5436536SAndroid Build Coastguard Worker   pRvlc->errorLogRvlc = 0;
150*e5436536SAndroid Build Coastguard Worker 
151*e5436536SAndroid Build Coastguard Worker   pRvlc->conceal_max = CONCEAL_MAX_INIT;
152*e5436536SAndroid Build Coastguard Worker   pRvlc->conceal_min = CONCEAL_MIN_INIT;
153*e5436536SAndroid Build Coastguard Worker 
154*e5436536SAndroid Build Coastguard Worker   pRvlc->conceal_max_esc = CONCEAL_MAX_INIT;
155*e5436536SAndroid Build Coastguard Worker   pRvlc->conceal_min_esc = CONCEAL_MIN_INIT;
156*e5436536SAndroid Build Coastguard Worker 
157*e5436536SAndroid Build Coastguard Worker   pRvlc->pHuffTreeRvlcEscape = aHuffTreeRvlcEscape;
158*e5436536SAndroid Build Coastguard Worker   pRvlc->pHuffTreeRvlCodewds = aHuffTreeRvlCodewds;
159*e5436536SAndroid Build Coastguard Worker 
160*e5436536SAndroid Build Coastguard Worker   /* init scf arrays (for savety (in case of there are only zero codebooks)) */
161*e5436536SAndroid Build Coastguard Worker   for (bnds = 0; bnds < RVLC_MAX_SFB; bnds++) {
162*e5436536SAndroid Build Coastguard Worker     pScfFwd[bnds] = 0;
163*e5436536SAndroid Build Coastguard Worker     pScfBwd[bnds] = 0;
164*e5436536SAndroid Build Coastguard Worker     pScfEsc[bnds] = 0;
165*e5436536SAndroid Build Coastguard Worker     pScaleFactor[bnds] = 0;
166*e5436536SAndroid Build Coastguard Worker   }
167*e5436536SAndroid Build Coastguard Worker 
168*e5436536SAndroid Build Coastguard Worker   /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2))
169*e5436536SAndroid Build Coastguard Worker    */
170*e5436536SAndroid Build Coastguard Worker   FDKsyncCache(bs);
171*e5436536SAndroid Build Coastguard Worker   pRvlc->bsAnchor = (INT)FDKgetValidBits(bs);
172*e5436536SAndroid Build Coastguard Worker 
173*e5436536SAndroid Build Coastguard Worker   pRvlc->bitstreamIndexRvlFwd =
174*e5436536SAndroid Build Coastguard Worker       0; /* first bit within RVL coded block as start address for  forward
175*e5436536SAndroid Build Coastguard Worker             decoding */
176*e5436536SAndroid Build Coastguard Worker   pRvlc->bitstreamIndexRvlBwd =
177*e5436536SAndroid Build Coastguard Worker       pRvlc->length_of_rvlc_sf - 1; /* last bit within RVL coded block as start
178*e5436536SAndroid Build Coastguard Worker                                        address for backward decoding */
179*e5436536SAndroid Build Coastguard Worker 
180*e5436536SAndroid Build Coastguard Worker   /* skip RVLC-bitstream-part -- pointing now to escapes (if present) or to TNS
181*e5436536SAndroid Build Coastguard Worker    * data (if present) */
182*e5436536SAndroid Build Coastguard Worker   FDKpushFor(bs, pRvlc->length_of_rvlc_sf);
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker   if (pRvlc->sf_escapes_present != 0) {
185*e5436536SAndroid Build Coastguard Worker     /* locate internal bitstream ptr at escapes (which is the second part) */
186*e5436536SAndroid Build Coastguard Worker     FDKsyncCache(bs);
187*e5436536SAndroid Build Coastguard Worker     pRvlc->bitstreamIndexEsc = pRvlc->bsAnchor - (INT)FDKgetValidBits(bs);
188*e5436536SAndroid Build Coastguard Worker 
189*e5436536SAndroid Build Coastguard Worker     /* skip escapeRVLC-bitstream-part -- pointing to TNS data (if present)   to
190*e5436536SAndroid Build Coastguard Worker      * make decoder continue */
191*e5436536SAndroid Build Coastguard Worker     /* decoding of RVLC should work despite this second pushFor during
192*e5436536SAndroid Build Coastguard Worker      * initialization because        */
193*e5436536SAndroid Build Coastguard Worker     /* bitstream initialization is valid for both ESC2 data parts (RVL-coded
194*e5436536SAndroid Build Coastguard Worker      * values and ESC-coded values) */
195*e5436536SAndroid Build Coastguard Worker     FDKpushFor(bs, pRvlc->length_of_rvlc_escapes);
196*e5436536SAndroid Build Coastguard Worker   }
197*e5436536SAndroid Build Coastguard Worker }
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
200*e5436536SAndroid Build Coastguard Worker      function:     rvlcCheckIntensityCb
201*e5436536SAndroid Build Coastguard Worker 
202*e5436536SAndroid Build Coastguard Worker      description:  Check if a intensity codebook is used in the current channel.
203*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
204*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
205*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
206*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
207*e5436536SAndroid Build Coastguard Worker         output:    - intensity_used: 0 no intensity codebook is used
208*e5436536SAndroid Build Coastguard Worker                                      1 intensity codebook is used
209*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
210*e5436536SAndroid Build Coastguard Worker         return:    -
211*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
212*e5436536SAndroid Build Coastguard Worker */
213*e5436536SAndroid Build Coastguard Worker 
rvlcCheckIntensityCb(CErRvlcInfo * pRvlc,CAacDecoderChannelInfo * pAacDecoderChannelInfo)214*e5436536SAndroid Build Coastguard Worker static void rvlcCheckIntensityCb(
215*e5436536SAndroid Build Coastguard Worker     CErRvlcInfo *pRvlc, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
216*e5436536SAndroid Build Coastguard Worker   int group, band, bnds;
217*e5436536SAndroid Build Coastguard Worker 
218*e5436536SAndroid Build Coastguard Worker   pRvlc->intensity_used = 0;
219*e5436536SAndroid Build Coastguard Worker 
220*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < pRvlc->numWindowGroups; group++) {
221*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
222*e5436536SAndroid Build Coastguard Worker       bnds = 16 * group + band;
223*e5436536SAndroid Build Coastguard Worker       if ((pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
224*e5436536SAndroid Build Coastguard Worker            INTENSITY_HCB) ||
225*e5436536SAndroid Build Coastguard Worker           (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
226*e5436536SAndroid Build Coastguard Worker            INTENSITY_HCB2)) {
227*e5436536SAndroid Build Coastguard Worker         pRvlc->intensity_used = 1;
228*e5436536SAndroid Build Coastguard Worker         break;
229*e5436536SAndroid Build Coastguard Worker       }
230*e5436536SAndroid Build Coastguard Worker     }
231*e5436536SAndroid Build Coastguard Worker   }
232*e5436536SAndroid Build Coastguard Worker }
233*e5436536SAndroid Build Coastguard Worker 
234*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
235*e5436536SAndroid Build Coastguard Worker      function:     rvlcDecodeEscapeWord
236*e5436536SAndroid Build Coastguard Worker 
237*e5436536SAndroid Build Coastguard Worker      description:  Decode a huffman coded RVLC Escape-word. This value is part
238*e5436536SAndroid Build Coastguard Worker of a DPCM coded scalefactor.
239*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
240*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
241*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
242*e5436536SAndroid Build Coastguard Worker         return:    - a single RVLC-Escape value which had to be applied to a
243*e5436536SAndroid Build Coastguard Worker DPCM value (which has a absolute value of 7)
244*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
245*e5436536SAndroid Build Coastguard Worker */
246*e5436536SAndroid Build Coastguard Worker 
rvlcDecodeEscapeWord(CErRvlcInfo * pRvlc,HANDLE_FDK_BITSTREAM bs)247*e5436536SAndroid Build Coastguard Worker static SCHAR rvlcDecodeEscapeWord(CErRvlcInfo *pRvlc, HANDLE_FDK_BITSTREAM bs) {
248*e5436536SAndroid Build Coastguard Worker   int i;
249*e5436536SAndroid Build Coastguard Worker   SCHAR value;
250*e5436536SAndroid Build Coastguard Worker   UCHAR carryBit;
251*e5436536SAndroid Build Coastguard Worker   UINT treeNode;
252*e5436536SAndroid Build Coastguard Worker   UINT branchValue;
253*e5436536SAndroid Build Coastguard Worker   UINT branchNode;
254*e5436536SAndroid Build Coastguard Worker 
255*e5436536SAndroid Build Coastguard Worker   INT *pBitstreamIndexEsc;
256*e5436536SAndroid Build Coastguard Worker   const UINT *pEscTree;
257*e5436536SAndroid Build Coastguard Worker 
258*e5436536SAndroid Build Coastguard Worker   pEscTree = pRvlc->pHuffTreeRvlcEscape;
259*e5436536SAndroid Build Coastguard Worker   pBitstreamIndexEsc = &(pRvlc->bitstreamIndexEsc);
260*e5436536SAndroid Build Coastguard Worker   treeNode = *pEscTree; /* init at starting node */
261*e5436536SAndroid Build Coastguard Worker 
262*e5436536SAndroid Build Coastguard Worker   for (i = MAX_LEN_RVLC_ESCAPE_WORD - 1; i >= 0; i--) {
263*e5436536SAndroid Build Coastguard Worker     carryBit =
264*e5436536SAndroid Build Coastguard Worker         rvlcReadBitFromBitstream(bs, /* get next bit */
265*e5436536SAndroid Build Coastguard Worker                                  pRvlc->bsAnchor, pBitstreamIndexEsc, FWD);
266*e5436536SAndroid Build Coastguard Worker 
267*e5436536SAndroid Build Coastguard Worker     CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
268*e5436536SAndroid Build Coastguard Worker                                        huffman decoding tree */
269*e5436536SAndroid Build Coastguard Worker                           treeNode, &branchValue, &branchNode);
270*e5436536SAndroid Build Coastguard Worker 
271*e5436536SAndroid Build Coastguard Worker     if ((branchNode & TEST_BIT_10) ==
272*e5436536SAndroid Build Coastguard Worker         TEST_BIT_10) { /* test bit 10 ; if set --> a RVLC-escape-word is
273*e5436536SAndroid Build Coastguard Worker                           completely decoded */
274*e5436536SAndroid Build Coastguard Worker       value = (SCHAR)branchNode & CLR_BIT_10;
275*e5436536SAndroid Build Coastguard Worker       pRvlc->length_of_rvlc_escapes -= (MAX_LEN_RVLC_ESCAPE_WORD - i);
276*e5436536SAndroid Build Coastguard Worker 
277*e5436536SAndroid Build Coastguard Worker       if (pRvlc->length_of_rvlc_escapes < 0) {
278*e5436536SAndroid Build Coastguard Worker         pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
279*e5436536SAndroid Build Coastguard Worker         value = -1;
280*e5436536SAndroid Build Coastguard Worker       }
281*e5436536SAndroid Build Coastguard Worker 
282*e5436536SAndroid Build Coastguard Worker       return value;
283*e5436536SAndroid Build Coastguard Worker     } else {
284*e5436536SAndroid Build Coastguard Worker       treeNode = *(
285*e5436536SAndroid Build Coastguard Worker           pEscTree +
286*e5436536SAndroid Build Coastguard Worker           branchValue); /* update treeNode for further step in decoding tree */
287*e5436536SAndroid Build Coastguard Worker     }
288*e5436536SAndroid Build Coastguard Worker   }
289*e5436536SAndroid Build Coastguard Worker 
290*e5436536SAndroid Build Coastguard Worker   pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
291*e5436536SAndroid Build Coastguard Worker 
292*e5436536SAndroid Build Coastguard Worker   return -1; /* should not be reached */
293*e5436536SAndroid Build Coastguard Worker }
294*e5436536SAndroid Build Coastguard Worker 
295*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
296*e5436536SAndroid Build Coastguard Worker      function:     rvlcDecodeEscapes
297*e5436536SAndroid Build Coastguard Worker 
298*e5436536SAndroid Build Coastguard Worker      description:  Decodes all huffman coded RVLC Escape Words.
299*e5436536SAndroid Build Coastguard Worker                    Here a difference to the pseudo-code-implementation from
300*e5436536SAndroid Build Coastguard Worker standard can be found. A while loop (and not two nested for loops) is used for
301*e5436536SAndroid Build Coastguard Worker two reasons:
302*e5436536SAndroid Build Coastguard Worker 
303*e5436536SAndroid Build Coastguard Worker                    1. The plain huffman encoded escapes are decoded before the
304*e5436536SAndroid Build Coastguard Worker RVL-coded scalefactors. Therefore the escapes are present in the second step
305*e5436536SAndroid Build Coastguard Worker                       when decoding the RVL-coded-scalefactor values in forward
306*e5436536SAndroid Build Coastguard Worker and backward direction.
307*e5436536SAndroid Build Coastguard Worker 
308*e5436536SAndroid Build Coastguard Worker                       When the RVL-coded scalefactors are decoded and there a
309*e5436536SAndroid Build Coastguard Worker escape is needed, then it is just taken out of the array in ascending order.
310*e5436536SAndroid Build Coastguard Worker 
311*e5436536SAndroid Build Coastguard Worker                    2. It's faster.
312*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
313*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
314*e5436536SAndroid Build Coastguard Worker                    - handle to FDK bitstream
315*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
316*e5436536SAndroid Build Coastguard Worker         return:    - 0 ok     the decoded escapes seem to be valid
317*e5436536SAndroid Build Coastguard Worker                    - 1 error  there was a error detected during decoding escapes
318*e5436536SAndroid Build Coastguard Worker                               --> all escapes are invalid
319*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
320*e5436536SAndroid Build Coastguard Worker */
321*e5436536SAndroid Build Coastguard Worker 
rvlcDecodeEscapes(CErRvlcInfo * pRvlc,SHORT * pEsc,HANDLE_FDK_BITSTREAM bs)322*e5436536SAndroid Build Coastguard Worker static void rvlcDecodeEscapes(CErRvlcInfo *pRvlc, SHORT *pEsc,
323*e5436536SAndroid Build Coastguard Worker                               HANDLE_FDK_BITSTREAM bs) {
324*e5436536SAndroid Build Coastguard Worker   SCHAR escWord;
325*e5436536SAndroid Build Coastguard Worker   SCHAR escCnt = 0;
326*e5436536SAndroid Build Coastguard Worker   SHORT *pEscBitCntSum;
327*e5436536SAndroid Build Coastguard Worker 
328*e5436536SAndroid Build Coastguard Worker   pEscBitCntSum = &(pRvlc->length_of_rvlc_escapes);
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker   /* Decode all RVLC-Escape words with a plain Huffman-Decoder */
331*e5436536SAndroid Build Coastguard Worker   while (*pEscBitCntSum > 0) {
332*e5436536SAndroid Build Coastguard Worker     escWord = rvlcDecodeEscapeWord(pRvlc, bs);
333*e5436536SAndroid Build Coastguard Worker 
334*e5436536SAndroid Build Coastguard Worker     if (escWord >= 0) {
335*e5436536SAndroid Build Coastguard Worker       pEsc[escCnt] = escWord;
336*e5436536SAndroid Build Coastguard Worker       escCnt++;
337*e5436536SAndroid Build Coastguard Worker     } else {
338*e5436536SAndroid Build Coastguard Worker       pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
339*e5436536SAndroid Build Coastguard Worker       pRvlc->numDecodedEscapeWordsEsc = escCnt;
340*e5436536SAndroid Build Coastguard Worker 
341*e5436536SAndroid Build Coastguard Worker       return;
342*e5436536SAndroid Build Coastguard Worker     }
343*e5436536SAndroid Build Coastguard Worker   } /* all RVLC escapes decoded */
344*e5436536SAndroid Build Coastguard Worker 
345*e5436536SAndroid Build Coastguard Worker   pRvlc->numDecodedEscapeWordsEsc = escCnt;
346*e5436536SAndroid Build Coastguard Worker }
347*e5436536SAndroid Build Coastguard Worker 
348*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
349*e5436536SAndroid Build Coastguard Worker      function:     decodeRVLCodeword
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker      description:  Decodes a RVL-coded dpcm-word (-part).
352*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
353*e5436536SAndroid Build Coastguard Worker         input:     - FDK bitstream handle
354*e5436536SAndroid Build Coastguard Worker                    - pointer rvlc structure
355*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
356*e5436536SAndroid Build Coastguard Worker         return:    - a dpcm value which is within range [0,1,..,14] in case of
357*e5436536SAndroid Build Coastguard Worker no errors. The offset of 7 must be subtracted to get a valid dpcm scalefactor
358*e5436536SAndroid Build Coastguard Worker value. In case of errors a forbidden codeword is detected --> returning -1
359*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
360*e5436536SAndroid Build Coastguard Worker */
361*e5436536SAndroid Build Coastguard Worker 
decodeRVLCodeword(HANDLE_FDK_BITSTREAM bs,CErRvlcInfo * pRvlc)362*e5436536SAndroid Build Coastguard Worker SCHAR decodeRVLCodeword(HANDLE_FDK_BITSTREAM bs, CErRvlcInfo *pRvlc) {
363*e5436536SAndroid Build Coastguard Worker   int i;
364*e5436536SAndroid Build Coastguard Worker   SCHAR value;
365*e5436536SAndroid Build Coastguard Worker   UCHAR carryBit;
366*e5436536SAndroid Build Coastguard Worker   UINT branchValue;
367*e5436536SAndroid Build Coastguard Worker   UINT branchNode;
368*e5436536SAndroid Build Coastguard Worker 
369*e5436536SAndroid Build Coastguard Worker   const UINT *pRvlCodeTree = pRvlc->pHuffTreeRvlCodewds;
370*e5436536SAndroid Build Coastguard Worker   UCHAR direction = pRvlc->direction;
371*e5436536SAndroid Build Coastguard Worker   INT *pBitstrIndxRvl = pRvlc->pBitstrIndxRvl_RVL;
372*e5436536SAndroid Build Coastguard Worker   UINT treeNode = *pRvlCodeTree;
373*e5436536SAndroid Build Coastguard Worker 
374*e5436536SAndroid Build Coastguard Worker   for (i = MAX_LEN_RVLC_CODE_WORD - 1; i >= 0; i--) {
375*e5436536SAndroid Build Coastguard Worker     carryBit =
376*e5436536SAndroid Build Coastguard Worker         rvlcReadBitFromBitstream(bs, /* get next bit */
377*e5436536SAndroid Build Coastguard Worker                                  pRvlc->bsAnchor, pBitstrIndxRvl, direction);
378*e5436536SAndroid Build Coastguard Worker 
379*e5436536SAndroid Build Coastguard Worker     CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
380*e5436536SAndroid Build Coastguard Worker                                        huffman decoding tree */
381*e5436536SAndroid Build Coastguard Worker                           treeNode, &branchValue, &branchNode);
382*e5436536SAndroid Build Coastguard Worker 
383*e5436536SAndroid Build Coastguard Worker     if ((branchNode & TEST_BIT_10) ==
384*e5436536SAndroid Build Coastguard Worker         TEST_BIT_10) { /* test bit 10 ; if set --> a
385*e5436536SAndroid Build Coastguard Worker                           RVLC-codeword is completely decoded
386*e5436536SAndroid Build Coastguard Worker                         */
387*e5436536SAndroid Build Coastguard Worker       value = (SCHAR)(branchNode & CLR_BIT_10);
388*e5436536SAndroid Build Coastguard Worker       *pRvlc->pRvlBitCnt_RVL -= (MAX_LEN_RVLC_CODE_WORD - i);
389*e5436536SAndroid Build Coastguard Worker 
390*e5436536SAndroid Build Coastguard Worker       /* check available bits for decoding */
391*e5436536SAndroid Build Coastguard Worker       if (*pRvlc->pRvlBitCnt_RVL < 0) {
392*e5436536SAndroid Build Coastguard Worker         if (direction == FWD) {
393*e5436536SAndroid Build Coastguard Worker           pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD;
394*e5436536SAndroid Build Coastguard Worker         } else {
395*e5436536SAndroid Build Coastguard Worker           pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD;
396*e5436536SAndroid Build Coastguard Worker         }
397*e5436536SAndroid Build Coastguard Worker         value = -1; /* signalize an error in return value, because too many bits
398*e5436536SAndroid Build Coastguard Worker                        was decoded */
399*e5436536SAndroid Build Coastguard Worker       }
400*e5436536SAndroid Build Coastguard Worker 
401*e5436536SAndroid Build Coastguard Worker       /* check max value of dpcm value */
402*e5436536SAndroid Build Coastguard Worker       if (value > MAX_ALLOWED_DPCM_INDEX) {
403*e5436536SAndroid Build Coastguard Worker         if (direction == FWD) {
404*e5436536SAndroid Build Coastguard Worker           pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD;
405*e5436536SAndroid Build Coastguard Worker         } else {
406*e5436536SAndroid Build Coastguard Worker           pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD;
407*e5436536SAndroid Build Coastguard Worker         }
408*e5436536SAndroid Build Coastguard Worker         value = -1; /* signalize an error in return value, because a forbidden
409*e5436536SAndroid Build Coastguard Worker                        cw was detected*/
410*e5436536SAndroid Build Coastguard Worker       }
411*e5436536SAndroid Build Coastguard Worker 
412*e5436536SAndroid Build Coastguard Worker       return value; /* return a dpcm value with offset +7 or an error status */
413*e5436536SAndroid Build Coastguard Worker     } else {
414*e5436536SAndroid Build Coastguard Worker       treeNode = *(
415*e5436536SAndroid Build Coastguard Worker           pRvlCodeTree +
416*e5436536SAndroid Build Coastguard Worker           branchValue); /* update treeNode for further step in decoding tree */
417*e5436536SAndroid Build Coastguard Worker     }
418*e5436536SAndroid Build Coastguard Worker   }
419*e5436536SAndroid Build Coastguard Worker 
420*e5436536SAndroid Build Coastguard Worker   return -1;
421*e5436536SAndroid Build Coastguard Worker }
422*e5436536SAndroid Build Coastguard Worker 
423*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
424*e5436536SAndroid Build Coastguard Worker      function:     rvlcDecodeForward
425*e5436536SAndroid Build Coastguard Worker 
426*e5436536SAndroid Build Coastguard Worker      description:  Decode RVL-coded codewords in forward direction.
427*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
428*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
429*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
430*e5436536SAndroid Build Coastguard Worker                    - handle to FDK bitstream
431*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
432*e5436536SAndroid Build Coastguard Worker         return:    -
433*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
434*e5436536SAndroid Build Coastguard Worker */
435*e5436536SAndroid Build Coastguard Worker 
rvlcDecodeForward(CErRvlcInfo * pRvlc,CAacDecoderChannelInfo * pAacDecoderChannelInfo,HANDLE_FDK_BITSTREAM bs)436*e5436536SAndroid Build Coastguard Worker static void rvlcDecodeForward(CErRvlcInfo *pRvlc,
437*e5436536SAndroid Build Coastguard Worker                               CAacDecoderChannelInfo *pAacDecoderChannelInfo,
438*e5436536SAndroid Build Coastguard Worker                               HANDLE_FDK_BITSTREAM bs) {
439*e5436536SAndroid Build Coastguard Worker   int band = 0;
440*e5436536SAndroid Build Coastguard Worker   int group = 0;
441*e5436536SAndroid Build Coastguard Worker   int bnds = 0;
442*e5436536SAndroid Build Coastguard Worker 
443*e5436536SAndroid Build Coastguard Worker   SHORT dpcm;
444*e5436536SAndroid Build Coastguard Worker 
445*e5436536SAndroid Build Coastguard Worker   SHORT factor =
446*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
447*e5436536SAndroid Build Coastguard Worker   SHORT position = -SF_OFFSET;
448*e5436536SAndroid Build Coastguard Worker   SHORT noisenrg = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
449*e5436536SAndroid Build Coastguard Worker                    SF_OFFSET - 90 - 256;
450*e5436536SAndroid Build Coastguard Worker 
451*e5436536SAndroid Build Coastguard Worker   SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
452*e5436536SAndroid Build Coastguard Worker   SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
453*e5436536SAndroid Build Coastguard Worker   UCHAR *pEscFwdCnt = &(pRvlc->numDecodedEscapeWordsFwd);
454*e5436536SAndroid Build Coastguard Worker 
455*e5436536SAndroid Build Coastguard Worker   pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_fwd);
456*e5436536SAndroid Build Coastguard Worker   pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlFwd);
457*e5436536SAndroid Build Coastguard Worker 
458*e5436536SAndroid Build Coastguard Worker   *pEscFwdCnt = 0;
459*e5436536SAndroid Build Coastguard Worker   pRvlc->direction = FWD;
460*e5436536SAndroid Build Coastguard Worker   pRvlc->noise_used = 0;
461*e5436536SAndroid Build Coastguard Worker   pRvlc->sf_used = 0;
462*e5436536SAndroid Build Coastguard Worker   pRvlc->lastScf = 0;
463*e5436536SAndroid Build Coastguard Worker   pRvlc->lastNrg = 0;
464*e5436536SAndroid Build Coastguard Worker   pRvlc->lastIs = 0;
465*e5436536SAndroid Build Coastguard Worker 
466*e5436536SAndroid Build Coastguard Worker   rvlcCheckIntensityCb(pRvlc, pAacDecoderChannelInfo);
467*e5436536SAndroid Build Coastguard Worker 
468*e5436536SAndroid Build Coastguard Worker   /* main loop fwd long */
469*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < pRvlc->numWindowGroups; group++) {
470*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
471*e5436536SAndroid Build Coastguard Worker       bnds = 16 * group + band;
472*e5436536SAndroid Build Coastguard Worker 
473*e5436536SAndroid Build Coastguard Worker       switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
474*e5436536SAndroid Build Coastguard Worker         case ZERO_HCB:
475*e5436536SAndroid Build Coastguard Worker           pScfFwd[bnds] = 0;
476*e5436536SAndroid Build Coastguard Worker           break;
477*e5436536SAndroid Build Coastguard Worker 
478*e5436536SAndroid Build Coastguard Worker         case INTENSITY_HCB2:
479*e5436536SAndroid Build Coastguard Worker         case INTENSITY_HCB:
480*e5436536SAndroid Build Coastguard Worker           /* store dpcm_is_position */
481*e5436536SAndroid Build Coastguard Worker           dpcm = decodeRVLCodeword(bs, pRvlc);
482*e5436536SAndroid Build Coastguard Worker           if (dpcm < 0) {
483*e5436536SAndroid Build Coastguard Worker             pRvlc->conceal_max = bnds;
484*e5436536SAndroid Build Coastguard Worker             return;
485*e5436536SAndroid Build Coastguard Worker           }
486*e5436536SAndroid Build Coastguard Worker           dpcm -= TABLE_OFFSET;
487*e5436536SAndroid Build Coastguard Worker           if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
488*e5436536SAndroid Build Coastguard Worker             if (pRvlc->length_of_rvlc_escapes) {
489*e5436536SAndroid Build Coastguard Worker               pRvlc->conceal_max = bnds;
490*e5436536SAndroid Build Coastguard Worker               return;
491*e5436536SAndroid Build Coastguard Worker             } else {
492*e5436536SAndroid Build Coastguard Worker               if (dpcm == MIN_RVL) {
493*e5436536SAndroid Build Coastguard Worker                 dpcm -= *pScfEsc++;
494*e5436536SAndroid Build Coastguard Worker               } else {
495*e5436536SAndroid Build Coastguard Worker                 dpcm += *pScfEsc++;
496*e5436536SAndroid Build Coastguard Worker               }
497*e5436536SAndroid Build Coastguard Worker               (*pEscFwdCnt)++;
498*e5436536SAndroid Build Coastguard Worker               if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
499*e5436536SAndroid Build Coastguard Worker                 pRvlc->conceal_max_esc = bnds;
500*e5436536SAndroid Build Coastguard Worker               }
501*e5436536SAndroid Build Coastguard Worker             }
502*e5436536SAndroid Build Coastguard Worker           }
503*e5436536SAndroid Build Coastguard Worker           position += dpcm;
504*e5436536SAndroid Build Coastguard Worker           pScfFwd[bnds] = position;
505*e5436536SAndroid Build Coastguard Worker           pRvlc->lastIs = position;
506*e5436536SAndroid Build Coastguard Worker           break;
507*e5436536SAndroid Build Coastguard Worker 
508*e5436536SAndroid Build Coastguard Worker         case NOISE_HCB:
509*e5436536SAndroid Build Coastguard Worker           if (pRvlc->noise_used == 0) {
510*e5436536SAndroid Build Coastguard Worker             pRvlc->noise_used = 1;
511*e5436536SAndroid Build Coastguard Worker             pRvlc->first_noise_band = bnds;
512*e5436536SAndroid Build Coastguard Worker             noisenrg += pRvlc->dpcm_noise_nrg;
513*e5436536SAndroid Build Coastguard Worker             pScfFwd[bnds] = 100 + noisenrg;
514*e5436536SAndroid Build Coastguard Worker             pRvlc->lastNrg = noisenrg;
515*e5436536SAndroid Build Coastguard Worker           } else {
516*e5436536SAndroid Build Coastguard Worker             dpcm = decodeRVLCodeword(bs, pRvlc);
517*e5436536SAndroid Build Coastguard Worker             if (dpcm < 0) {
518*e5436536SAndroid Build Coastguard Worker               pRvlc->conceal_max = bnds;
519*e5436536SAndroid Build Coastguard Worker               return;
520*e5436536SAndroid Build Coastguard Worker             }
521*e5436536SAndroid Build Coastguard Worker             dpcm -= TABLE_OFFSET;
522*e5436536SAndroid Build Coastguard Worker             if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
523*e5436536SAndroid Build Coastguard Worker               if (pRvlc->length_of_rvlc_escapes) {
524*e5436536SAndroid Build Coastguard Worker                 pRvlc->conceal_max = bnds;
525*e5436536SAndroid Build Coastguard Worker                 return;
526*e5436536SAndroid Build Coastguard Worker               } else {
527*e5436536SAndroid Build Coastguard Worker                 if (dpcm == MIN_RVL) {
528*e5436536SAndroid Build Coastguard Worker                   dpcm -= *pScfEsc++;
529*e5436536SAndroid Build Coastguard Worker                 } else {
530*e5436536SAndroid Build Coastguard Worker                   dpcm += *pScfEsc++;
531*e5436536SAndroid Build Coastguard Worker                 }
532*e5436536SAndroid Build Coastguard Worker                 (*pEscFwdCnt)++;
533*e5436536SAndroid Build Coastguard Worker                 if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
534*e5436536SAndroid Build Coastguard Worker                   pRvlc->conceal_max_esc = bnds;
535*e5436536SAndroid Build Coastguard Worker                 }
536*e5436536SAndroid Build Coastguard Worker               }
537*e5436536SAndroid Build Coastguard Worker             }
538*e5436536SAndroid Build Coastguard Worker             noisenrg += dpcm;
539*e5436536SAndroid Build Coastguard Worker             pScfFwd[bnds] = 100 + noisenrg;
540*e5436536SAndroid Build Coastguard Worker             pRvlc->lastNrg = noisenrg;
541*e5436536SAndroid Build Coastguard Worker           }
542*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->data.aac.PnsData.pnsUsed[bnds] = 1;
543*e5436536SAndroid Build Coastguard Worker           break;
544*e5436536SAndroid Build Coastguard Worker 
545*e5436536SAndroid Build Coastguard Worker         default:
546*e5436536SAndroid Build Coastguard Worker           pRvlc->sf_used = 1;
547*e5436536SAndroid Build Coastguard Worker           dpcm = decodeRVLCodeword(bs, pRvlc);
548*e5436536SAndroid Build Coastguard Worker           if (dpcm < 0) {
549*e5436536SAndroid Build Coastguard Worker             pRvlc->conceal_max = bnds;
550*e5436536SAndroid Build Coastguard Worker             return;
551*e5436536SAndroid Build Coastguard Worker           }
552*e5436536SAndroid Build Coastguard Worker           dpcm -= TABLE_OFFSET;
553*e5436536SAndroid Build Coastguard Worker           if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
554*e5436536SAndroid Build Coastguard Worker             if (pRvlc->length_of_rvlc_escapes) {
555*e5436536SAndroid Build Coastguard Worker               pRvlc->conceal_max = bnds;
556*e5436536SAndroid Build Coastguard Worker               return;
557*e5436536SAndroid Build Coastguard Worker             } else {
558*e5436536SAndroid Build Coastguard Worker               if (dpcm == MIN_RVL) {
559*e5436536SAndroid Build Coastguard Worker                 dpcm -= *pScfEsc++;
560*e5436536SAndroid Build Coastguard Worker               } else {
561*e5436536SAndroid Build Coastguard Worker                 dpcm += *pScfEsc++;
562*e5436536SAndroid Build Coastguard Worker               }
563*e5436536SAndroid Build Coastguard Worker               (*pEscFwdCnt)++;
564*e5436536SAndroid Build Coastguard Worker               if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
565*e5436536SAndroid Build Coastguard Worker                 pRvlc->conceal_max_esc = bnds;
566*e5436536SAndroid Build Coastguard Worker               }
567*e5436536SAndroid Build Coastguard Worker             }
568*e5436536SAndroid Build Coastguard Worker           }
569*e5436536SAndroid Build Coastguard Worker           factor += dpcm;
570*e5436536SAndroid Build Coastguard Worker           pScfFwd[bnds] = factor;
571*e5436536SAndroid Build Coastguard Worker           pRvlc->lastScf = factor;
572*e5436536SAndroid Build Coastguard Worker           break;
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   /* postfetch fwd long */
578*e5436536SAndroid Build Coastguard Worker   if (pRvlc->intensity_used) {
579*e5436536SAndroid Build Coastguard Worker     dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
580*e5436536SAndroid Build Coastguard Worker     if (dpcm < 0) {
581*e5436536SAndroid Build Coastguard Worker       pRvlc->conceal_max = bnds;
582*e5436536SAndroid Build Coastguard Worker       return;
583*e5436536SAndroid Build Coastguard Worker     }
584*e5436536SAndroid Build Coastguard Worker     dpcm -= TABLE_OFFSET;
585*e5436536SAndroid Build Coastguard Worker     if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
586*e5436536SAndroid Build Coastguard Worker       if (pRvlc->length_of_rvlc_escapes) {
587*e5436536SAndroid Build Coastguard Worker         pRvlc->conceal_max = bnds;
588*e5436536SAndroid Build Coastguard Worker         return;
589*e5436536SAndroid Build Coastguard Worker       } else {
590*e5436536SAndroid Build Coastguard Worker         if (dpcm == MIN_RVL) {
591*e5436536SAndroid Build Coastguard Worker           dpcm -= *pScfEsc++;
592*e5436536SAndroid Build Coastguard Worker         } else {
593*e5436536SAndroid Build Coastguard Worker           dpcm += *pScfEsc++;
594*e5436536SAndroid Build Coastguard Worker         }
595*e5436536SAndroid Build Coastguard Worker         (*pEscFwdCnt)++;
596*e5436536SAndroid Build Coastguard Worker         if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
597*e5436536SAndroid Build Coastguard Worker           pRvlc->conceal_max_esc = bnds;
598*e5436536SAndroid Build Coastguard Worker         }
599*e5436536SAndroid Build Coastguard Worker       }
600*e5436536SAndroid Build Coastguard Worker     }
601*e5436536SAndroid Build Coastguard Worker     pRvlc->dpcm_is_last_position = dpcm;
602*e5436536SAndroid Build Coastguard Worker   }
603*e5436536SAndroid Build Coastguard Worker }
604*e5436536SAndroid Build Coastguard Worker 
605*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
606*e5436536SAndroid Build Coastguard Worker      function:     rvlcDecodeBackward
607*e5436536SAndroid Build Coastguard Worker 
608*e5436536SAndroid Build Coastguard Worker      description:  Decode RVL-coded codewords in backward direction.
609*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
610*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
611*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
612*e5436536SAndroid Build Coastguard Worker                    - handle FDK bitstream
613*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
614*e5436536SAndroid Build Coastguard Worker         return:    -
615*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
616*e5436536SAndroid Build Coastguard Worker */
617*e5436536SAndroid Build Coastguard Worker 
rvlcDecodeBackward(CErRvlcInfo * pRvlc,CAacDecoderChannelInfo * pAacDecoderChannelInfo,HANDLE_FDK_BITSTREAM bs)618*e5436536SAndroid Build Coastguard Worker static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
619*e5436536SAndroid Build Coastguard Worker                                CAacDecoderChannelInfo *pAacDecoderChannelInfo,
620*e5436536SAndroid Build Coastguard Worker                                HANDLE_FDK_BITSTREAM bs) {
621*e5436536SAndroid Build Coastguard Worker   SHORT band, group, dpcm, offset;
622*e5436536SAndroid Build Coastguard Worker   SHORT bnds = pRvlc->maxSfbTransmitted - 1;
623*e5436536SAndroid Build Coastguard Worker 
624*e5436536SAndroid Build Coastguard Worker   SHORT factor = pRvlc->rev_global_gain - SF_OFFSET;
625*e5436536SAndroid Build Coastguard Worker   SHORT position = pRvlc->dpcm_is_last_position - SF_OFFSET;
626*e5436536SAndroid Build Coastguard Worker   SHORT noisenrg = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
627*e5436536SAndroid Build Coastguard Worker                    SF_OFFSET - 90 - 256;
628*e5436536SAndroid Build Coastguard Worker 
629*e5436536SAndroid Build Coastguard Worker   SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
630*e5436536SAndroid Build Coastguard Worker   SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
631*e5436536SAndroid Build Coastguard Worker   UCHAR escEscCnt = pRvlc->numDecodedEscapeWordsEsc;
632*e5436536SAndroid Build Coastguard Worker   UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd);
633*e5436536SAndroid Build Coastguard Worker 
634*e5436536SAndroid Build Coastguard Worker   pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd);
635*e5436536SAndroid Build Coastguard Worker   pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlBwd);
636*e5436536SAndroid Build Coastguard Worker 
637*e5436536SAndroid Build Coastguard Worker   *pEscBwdCnt = 0;
638*e5436536SAndroid Build Coastguard Worker   pRvlc->direction = BWD;
639*e5436536SAndroid Build Coastguard Worker   pScfEsc += escEscCnt - 1; /* set pScfEsc to last entry */
640*e5436536SAndroid Build Coastguard Worker   pRvlc->firstScf = 0;
641*e5436536SAndroid Build Coastguard Worker   pRvlc->firstNrg = 0;
642*e5436536SAndroid Build Coastguard Worker   pRvlc->firstIs = 0;
643*e5436536SAndroid Build Coastguard Worker 
644*e5436536SAndroid Build Coastguard Worker   /* prefetch long BWD */
645*e5436536SAndroid Build Coastguard Worker   if (pRvlc->intensity_used) {
646*e5436536SAndroid Build Coastguard Worker     dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
647*e5436536SAndroid Build Coastguard Worker     if (dpcm < 0) {
648*e5436536SAndroid Build Coastguard Worker       pRvlc->dpcm_is_last_position = 0;
649*e5436536SAndroid Build Coastguard Worker       pRvlc->conceal_min = bnds;
650*e5436536SAndroid Build Coastguard Worker       return;
651*e5436536SAndroid Build Coastguard Worker     }
652*e5436536SAndroid Build Coastguard Worker     dpcm -= TABLE_OFFSET;
653*e5436536SAndroid Build Coastguard Worker     if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
654*e5436536SAndroid Build Coastguard Worker       if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
655*e5436536SAndroid Build Coastguard Worker         pRvlc->conceal_min = bnds;
656*e5436536SAndroid Build Coastguard Worker         return;
657*e5436536SAndroid Build Coastguard Worker       } else {
658*e5436536SAndroid Build Coastguard Worker         if (dpcm == MIN_RVL) {
659*e5436536SAndroid Build Coastguard Worker           dpcm -= *pScfEsc--;
660*e5436536SAndroid Build Coastguard Worker         } else {
661*e5436536SAndroid Build Coastguard Worker           dpcm += *pScfEsc--;
662*e5436536SAndroid Build Coastguard Worker         }
663*e5436536SAndroid Build Coastguard Worker         (*pEscBwdCnt)++;
664*e5436536SAndroid Build Coastguard Worker         if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
665*e5436536SAndroid Build Coastguard Worker           pRvlc->conceal_min_esc = bnds;
666*e5436536SAndroid Build Coastguard Worker         }
667*e5436536SAndroid Build Coastguard Worker       }
668*e5436536SAndroid Build Coastguard Worker     }
669*e5436536SAndroid Build Coastguard Worker     pRvlc->dpcm_is_last_position = dpcm;
670*e5436536SAndroid Build Coastguard Worker   }
671*e5436536SAndroid Build Coastguard Worker 
672*e5436536SAndroid Build Coastguard Worker   /* main loop long BWD */
673*e5436536SAndroid Build Coastguard Worker   for (group = pRvlc->numWindowGroups - 1; group >= 0; group--) {
674*e5436536SAndroid Build Coastguard Worker     for (band = pRvlc->maxSfbTransmitted - 1; band >= 0; band--) {
675*e5436536SAndroid Build Coastguard Worker       bnds = 16 * group + band;
676*e5436536SAndroid Build Coastguard Worker       if ((band == 0) && (pRvlc->numWindowGroups != 1))
677*e5436536SAndroid Build Coastguard Worker         offset = 16 - pRvlc->maxSfbTransmitted + 1;
678*e5436536SAndroid Build Coastguard Worker       else
679*e5436536SAndroid Build Coastguard Worker         offset = 1;
680*e5436536SAndroid Build Coastguard Worker 
681*e5436536SAndroid Build Coastguard Worker       switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
682*e5436536SAndroid Build Coastguard Worker         case ZERO_HCB:
683*e5436536SAndroid Build Coastguard Worker           pScfBwd[bnds] = 0;
684*e5436536SAndroid Build Coastguard Worker           break;
685*e5436536SAndroid Build Coastguard Worker 
686*e5436536SAndroid Build Coastguard Worker         case INTENSITY_HCB2:
687*e5436536SAndroid Build Coastguard Worker         case INTENSITY_HCB:
688*e5436536SAndroid Build Coastguard Worker           /* store dpcm_is_position */
689*e5436536SAndroid Build Coastguard Worker           dpcm = decodeRVLCodeword(bs, pRvlc);
690*e5436536SAndroid Build Coastguard Worker           if (dpcm < 0) {
691*e5436536SAndroid Build Coastguard Worker             pScfBwd[bnds] = position;
692*e5436536SAndroid Build Coastguard Worker             pRvlc->conceal_min = fMax(0, bnds - offset);
693*e5436536SAndroid Build Coastguard Worker             return;
694*e5436536SAndroid Build Coastguard Worker           }
695*e5436536SAndroid Build Coastguard Worker           dpcm -= TABLE_OFFSET;
696*e5436536SAndroid Build Coastguard Worker           if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
697*e5436536SAndroid Build Coastguard Worker             if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
698*e5436536SAndroid Build Coastguard Worker               pScfBwd[bnds] = position;
699*e5436536SAndroid Build Coastguard Worker               pRvlc->conceal_min = fMax(0, bnds - offset);
700*e5436536SAndroid Build Coastguard Worker               return;
701*e5436536SAndroid Build Coastguard Worker             } else {
702*e5436536SAndroid Build Coastguard Worker               if (dpcm == MIN_RVL) {
703*e5436536SAndroid Build Coastguard Worker                 dpcm -= *pScfEsc--;
704*e5436536SAndroid Build Coastguard Worker               } else {
705*e5436536SAndroid Build Coastguard Worker                 dpcm += *pScfEsc--;
706*e5436536SAndroid Build Coastguard Worker               }
707*e5436536SAndroid Build Coastguard Worker               (*pEscBwdCnt)++;
708*e5436536SAndroid Build Coastguard Worker               if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
709*e5436536SAndroid Build Coastguard Worker                 pRvlc->conceal_min_esc = fMax(0, bnds - offset);
710*e5436536SAndroid Build Coastguard Worker               }
711*e5436536SAndroid Build Coastguard Worker             }
712*e5436536SAndroid Build Coastguard Worker           }
713*e5436536SAndroid Build Coastguard Worker           pScfBwd[bnds] = position;
714*e5436536SAndroid Build Coastguard Worker           position -= dpcm;
715*e5436536SAndroid Build Coastguard Worker           pRvlc->firstIs = position;
716*e5436536SAndroid Build Coastguard Worker           break;
717*e5436536SAndroid Build Coastguard Worker 
718*e5436536SAndroid Build Coastguard Worker         case NOISE_HCB:
719*e5436536SAndroid Build Coastguard Worker           if (bnds == pRvlc->first_noise_band) {
720*e5436536SAndroid Build Coastguard Worker             pScfBwd[bnds] =
721*e5436536SAndroid Build Coastguard Worker                 pRvlc->dpcm_noise_nrg +
722*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
723*e5436536SAndroid Build Coastguard Worker                 SF_OFFSET - 90 - 256;
724*e5436536SAndroid Build Coastguard Worker             pRvlc->firstNrg = pScfBwd[bnds];
725*e5436536SAndroid Build Coastguard Worker           } else {
726*e5436536SAndroid Build Coastguard Worker             dpcm = decodeRVLCodeword(bs, pRvlc);
727*e5436536SAndroid Build Coastguard Worker             if (dpcm < 0) {
728*e5436536SAndroid Build Coastguard Worker               pScfBwd[bnds] = noisenrg;
729*e5436536SAndroid Build Coastguard Worker               pRvlc->conceal_min = fMax(0, bnds - offset);
730*e5436536SAndroid Build Coastguard Worker               return;
731*e5436536SAndroid Build Coastguard Worker             }
732*e5436536SAndroid Build Coastguard Worker             dpcm -= TABLE_OFFSET;
733*e5436536SAndroid Build Coastguard Worker             if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
734*e5436536SAndroid Build Coastguard Worker               if ((pRvlc->length_of_rvlc_escapes) ||
735*e5436536SAndroid Build Coastguard Worker                   (*pEscBwdCnt >= escEscCnt)) {
736*e5436536SAndroid Build Coastguard Worker                 pScfBwd[bnds] = noisenrg;
737*e5436536SAndroid Build Coastguard Worker                 pRvlc->conceal_min = fMax(0, bnds - offset);
738*e5436536SAndroid Build Coastguard Worker                 return;
739*e5436536SAndroid Build Coastguard Worker               } else {
740*e5436536SAndroid Build Coastguard Worker                 if (dpcm == MIN_RVL) {
741*e5436536SAndroid Build Coastguard Worker                   dpcm -= *pScfEsc--;
742*e5436536SAndroid Build Coastguard Worker                 } else {
743*e5436536SAndroid Build Coastguard Worker                   dpcm += *pScfEsc--;
744*e5436536SAndroid Build Coastguard Worker                 }
745*e5436536SAndroid Build Coastguard Worker                 (*pEscBwdCnt)++;
746*e5436536SAndroid Build Coastguard Worker                 if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
747*e5436536SAndroid Build Coastguard Worker                   pRvlc->conceal_min_esc = fMax(0, bnds - offset);
748*e5436536SAndroid Build Coastguard Worker                 }
749*e5436536SAndroid Build Coastguard Worker               }
750*e5436536SAndroid Build Coastguard Worker             }
751*e5436536SAndroid Build Coastguard Worker             pScfBwd[bnds] = noisenrg;
752*e5436536SAndroid Build Coastguard Worker             noisenrg -= dpcm;
753*e5436536SAndroid Build Coastguard Worker             pRvlc->firstNrg = noisenrg;
754*e5436536SAndroid Build Coastguard Worker           }
755*e5436536SAndroid Build Coastguard Worker           break;
756*e5436536SAndroid Build Coastguard Worker 
757*e5436536SAndroid Build Coastguard Worker         default:
758*e5436536SAndroid Build Coastguard Worker           dpcm = decodeRVLCodeword(bs, pRvlc);
759*e5436536SAndroid Build Coastguard Worker           if (dpcm < 0) {
760*e5436536SAndroid Build Coastguard Worker             pScfBwd[bnds] = factor;
761*e5436536SAndroid Build Coastguard Worker             pRvlc->conceal_min = fMax(0, bnds - offset);
762*e5436536SAndroid Build Coastguard Worker             return;
763*e5436536SAndroid Build Coastguard Worker           }
764*e5436536SAndroid Build Coastguard Worker           dpcm -= TABLE_OFFSET;
765*e5436536SAndroid Build Coastguard Worker           if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
766*e5436536SAndroid Build Coastguard Worker             if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
767*e5436536SAndroid Build Coastguard Worker               pScfBwd[bnds] = factor;
768*e5436536SAndroid Build Coastguard Worker               pRvlc->conceal_min = fMax(0, bnds - offset);
769*e5436536SAndroid Build Coastguard Worker               return;
770*e5436536SAndroid Build Coastguard Worker             } else {
771*e5436536SAndroid Build Coastguard Worker               if (dpcm == MIN_RVL) {
772*e5436536SAndroid Build Coastguard Worker                 dpcm -= *pScfEsc--;
773*e5436536SAndroid Build Coastguard Worker               } else {
774*e5436536SAndroid Build Coastguard Worker                 dpcm += *pScfEsc--;
775*e5436536SAndroid Build Coastguard Worker               }
776*e5436536SAndroid Build Coastguard Worker               (*pEscBwdCnt)++;
777*e5436536SAndroid Build Coastguard Worker               if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
778*e5436536SAndroid Build Coastguard Worker                 pRvlc->conceal_min_esc = fMax(0, bnds - offset);
779*e5436536SAndroid Build Coastguard Worker               }
780*e5436536SAndroid Build Coastguard Worker             }
781*e5436536SAndroid Build Coastguard Worker           }
782*e5436536SAndroid Build Coastguard Worker           pScfBwd[bnds] = factor;
783*e5436536SAndroid Build Coastguard Worker           factor -= dpcm;
784*e5436536SAndroid Build Coastguard Worker           pRvlc->firstScf = factor;
785*e5436536SAndroid Build Coastguard Worker           break;
786*e5436536SAndroid Build Coastguard Worker       }
787*e5436536SAndroid Build Coastguard Worker     }
788*e5436536SAndroid Build Coastguard Worker   }
789*e5436536SAndroid Build Coastguard Worker }
790*e5436536SAndroid Build Coastguard Worker 
791*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
792*e5436536SAndroid Build Coastguard Worker      function:     rvlcFinalErrorDetection
793*e5436536SAndroid Build Coastguard Worker 
794*e5436536SAndroid Build Coastguard Worker      description:  Call RVLC concealment if error was detected in decoding
795*e5436536SAndroid Build Coastguard Worker process
796*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
797*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
798*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
799*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
800*e5436536SAndroid Build Coastguard Worker         return:    -
801*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
802*e5436536SAndroid Build Coastguard Worker */
803*e5436536SAndroid Build Coastguard Worker 
rvlcFinalErrorDetection(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo)804*e5436536SAndroid Build Coastguard Worker static void rvlcFinalErrorDetection(
805*e5436536SAndroid Build Coastguard Worker     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
806*e5436536SAndroid Build Coastguard Worker     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
807*e5436536SAndroid Build Coastguard Worker   CErRvlcInfo *pRvlc =
808*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
809*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusComplete = 0;
810*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusLengthFwd = 0;
811*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusLengthBwd = 0;
812*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusLengthEscapes = 0;
813*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusFirstScf = 0;
814*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusLastScf = 0;
815*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusFirstNrg = 0;
816*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusLastNrg = 0;
817*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusFirstIs = 0;
818*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusLastIs = 0;
819*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusForbiddenCwFwd = 0;
820*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusForbiddenCwBwd = 0;
821*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusNumEscapesFwd = 0;
822*e5436536SAndroid Build Coastguard Worker   UCHAR ErrorStatusNumEscapesBwd = 0;
823*e5436536SAndroid Build Coastguard Worker   UCHAR ConcealStatus = 1;
824*e5436536SAndroid Build Coastguard Worker   UCHAR currentBlockType; /* short: 0, not short: 1*/
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 1;
827*e5436536SAndroid Build Coastguard Worker 
828*e5436536SAndroid Build Coastguard Worker   /* invalid escape words, bit counter unequal zero, forbidden codeword detected
829*e5436536SAndroid Build Coastguard Worker    */
830*e5436536SAndroid Build Coastguard Worker   if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD)
831*e5436536SAndroid Build Coastguard Worker     ErrorStatusForbiddenCwFwd = 1;
832*e5436536SAndroid Build Coastguard Worker 
833*e5436536SAndroid Build Coastguard Worker   if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD)
834*e5436536SAndroid Build Coastguard Worker     ErrorStatusForbiddenCwBwd = 1;
835*e5436536SAndroid Build Coastguard Worker 
836*e5436536SAndroid Build Coastguard Worker   /* bit counter forward unequal zero */
837*e5436536SAndroid Build Coastguard Worker   if (pRvlc->length_of_rvlc_sf_fwd) ErrorStatusLengthFwd = 1;
838*e5436536SAndroid Build Coastguard Worker 
839*e5436536SAndroid Build Coastguard Worker   /* bit counter backward unequal zero */
840*e5436536SAndroid Build Coastguard Worker   if (pRvlc->length_of_rvlc_sf_bwd) ErrorStatusLengthBwd = 1;
841*e5436536SAndroid Build Coastguard Worker 
842*e5436536SAndroid Build Coastguard Worker   /* bit counter escape sequences unequal zero */
843*e5436536SAndroid Build Coastguard Worker   if (pRvlc->sf_escapes_present)
844*e5436536SAndroid Build Coastguard Worker     if (pRvlc->length_of_rvlc_escapes) ErrorStatusLengthEscapes = 1;
845*e5436536SAndroid Build Coastguard Worker 
846*e5436536SAndroid Build Coastguard Worker   if (pRvlc->sf_used) {
847*e5436536SAndroid Build Coastguard Worker     /* first decoded scf does not match to global gain in backward direction */
848*e5436536SAndroid Build Coastguard Worker     if (pRvlc->firstScf !=
849*e5436536SAndroid Build Coastguard Worker         (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET))
850*e5436536SAndroid Build Coastguard Worker       ErrorStatusFirstScf = 1;
851*e5436536SAndroid Build Coastguard Worker 
852*e5436536SAndroid Build Coastguard Worker     /* last decoded scf does not match to rev global gain in forward direction
853*e5436536SAndroid Build Coastguard Worker      */
854*e5436536SAndroid Build Coastguard Worker     if (pRvlc->lastScf != (pRvlc->rev_global_gain - SF_OFFSET))
855*e5436536SAndroid Build Coastguard Worker       ErrorStatusLastScf = 1;
856*e5436536SAndroid Build Coastguard Worker   }
857*e5436536SAndroid Build Coastguard Worker 
858*e5436536SAndroid Build Coastguard Worker   if (pRvlc->noise_used) {
859*e5436536SAndroid Build Coastguard Worker     /* first decoded nrg does not match to dpcm_noise_nrg in backward direction
860*e5436536SAndroid Build Coastguard Worker      */
861*e5436536SAndroid Build Coastguard Worker     if (pRvlc->firstNrg !=
862*e5436536SAndroid Build Coastguard Worker         (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain +
863*e5436536SAndroid Build Coastguard Worker          pRvlc->dpcm_noise_nrg - SF_OFFSET - 90 - 256))
864*e5436536SAndroid Build Coastguard Worker       ErrorStatusFirstNrg = 1;
865*e5436536SAndroid Build Coastguard Worker 
866*e5436536SAndroid Build Coastguard Worker     /* last decoded nrg does not match to dpcm_noise_last_position in forward
867*e5436536SAndroid Build Coastguard Worker      * direction */
868*e5436536SAndroid Build Coastguard Worker     if (pRvlc->lastNrg !=
869*e5436536SAndroid Build Coastguard Worker         (pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - SF_OFFSET -
870*e5436536SAndroid Build Coastguard Worker          90 - 256))
871*e5436536SAndroid Build Coastguard Worker       ErrorStatusLastNrg = 1;
872*e5436536SAndroid Build Coastguard Worker   }
873*e5436536SAndroid Build Coastguard Worker 
874*e5436536SAndroid Build Coastguard Worker   if (pRvlc->intensity_used) {
875*e5436536SAndroid Build Coastguard Worker     /* first decoded is position does not match in backward direction */
876*e5436536SAndroid Build Coastguard Worker     if (pRvlc->firstIs != (-SF_OFFSET)) ErrorStatusFirstIs = 1;
877*e5436536SAndroid Build Coastguard Worker 
878*e5436536SAndroid Build Coastguard Worker     /* last decoded is position does not match in forward direction */
879*e5436536SAndroid Build Coastguard Worker     if (pRvlc->lastIs != (pRvlc->dpcm_is_last_position - SF_OFFSET))
880*e5436536SAndroid Build Coastguard Worker       ErrorStatusLastIs = 1;
881*e5436536SAndroid Build Coastguard Worker   }
882*e5436536SAndroid Build Coastguard Worker 
883*e5436536SAndroid Build Coastguard Worker   /* decoded escapes and used escapes in forward direction do not fit */
884*e5436536SAndroid Build Coastguard Worker   if ((pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
885*e5436536SAndroid Build Coastguard Worker       (pRvlc->conceal_max == CONCEAL_MAX_INIT)) {
886*e5436536SAndroid Build Coastguard Worker     ErrorStatusNumEscapesFwd = 1;
887*e5436536SAndroid Build Coastguard Worker   }
888*e5436536SAndroid Build Coastguard Worker 
889*e5436536SAndroid Build Coastguard Worker   /* decoded escapes and used escapes in backward direction do not fit */
890*e5436536SAndroid Build Coastguard Worker   if ((pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
891*e5436536SAndroid Build Coastguard Worker       (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
892*e5436536SAndroid Build Coastguard Worker     ErrorStatusNumEscapesBwd = 1;
893*e5436536SAndroid Build Coastguard Worker   }
894*e5436536SAndroid Build Coastguard Worker 
895*e5436536SAndroid Build Coastguard Worker   if (ErrorStatusLengthEscapes ||
896*e5436536SAndroid Build Coastguard Worker       (((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
897*e5436536SAndroid Build Coastguard Worker         (pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
898*e5436536SAndroid Build Coastguard Worker         (ErrorStatusLastScf || ErrorStatusLastNrg || ErrorStatusLastIs))
899*e5436536SAndroid Build Coastguard Worker 
900*e5436536SAndroid Build Coastguard Worker        &&
901*e5436536SAndroid Build Coastguard Worker 
902*e5436536SAndroid Build Coastguard Worker        ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
903*e5436536SAndroid Build Coastguard Worker         (pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
904*e5436536SAndroid Build Coastguard Worker         (ErrorStatusFirstScf || ErrorStatusFirstNrg || ErrorStatusFirstIs))) ||
905*e5436536SAndroid Build Coastguard Worker       ((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
906*e5436536SAndroid Build Coastguard Worker        ((pRvlc->rev_global_gain - SF_OFFSET - pRvlc->lastScf) < -15)) ||
907*e5436536SAndroid Build Coastguard Worker       ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
908*e5436536SAndroid Build Coastguard Worker        ((pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET -
909*e5436536SAndroid Build Coastguard Worker          pRvlc->firstScf) < -15))) {
910*e5436536SAndroid Build Coastguard Worker     if ((pRvlc->conceal_max == CONCEAL_MAX_INIT) ||
911*e5436536SAndroid Build Coastguard Worker         (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
912*e5436536SAndroid Build Coastguard Worker       pRvlc->conceal_max = 0;
913*e5436536SAndroid Build Coastguard Worker       pRvlc->conceal_min = fMax(
914*e5436536SAndroid Build Coastguard Worker           0, (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1);
915*e5436536SAndroid Build Coastguard Worker     } else {
916*e5436536SAndroid Build Coastguard Worker       pRvlc->conceal_max = fMin(pRvlc->conceal_max, pRvlc->conceal_max_esc);
917*e5436536SAndroid Build Coastguard Worker       pRvlc->conceal_min = fMax(pRvlc->conceal_min, pRvlc->conceal_min_esc);
918*e5436536SAndroid Build Coastguard Worker     }
919*e5436536SAndroid Build Coastguard Worker   }
920*e5436536SAndroid Build Coastguard Worker 
921*e5436536SAndroid Build Coastguard Worker   ErrorStatusComplete = ErrorStatusLastScf || ErrorStatusFirstScf ||
922*e5436536SAndroid Build Coastguard Worker                         ErrorStatusLastNrg || ErrorStatusFirstNrg ||
923*e5436536SAndroid Build Coastguard Worker                         ErrorStatusLastIs || ErrorStatusFirstIs ||
924*e5436536SAndroid Build Coastguard Worker                         ErrorStatusForbiddenCwFwd ||
925*e5436536SAndroid Build Coastguard Worker                         ErrorStatusForbiddenCwBwd || ErrorStatusLengthFwd ||
926*e5436536SAndroid Build Coastguard Worker                         ErrorStatusLengthBwd || ErrorStatusLengthEscapes ||
927*e5436536SAndroid Build Coastguard Worker                         ErrorStatusNumEscapesFwd || ErrorStatusNumEscapesBwd;
928*e5436536SAndroid Build Coastguard Worker 
929*e5436536SAndroid Build Coastguard Worker   currentBlockType =
930*e5436536SAndroid Build Coastguard Worker       (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 0
931*e5436536SAndroid Build Coastguard Worker                                                                            : 1;
932*e5436536SAndroid Build Coastguard Worker 
933*e5436536SAndroid Build Coastguard Worker   if (!ErrorStatusComplete) {
934*e5436536SAndroid Build Coastguard Worker     int band;
935*e5436536SAndroid Build Coastguard Worker     int group;
936*e5436536SAndroid Build Coastguard Worker     int bnds;
937*e5436536SAndroid Build Coastguard Worker     int lastSfbIndex;
938*e5436536SAndroid Build Coastguard Worker 
939*e5436536SAndroid Build Coastguard Worker     lastSfbIndex = (pRvlc->numWindowGroups > 1) ? 16 : 64;
940*e5436536SAndroid Build Coastguard Worker 
941*e5436536SAndroid Build Coastguard Worker     for (group = 0; group < pRvlc->numWindowGroups; group++) {
942*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
943*e5436536SAndroid Build Coastguard Worker         bnds = 16 * group + band;
944*e5436536SAndroid Build Coastguard Worker         pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
945*e5436536SAndroid Build Coastguard Worker             pAacDecoderStaticChannelInfo->concealmentInfo
946*e5436536SAndroid Build Coastguard Worker                 .aRvlcPreviousScaleFactor[bnds] =
947*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
948*e5436536SAndroid Build Coastguard Worker       }
949*e5436536SAndroid Build Coastguard Worker     }
950*e5436536SAndroid Build Coastguard Worker 
951*e5436536SAndroid Build Coastguard Worker     for (group = 0; group < pRvlc->numWindowGroups; group++) {
952*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
953*e5436536SAndroid Build Coastguard Worker         bnds = 16 * group + band;
954*e5436536SAndroid Build Coastguard Worker         pAacDecoderStaticChannelInfo->concealmentInfo
955*e5436536SAndroid Build Coastguard Worker             .aRvlcPreviousCodebook[bnds] =
956*e5436536SAndroid Build Coastguard Worker             pAacDecoderChannelInfo->pDynData->aCodeBook[bnds];
957*e5436536SAndroid Build Coastguard Worker       }
958*e5436536SAndroid Build Coastguard Worker       for (; band < lastSfbIndex; band++) {
959*e5436536SAndroid Build Coastguard Worker         bnds = 16 * group + band;
960*e5436536SAndroid Build Coastguard Worker         FDK_ASSERT(bnds >= 0 && bnds < RVLC_MAX_SFB);
961*e5436536SAndroid Build Coastguard Worker         pAacDecoderStaticChannelInfo->concealmentInfo
962*e5436536SAndroid Build Coastguard Worker             .aRvlcPreviousCodebook[bnds] = ZERO_HCB;
963*e5436536SAndroid Build Coastguard Worker       }
964*e5436536SAndroid Build Coastguard Worker     }
965*e5436536SAndroid Build Coastguard Worker   } else {
966*e5436536SAndroid Build Coastguard Worker     int band;
967*e5436536SAndroid Build Coastguard Worker     int group;
968*e5436536SAndroid Build Coastguard Worker 
969*e5436536SAndroid Build Coastguard Worker     /* A single bit error was detected in decoding of dpcm values. It also could
970*e5436536SAndroid Build Coastguard Worker        be an error with more bits in decoding of escapes and dpcm values whereby
971*e5436536SAndroid Build Coastguard Worker        an illegal codeword followed not directly after the corrupted bits but
972*e5436536SAndroid Build Coastguard Worker        just after decoding some more (wrong) scalefactors. Use the smaller
973*e5436536SAndroid Build Coastguard Worker        scalefactor from forward decoding, backward decoding and previous frame.
974*e5436536SAndroid Build Coastguard Worker      */
975*e5436536SAndroid Build Coastguard Worker     if (((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
976*e5436536SAndroid Build Coastguard Worker          (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
977*e5436536SAndroid Build Coastguard Worker         (pRvlc->conceal_min <= pRvlc->conceal_max) &&
978*e5436536SAndroid Build Coastguard Worker         (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
979*e5436536SAndroid Build Coastguard Worker          currentBlockType) &&
980*e5436536SAndroid Build Coastguard Worker         pAacDecoderStaticChannelInfo->concealmentInfo
981*e5436536SAndroid Build Coastguard Worker             .rvlcPreviousScaleFactorOK &&
982*e5436536SAndroid Build Coastguard Worker         pRvlc->sf_concealment && ConcealStatus) {
983*e5436536SAndroid Build Coastguard Worker       BidirectionalEstimation_UseScfOfPrevFrameAsReference(
984*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
985*e5436536SAndroid Build Coastguard Worker       ConcealStatus = 0;
986*e5436536SAndroid Build Coastguard Worker     }
987*e5436536SAndroid Build Coastguard Worker 
988*e5436536SAndroid Build Coastguard Worker     /* A single bit error was detected in decoding of dpcm values. It also could
989*e5436536SAndroid Build Coastguard Worker        be an error with more bits in decoding of escapes and dpcm values whereby
990*e5436536SAndroid Build Coastguard Worker        an illegal codeword followed not directly after the corrupted bits but
991*e5436536SAndroid Build Coastguard Worker        just after decoding some more (wrong) scalefactors. Use the smaller
992*e5436536SAndroid Build Coastguard Worker        scalefactor from forward and backward decoding. */
993*e5436536SAndroid Build Coastguard Worker     if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
994*e5436536SAndroid Build Coastguard Worker         ((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
995*e5436536SAndroid Build Coastguard Worker          (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
996*e5436536SAndroid Build Coastguard Worker         !(pAacDecoderStaticChannelInfo->concealmentInfo
997*e5436536SAndroid Build Coastguard Worker               .rvlcPreviousScaleFactorOK &&
998*e5436536SAndroid Build Coastguard Worker           pRvlc->sf_concealment &&
999*e5436536SAndroid Build Coastguard Worker           (pAacDecoderStaticChannelInfo->concealmentInfo
1000*e5436536SAndroid Build Coastguard Worker                .rvlcPreviousBlockType == currentBlockType)) &&
1001*e5436536SAndroid Build Coastguard Worker         ConcealStatus) {
1002*e5436536SAndroid Build Coastguard Worker       BidirectionalEstimation_UseLowerScfOfCurrentFrame(pAacDecoderChannelInfo);
1003*e5436536SAndroid Build Coastguard Worker       ConcealStatus = 0;
1004*e5436536SAndroid Build Coastguard Worker     }
1005*e5436536SAndroid Build Coastguard Worker 
1006*e5436536SAndroid Build Coastguard Worker     /* No errors were detected in decoding of escapes and dpcm values however
1007*e5436536SAndroid Build Coastguard Worker        the first and last value of a group (is,nrg,sf) is incorrect */
1008*e5436536SAndroid Build Coastguard Worker     if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
1009*e5436536SAndroid Build Coastguard Worker         ((ErrorStatusLastScf && ErrorStatusFirstScf) ||
1010*e5436536SAndroid Build Coastguard Worker          (ErrorStatusLastNrg && ErrorStatusFirstNrg) ||
1011*e5436536SAndroid Build Coastguard Worker          (ErrorStatusLastIs && ErrorStatusFirstIs)) &&
1012*e5436536SAndroid Build Coastguard Worker         !(ErrorStatusForbiddenCwFwd || ErrorStatusForbiddenCwBwd ||
1013*e5436536SAndroid Build Coastguard Worker           ErrorStatusLengthEscapes) &&
1014*e5436536SAndroid Build Coastguard Worker         ConcealStatus) {
1015*e5436536SAndroid Build Coastguard Worker       StatisticalEstimation(pAacDecoderChannelInfo);
1016*e5436536SAndroid Build Coastguard Worker       ConcealStatus = 0;
1017*e5436536SAndroid Build Coastguard Worker     }
1018*e5436536SAndroid Build Coastguard Worker 
1019*e5436536SAndroid Build Coastguard Worker     /* A error with more bits in decoding of escapes and dpcm values was
1020*e5436536SAndroid Build Coastguard Worker        detected. Use the smaller scalefactor from forward decoding, backward
1021*e5436536SAndroid Build Coastguard Worker        decoding and previous frame. */
1022*e5436536SAndroid Build Coastguard Worker     if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
1023*e5436536SAndroid Build Coastguard Worker         pAacDecoderStaticChannelInfo->concealmentInfo
1024*e5436536SAndroid Build Coastguard Worker             .rvlcPreviousScaleFactorOK &&
1025*e5436536SAndroid Build Coastguard Worker         pRvlc->sf_concealment &&
1026*e5436536SAndroid Build Coastguard Worker         (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
1027*e5436536SAndroid Build Coastguard Worker          currentBlockType) &&
1028*e5436536SAndroid Build Coastguard Worker         ConcealStatus) {
1029*e5436536SAndroid Build Coastguard Worker       PredictiveInterpolation(pAacDecoderChannelInfo,
1030*e5436536SAndroid Build Coastguard Worker                               pAacDecoderStaticChannelInfo);
1031*e5436536SAndroid Build Coastguard Worker       ConcealStatus = 0;
1032*e5436536SAndroid Build Coastguard Worker     }
1033*e5436536SAndroid Build Coastguard Worker 
1034*e5436536SAndroid Build Coastguard Worker     /* Call frame concealment, because no better strategy was found. Setting the
1035*e5436536SAndroid Build Coastguard Worker        scalefactors to zero is done for debugging purposes */
1036*e5436536SAndroid Build Coastguard Worker     if (ConcealStatus) {
1037*e5436536SAndroid Build Coastguard Worker       for (group = 0; group < pRvlc->numWindowGroups; group++) {
1038*e5436536SAndroid Build Coastguard Worker         for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
1039*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->pDynData->aScaleFactor[16 * group + band] = 0;
1040*e5436536SAndroid Build Coastguard Worker         }
1041*e5436536SAndroid Build Coastguard Worker       }
1042*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac
1043*e5436536SAndroid Build Coastguard Worker           .rvlcCurrentScaleFactorOK = 0;
1044*e5436536SAndroid Build Coastguard Worker     }
1045*e5436536SAndroid Build Coastguard Worker   }
1046*e5436536SAndroid Build Coastguard Worker }
1047*e5436536SAndroid Build Coastguard Worker 
1048*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1049*e5436536SAndroid Build Coastguard Worker      function:     CRvlc_Read
1050*e5436536SAndroid Build Coastguard Worker 
1051*e5436536SAndroid Build Coastguard Worker      description:  Read RVLC ESC1 data (side info) from bitstream.
1052*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1053*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
1054*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
1055*e5436536SAndroid Build Coastguard Worker                    - pointer bitstream structure
1056*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1057*e5436536SAndroid Build Coastguard Worker         return:    -
1058*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1059*e5436536SAndroid Build Coastguard Worker */
1060*e5436536SAndroid Build Coastguard Worker 
CRvlc_Read(CAacDecoderChannelInfo * pAacDecoderChannelInfo,HANDLE_FDK_BITSTREAM bs)1061*e5436536SAndroid Build Coastguard Worker void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1062*e5436536SAndroid Build Coastguard Worker                 HANDLE_FDK_BITSTREAM bs) {
1063*e5436536SAndroid Build Coastguard Worker   CErRvlcInfo *pRvlc =
1064*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
1065*e5436536SAndroid Build Coastguard Worker 
1066*e5436536SAndroid Build Coastguard Worker   int group, band;
1067*e5436536SAndroid Build Coastguard Worker 
1068*e5436536SAndroid Build Coastguard Worker   /* RVLC long specific initialization  Init part 1 of 2 */
1069*e5436536SAndroid Build Coastguard Worker   pRvlc->numWindowGroups = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
1070*e5436536SAndroid Build Coastguard Worker   pRvlc->maxSfbTransmitted =
1071*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
1072*e5436536SAndroid Build Coastguard Worker   pRvlc->noise_used = 0;               /* noise detection */
1073*e5436536SAndroid Build Coastguard Worker   pRvlc->dpcm_noise_nrg = 0;           /* only for debugging */
1074*e5436536SAndroid Build Coastguard Worker   pRvlc->dpcm_noise_last_position = 0; /* only for debugging */
1075*e5436536SAndroid Build Coastguard Worker   pRvlc->length_of_rvlc_escapes =
1076*e5436536SAndroid Build Coastguard Worker       -1; /* default value is used for error detection and concealment */
1077*e5436536SAndroid Build Coastguard Worker 
1078*e5436536SAndroid Build Coastguard Worker   /* read only error sensitivity class 1 data (ESC 1 - data) */
1079*e5436536SAndroid Build Coastguard Worker   pRvlc->sf_concealment = FDKreadBits(bs, 1);  /* #1 */
1080*e5436536SAndroid Build Coastguard Worker   pRvlc->rev_global_gain = FDKreadBits(bs, 8); /* #2 */
1081*e5436536SAndroid Build Coastguard Worker 
1082*e5436536SAndroid Build Coastguard Worker   if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
1083*e5436536SAndroid Build Coastguard Worker     pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 11); /* #3 */
1084*e5436536SAndroid Build Coastguard Worker   } else {
1085*e5436536SAndroid Build Coastguard Worker     pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 9); /* #3 */
1086*e5436536SAndroid Build Coastguard Worker   }
1087*e5436536SAndroid Build Coastguard Worker 
1088*e5436536SAndroid Build Coastguard Worker   /* check if noise codebook is used */
1089*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < pRvlc->numWindowGroups; group++) {
1090*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
1091*e5436536SAndroid Build Coastguard Worker       if (pAacDecoderChannelInfo->pDynData->aCodeBook[16 * group + band] ==
1092*e5436536SAndroid Build Coastguard Worker           NOISE_HCB) {
1093*e5436536SAndroid Build Coastguard Worker         pRvlc->noise_used = 1;
1094*e5436536SAndroid Build Coastguard Worker         break;
1095*e5436536SAndroid Build Coastguard Worker       }
1096*e5436536SAndroid Build Coastguard Worker     }
1097*e5436536SAndroid Build Coastguard Worker   }
1098*e5436536SAndroid Build Coastguard Worker 
1099*e5436536SAndroid Build Coastguard Worker   if (pRvlc->noise_used)
1100*e5436536SAndroid Build Coastguard Worker     pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4  PNS */
1101*e5436536SAndroid Build Coastguard Worker 
1102*e5436536SAndroid Build Coastguard Worker   pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5      */
1103*e5436536SAndroid Build Coastguard Worker 
1104*e5436536SAndroid Build Coastguard Worker   if (pRvlc->sf_escapes_present) {
1105*e5436536SAndroid Build Coastguard Worker     pRvlc->length_of_rvlc_escapes = FDKreadBits(bs, 8); /* #6      */
1106*e5436536SAndroid Build Coastguard Worker   }
1107*e5436536SAndroid Build Coastguard Worker 
1108*e5436536SAndroid Build Coastguard Worker   if (pRvlc->noise_used) {
1109*e5436536SAndroid Build Coastguard Worker     pRvlc->dpcm_noise_last_position = FDKreadBits(bs, 9); /* #7  PNS */
1110*e5436536SAndroid Build Coastguard Worker     pRvlc->length_of_rvlc_sf -= 9;
1111*e5436536SAndroid Build Coastguard Worker   }
1112*e5436536SAndroid Build Coastguard Worker 
1113*e5436536SAndroid Build Coastguard Worker   pRvlc->length_of_rvlc_sf_fwd = pRvlc->length_of_rvlc_sf;
1114*e5436536SAndroid Build Coastguard Worker   pRvlc->length_of_rvlc_sf_bwd = pRvlc->length_of_rvlc_sf;
1115*e5436536SAndroid Build Coastguard Worker }
1116*e5436536SAndroid Build Coastguard Worker 
1117*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1118*e5436536SAndroid Build Coastguard Worker      function:     CRvlc_Decode
1119*e5436536SAndroid Build Coastguard Worker 
1120*e5436536SAndroid Build Coastguard Worker      description:  Decode rvlc data
1121*e5436536SAndroid Build Coastguard Worker                    The function reads both the escape sequences and the
1122*e5436536SAndroid Build Coastguard Worker scalefactors in forward and backward direction. If an error occured during
1123*e5436536SAndroid Build Coastguard Worker decoding process which can not be concealed with the rvlc concealment frame
1124*e5436536SAndroid Build Coastguard Worker concealment will be initiated. Then the element "rvlcCurrentScaleFactorOK" in
1125*e5436536SAndroid Build Coastguard Worker the decoder channel info is set to 0 otherwise it is set to 1.
1126*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1127*e5436536SAndroid Build Coastguard Worker         input:     - pointer rvlc structure
1128*e5436536SAndroid Build Coastguard Worker                    - pointer channel info structure
1129*e5436536SAndroid Build Coastguard Worker                    - pointer to persistent channel info structure
1130*e5436536SAndroid Build Coastguard Worker                    - pointer bitstream structure
1131*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1132*e5436536SAndroid Build Coastguard Worker         return:    ErrorStatus = AAC_DEC_OK
1133*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1134*e5436536SAndroid Build Coastguard Worker */
1135*e5436536SAndroid Build Coastguard Worker 
CRvlc_Decode(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,HANDLE_FDK_BITSTREAM bs)1136*e5436536SAndroid Build Coastguard Worker void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1137*e5436536SAndroid Build Coastguard Worker                   CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1138*e5436536SAndroid Build Coastguard Worker                   HANDLE_FDK_BITSTREAM bs) {
1139*e5436536SAndroid Build Coastguard Worker   CErRvlcInfo *pRvlc =
1140*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
1141*e5436536SAndroid Build Coastguard Worker   INT bitCntOffst;
1142*e5436536SAndroid Build Coastguard Worker   INT saveBitCnt;
1143*e5436536SAndroid Build Coastguard Worker 
1144*e5436536SAndroid Build Coastguard Worker   rvlcInit(pRvlc, pAacDecoderChannelInfo, bs);
1145*e5436536SAndroid Build Coastguard Worker 
1146*e5436536SAndroid Build Coastguard Worker   /* save bitstream position */
1147*e5436536SAndroid Build Coastguard Worker   saveBitCnt = (INT)FDKgetValidBits(bs);
1148*e5436536SAndroid Build Coastguard Worker 
1149*e5436536SAndroid Build Coastguard Worker   if (pRvlc->sf_escapes_present)
1150*e5436536SAndroid Build Coastguard Worker     rvlcDecodeEscapes(
1151*e5436536SAndroid Build Coastguard Worker         pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs);
1152*e5436536SAndroid Build Coastguard Worker 
1153*e5436536SAndroid Build Coastguard Worker   rvlcDecodeForward(pRvlc, pAacDecoderChannelInfo, bs);
1154*e5436536SAndroid Build Coastguard Worker   rvlcDecodeBackward(pRvlc, pAacDecoderChannelInfo, bs);
1155*e5436536SAndroid Build Coastguard Worker   rvlcFinalErrorDetection(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
1156*e5436536SAndroid Build Coastguard Worker 
1157*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed =
1158*e5436536SAndroid Build Coastguard Worker       pRvlc->intensity_used;
1159*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->data.aac.PnsData.PnsActive = pRvlc->noise_used;
1160*e5436536SAndroid Build Coastguard Worker 
1161*e5436536SAndroid Build Coastguard Worker   /* restore bitstream position */
1162*e5436536SAndroid Build Coastguard Worker   bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
1163*e5436536SAndroid Build Coastguard Worker   if (bitCntOffst) {
1164*e5436536SAndroid Build Coastguard Worker     FDKpushBiDirectional(bs, bitCntOffst);
1165*e5436536SAndroid Build Coastguard Worker   }
1166*e5436536SAndroid Build Coastguard Worker }
1167*e5436536SAndroid Build Coastguard Worker 
CRvlc_ElementCheck(CAacDecoderChannelInfo * pAacDecoderChannelInfo[],CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo[],const UINT flags,const INT elChannels)1168*e5436536SAndroid Build Coastguard Worker void CRvlc_ElementCheck(
1169*e5436536SAndroid Build Coastguard Worker     CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
1170*e5436536SAndroid Build Coastguard Worker     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
1171*e5436536SAndroid Build Coastguard Worker     const UINT flags, const INT elChannels) {
1172*e5436536SAndroid Build Coastguard Worker   int ch;
1173*e5436536SAndroid Build Coastguard Worker 
1174*e5436536SAndroid Build Coastguard Worker   /* Required for MPS residuals. */
1175*e5436536SAndroid Build Coastguard Worker   if (pAacDecoderStaticChannelInfo == NULL) {
1176*e5436536SAndroid Build Coastguard Worker     return;
1177*e5436536SAndroid Build Coastguard Worker   }
1178*e5436536SAndroid Build Coastguard Worker 
1179*e5436536SAndroid Build Coastguard Worker   /* RVLC specific sanity checks */
1180*e5436536SAndroid Build Coastguard Worker   if ((flags & AC_ER_RVLC) && (elChannels == 2)) { /* to be reviewed */
1181*e5436536SAndroid Build Coastguard Worker     if (((pAacDecoderChannelInfo[0]
1182*e5436536SAndroid Build Coastguard Worker               ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) ||
1183*e5436536SAndroid Build Coastguard Worker          (pAacDecoderChannelInfo[1]
1184*e5436536SAndroid Build Coastguard Worker               ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0)) &&
1185*e5436536SAndroid Build Coastguard Worker         pAacDecoderChannelInfo[0]->pComData->jointStereoData.MsMaskPresent) {
1186*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo[0]
1187*e5436536SAndroid Build Coastguard Worker           ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
1188*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo[1]
1189*e5436536SAndroid Build Coastguard Worker           ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
1190*e5436536SAndroid Build Coastguard Worker     }
1191*e5436536SAndroid Build Coastguard Worker 
1192*e5436536SAndroid Build Coastguard Worker     if ((pAacDecoderChannelInfo[0]
1193*e5436536SAndroid Build Coastguard Worker              ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) &&
1194*e5436536SAndroid Build Coastguard Worker         (pAacDecoderChannelInfo[1]
1195*e5436536SAndroid Build Coastguard Worker              ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 1) &&
1196*e5436536SAndroid Build Coastguard Worker         (pAacDecoderChannelInfo[1]
1197*e5436536SAndroid Build Coastguard Worker              ->pDynData->specificTo.aac.rvlcIntensityUsed == 1)) {
1198*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo[1]
1199*e5436536SAndroid Build Coastguard Worker           ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
1200*e5436536SAndroid Build Coastguard Worker     }
1201*e5436536SAndroid Build Coastguard Worker   }
1202*e5436536SAndroid Build Coastguard Worker 
1203*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < elChannels; ch++) {
1204*e5436536SAndroid Build Coastguard Worker     pAacDecoderStaticChannelInfo[ch]->concealmentInfo.rvlcPreviousBlockType =
1205*e5436536SAndroid Build Coastguard Worker         (GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) == BLOCK_SHORT)
1206*e5436536SAndroid Build Coastguard Worker             ? 0
1207*e5436536SAndroid Build Coastguard Worker             : 1;
1208*e5436536SAndroid Build Coastguard Worker     if (flags & AC_ER_RVLC) {
1209*e5436536SAndroid Build Coastguard Worker       pAacDecoderStaticChannelInfo[ch]
1210*e5436536SAndroid Build Coastguard Worker           ->concealmentInfo.rvlcPreviousScaleFactorOK =
1211*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo[ch]
1212*e5436536SAndroid Build Coastguard Worker               ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK;
1213*e5436536SAndroid Build Coastguard Worker     } else {
1214*e5436536SAndroid Build Coastguard Worker       pAacDecoderStaticChannelInfo[ch]
1215*e5436536SAndroid Build Coastguard Worker           ->concealmentInfo.rvlcPreviousScaleFactorOK = 0;
1216*e5436536SAndroid Build Coastguard Worker     }
1217*e5436536SAndroid Build Coastguard Worker   }
1218*e5436536SAndroid Build Coastguard Worker }
1219