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