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