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 - 2019 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): Robert Weidner (DSP Solutions)
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo,
100*e5436536SAndroid Build Coastguard Worker decode priority codewords (PCWs)
101*e5436536SAndroid Build Coastguard Worker
102*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
103*e5436536SAndroid Build Coastguard Worker
104*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr.h"
105*e5436536SAndroid Build Coastguard Worker
106*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr_types.h"
107*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr_bit.h"
108*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcrs.h"
109*e5436536SAndroid Build Coastguard Worker #include "aac_ram.h"
110*e5436536SAndroid Build Coastguard Worker #include "aac_rom.h"
111*e5436536SAndroid Build Coastguard Worker #include "channel.h"
112*e5436536SAndroid Build Coastguard Worker #include "block.h"
113*e5436536SAndroid Build Coastguard Worker
114*e5436536SAndroid Build Coastguard Worker #include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */
115*e5436536SAndroid Build Coastguard Worker #include "FDK_bitstream.h"
116*e5436536SAndroid Build Coastguard Worker
117*e5436536SAndroid Build Coastguard Worker extern int mlFileChCurr;
118*e5436536SAndroid Build Coastguard Worker
119*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
120*e5436536SAndroid Build Coastguard Worker UINT *errorWord);
121*e5436536SAndroid Build Coastguard Worker
122*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
123*e5436536SAndroid Build Coastguard Worker SHORT lengthOfReorderedSpectralData,
124*e5436536SAndroid Build Coastguard Worker UINT *errorWord);
125*e5436536SAndroid Build Coastguard Worker
126*e5436536SAndroid Build Coastguard Worker static void HcrCalcNumCodeword(H_HCR_INFO pHcr);
127*e5436536SAndroid Build Coastguard Worker static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr);
128*e5436536SAndroid Build Coastguard Worker static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr);
129*e5436536SAndroid Build Coastguard Worker static void HcrExtendedSectionInfo(H_HCR_INFO pHcr);
130*e5436536SAndroid Build Coastguard Worker
131*e5436536SAndroid Build Coastguard Worker static void DeriveNumberOfExtendedSortedSectionsInSets(
132*e5436536SAndroid Build Coastguard Worker UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
133*e5436536SAndroid Build Coastguard Worker int numExtendedSortedCodewordInSectionIdx,
134*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtendedSortedSectionsInSets,
135*e5436536SAndroid Build Coastguard Worker int numExtendedSortedSectionsInSetsIdx);
136*e5436536SAndroid Build Coastguard Worker
137*e5436536SAndroid Build Coastguard Worker static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
138*e5436536SAndroid Build Coastguard Worker INT quantSpecCoef, INT *pLeftStartOfSegment,
139*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
140*e5436536SAndroid Build Coastguard Worker int *pNumDecodedBits, UINT *errorWord);
141*e5436536SAndroid Build Coastguard Worker
142*e5436536SAndroid Build Coastguard Worker static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
143*e5436536SAndroid Build Coastguard Worker UINT codebookDim, const SCHAR *pQuantVal,
144*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
145*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment,
146*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment, int *pNumDecodedBits);
147*e5436536SAndroid Build Coastguard Worker
148*e5436536SAndroid Build Coastguard Worker static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
149*e5436536SAndroid Build Coastguard Worker const UINT *pCurrentTree,
150*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantValBase,
151*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment,
152*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
153*e5436536SAndroid Build Coastguard Worker int *pNumDecodedBits);
154*e5436536SAndroid Build Coastguard Worker
155*e5436536SAndroid Build Coastguard Worker static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr);
156*e5436536SAndroid Build Coastguard Worker
157*e5436536SAndroid Build Coastguard Worker static void HcrReorderQuantizedSpectralCoefficients(
158*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
159*e5436536SAndroid Build Coastguard Worker const SamplingRateInfo *pSamplingRateInfo);
160*e5436536SAndroid Build Coastguard Worker
161*e5436536SAndroid Build Coastguard Worker static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
162*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr, PCW_TYPE kind,
163*e5436536SAndroid Build Coastguard Worker FIXP_DBL *qsc_base_of_cw,
164*e5436536SAndroid Build Coastguard Worker UCHAR dimension);
165*e5436536SAndroid Build Coastguard Worker
166*e5436536SAndroid Build Coastguard Worker static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr);
167*e5436536SAndroid Build Coastguard Worker
168*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
169*e5436536SAndroid Build Coastguard Worker description: Check if codebook and numSect are within allowed range
170*e5436536SAndroid Build Coastguard Worker (short only)
171*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
172*e5436536SAndroid Build Coastguard Worker */
errDetectorInHcrSideinfoShrt(SCHAR cb,SHORT numLine,UINT * errorWord)173*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
174*e5436536SAndroid Build Coastguard Worker UINT *errorWord) {
175*e5436536SAndroid Build Coastguard Worker if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
176*e5436536SAndroid Build Coastguard Worker *errorWord |= CB_OUT_OF_RANGE_SHORT_BLOCK;
177*e5436536SAndroid Build Coastguard Worker }
178*e5436536SAndroid Build Coastguard Worker if (numLine < 0 || numLine > 1024) {
179*e5436536SAndroid Build Coastguard Worker *errorWord |= LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK;
180*e5436536SAndroid Build Coastguard Worker }
181*e5436536SAndroid Build Coastguard Worker }
182*e5436536SAndroid Build Coastguard Worker
183*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
184*e5436536SAndroid Build Coastguard Worker description: Check both HCR lengths
185*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
186*e5436536SAndroid Build Coastguard Worker */
errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,SHORT lengthOfReorderedSpectralData,UINT * errorWord)187*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
188*e5436536SAndroid Build Coastguard Worker SHORT lengthOfReorderedSpectralData,
189*e5436536SAndroid Build Coastguard Worker UINT *errorWord) {
190*e5436536SAndroid Build Coastguard Worker if (lengthOfReorderedSpectralData < lengthOfLongestCodeword) {
191*e5436536SAndroid Build Coastguard Worker *errorWord |= HCR_SI_LENGTHS_FAILURE;
192*e5436536SAndroid Build Coastguard Worker }
193*e5436536SAndroid Build Coastguard Worker }
194*e5436536SAndroid Build Coastguard Worker
195*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
196*e5436536SAndroid Build Coastguard Worker description: Decode (and adapt if necessary) the two HCR sideinfo
197*e5436536SAndroid Build Coastguard Worker components: 'reordered_spectral_data_length' and 'longest_codeword_length'
198*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
199*e5436536SAndroid Build Coastguard Worker */
200*e5436536SAndroid Build Coastguard Worker
CHcr_Read(HANDLE_FDK_BITSTREAM bs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const MP4_ELEMENT_ID globalHcrType)201*e5436536SAndroid Build Coastguard Worker void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
202*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo,
203*e5436536SAndroid Build Coastguard Worker const MP4_ELEMENT_ID globalHcrType) {
204*e5436536SAndroid Build Coastguard Worker SHORT lengOfReorderedSpectralData;
205*e5436536SAndroid Build Coastguard Worker SCHAR lengOfLongestCodeword;
206*e5436536SAndroid Build Coastguard Worker
207*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData =
208*e5436536SAndroid Build Coastguard Worker 0;
209*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = 0;
210*e5436536SAndroid Build Coastguard Worker
211*e5436536SAndroid Build Coastguard Worker /* ------- SI-Value No 1 ------- */
212*e5436536SAndroid Build Coastguard Worker lengOfReorderedSpectralData = FDKreadBits(bs, 14) + ERROR_LORSD;
213*e5436536SAndroid Build Coastguard Worker if (globalHcrType == ID_CPE) {
214*e5436536SAndroid Build Coastguard Worker if ((lengOfReorderedSpectralData >= 0) &&
215*e5436536SAndroid Build Coastguard Worker (lengOfReorderedSpectralData <= CPE_TOP_LENGTH)) {
216*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac
217*e5436536SAndroid Build Coastguard Worker .lenOfReorderedSpectralData =
218*e5436536SAndroid Build Coastguard Worker lengOfReorderedSpectralData; /* the decoded value is within range */
219*e5436536SAndroid Build Coastguard Worker } else {
220*e5436536SAndroid Build Coastguard Worker if (lengOfReorderedSpectralData > CPE_TOP_LENGTH) {
221*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac
222*e5436536SAndroid Build Coastguard Worker .lenOfReorderedSpectralData =
223*e5436536SAndroid Build Coastguard Worker CPE_TOP_LENGTH; /* use valid maximum */
224*e5436536SAndroid Build Coastguard Worker }
225*e5436536SAndroid Build Coastguard Worker }
226*e5436536SAndroid Build Coastguard Worker } else if (globalHcrType == ID_SCE || globalHcrType == ID_LFE ||
227*e5436536SAndroid Build Coastguard Worker globalHcrType == ID_CCE) {
228*e5436536SAndroid Build Coastguard Worker if ((lengOfReorderedSpectralData >= 0) &&
229*e5436536SAndroid Build Coastguard Worker (lengOfReorderedSpectralData <= SCE_TOP_LENGTH)) {
230*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac
231*e5436536SAndroid Build Coastguard Worker .lenOfReorderedSpectralData =
232*e5436536SAndroid Build Coastguard Worker lengOfReorderedSpectralData; /* the decoded value is within range */
233*e5436536SAndroid Build Coastguard Worker } else {
234*e5436536SAndroid Build Coastguard Worker if (lengOfReorderedSpectralData > SCE_TOP_LENGTH) {
235*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac
236*e5436536SAndroid Build Coastguard Worker .lenOfReorderedSpectralData =
237*e5436536SAndroid Build Coastguard Worker SCE_TOP_LENGTH; /* use valid maximum */
238*e5436536SAndroid Build Coastguard Worker }
239*e5436536SAndroid Build Coastguard Worker }
240*e5436536SAndroid Build Coastguard Worker }
241*e5436536SAndroid Build Coastguard Worker
242*e5436536SAndroid Build Coastguard Worker /* ------- SI-Value No 2 ------- */
243*e5436536SAndroid Build Coastguard Worker lengOfLongestCodeword = FDKreadBits(bs, 6) + ERROR_LOLC;
244*e5436536SAndroid Build Coastguard Worker if ((lengOfLongestCodeword >= 0) &&
245*e5436536SAndroid Build Coastguard Worker (lengOfLongestCodeword <= LEN_OF_LONGEST_CW_TOP_LENGTH)) {
246*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
247*e5436536SAndroid Build Coastguard Worker lengOfLongestCodeword; /* the decoded value is within range */
248*e5436536SAndroid Build Coastguard Worker } else {
249*e5436536SAndroid Build Coastguard Worker if (lengOfLongestCodeword > LEN_OF_LONGEST_CW_TOP_LENGTH) {
250*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
251*e5436536SAndroid Build Coastguard Worker LEN_OF_LONGEST_CW_TOP_LENGTH; /* use valid maximum */
252*e5436536SAndroid Build Coastguard Worker }
253*e5436536SAndroid Build Coastguard Worker }
254*e5436536SAndroid Build Coastguard Worker }
255*e5436536SAndroid Build Coastguard Worker
256*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
257*e5436536SAndroid Build Coastguard Worker description: Set up HCR - must be called before every call to
258*e5436536SAndroid Build Coastguard Worker HcrDecoder(). For short block a sorting algorithm is applied to get the SI in
259*e5436536SAndroid Build Coastguard Worker the order that HCR could assemble the qsc's as if it is a long block.
260*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
261*e5436536SAndroid Build Coastguard Worker return: error log
262*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
263*e5436536SAndroid Build Coastguard Worker */
264*e5436536SAndroid Build Coastguard Worker
HcrInit(H_HCR_INFO pHcr,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,HANDLE_FDK_BITSTREAM bs)265*e5436536SAndroid Build Coastguard Worker UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
266*e5436536SAndroid Build Coastguard Worker const SamplingRateInfo *pSamplingRateInfo,
267*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM bs) {
268*e5436536SAndroid Build Coastguard Worker CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
269*e5436536SAndroid Build Coastguard Worker SHORT *pNumLinesInSec;
270*e5436536SAndroid Build Coastguard Worker UCHAR *pCodeBk;
271*e5436536SAndroid Build Coastguard Worker SHORT numSection;
272*e5436536SAndroid Build Coastguard Worker SCHAR cb;
273*e5436536SAndroid Build Coastguard Worker int numLine;
274*e5436536SAndroid Build Coastguard Worker int i;
275*e5436536SAndroid Build Coastguard Worker
276*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.lengthOfReorderedSpectralData =
277*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac
278*e5436536SAndroid Build Coastguard Worker .lenOfReorderedSpectralData;
279*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.lengthOfLongestCodeword =
280*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword;
281*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.pQuantizedSpectralCoefficientsBase =
282*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pSpectralCoefficient;
283*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.quantizedSpectralCoefficientsIdx = 0;
284*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.pCodebook =
285*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
286*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.pNumLineInSect =
287*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
288*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.numSection =
289*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection;
290*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog = 0;
291*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pResultBase =
292*e5436536SAndroid Build Coastguard Worker SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
293*e5436536SAndroid Build Coastguard Worker
294*e5436536SAndroid Build Coastguard Worker FDKsyncCache(bs);
295*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.bitstreamAnchor = (INT)FDKgetValidBits(bs);
296*e5436536SAndroid Build Coastguard Worker
297*e5436536SAndroid Build Coastguard Worker if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */
298*e5436536SAndroid Build Coastguard Worker {
299*e5436536SAndroid Build Coastguard Worker SHORT band;
300*e5436536SAndroid Build Coastguard Worker SHORT maxBand;
301*e5436536SAndroid Build Coastguard Worker SCHAR group;
302*e5436536SAndroid Build Coastguard Worker SCHAR winGroupLen;
303*e5436536SAndroid Build Coastguard Worker SCHAR window;
304*e5436536SAndroid Build Coastguard Worker SCHAR numUnitInBand;
305*e5436536SAndroid Build Coastguard Worker SCHAR cntUnitInBand;
306*e5436536SAndroid Build Coastguard Worker SCHAR groupWin;
307*e5436536SAndroid Build Coastguard Worker SCHAR cb_prev;
308*e5436536SAndroid Build Coastguard Worker
309*e5436536SAndroid Build Coastguard Worker UCHAR *pCodeBook;
310*e5436536SAndroid Build Coastguard Worker const SHORT *BandOffsets;
311*e5436536SAndroid Build Coastguard Worker SCHAR numOfGroups;
312*e5436536SAndroid Build Coastguard Worker
313*e5436536SAndroid Build Coastguard Worker pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; /* in */
314*e5436536SAndroid Build Coastguard Worker pNumLinesInSec = pHcr->decInOut.pNumLineInSect; /* out */
315*e5436536SAndroid Build Coastguard Worker pCodeBk = pHcr->decInOut.pCodebook; /* out */
316*e5436536SAndroid Build Coastguard Worker BandOffsets =
317*e5436536SAndroid Build Coastguard Worker GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo); /* aux */
318*e5436536SAndroid Build Coastguard Worker numOfGroups = GetWindowGroups(pIcsInfo);
319*e5436536SAndroid Build Coastguard Worker
320*e5436536SAndroid Build Coastguard Worker numLine = 0;
321*e5436536SAndroid Build Coastguard Worker numSection = 0;
322*e5436536SAndroid Build Coastguard Worker cb = pCodeBook[0];
323*e5436536SAndroid Build Coastguard Worker cb_prev = pCodeBook[0];
324*e5436536SAndroid Build Coastguard Worker
325*e5436536SAndroid Build Coastguard Worker /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new
326*e5436536SAndroid Build Coastguard Worker * section starts */
327*e5436536SAndroid Build Coastguard Worker
328*e5436536SAndroid Build Coastguard Worker *pCodeBk++ = cb_prev;
329*e5436536SAndroid Build Coastguard Worker
330*e5436536SAndroid Build Coastguard Worker maxBand = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
331*e5436536SAndroid Build Coastguard Worker for (band = 0; band < maxBand;
332*e5436536SAndroid Build Coastguard Worker band++) { /* from low to high sfbs i.e. from low to high frequencies */
333*e5436536SAndroid Build Coastguard Worker numUnitInBand =
334*e5436536SAndroid Build Coastguard Worker ((BandOffsets[band + 1] - BandOffsets[band]) >>
335*e5436536SAndroid Build Coastguard Worker FOUR_LOG_DIV_TWO_LOG); /* get the number of units in current sfb */
336*e5436536SAndroid Build Coastguard Worker for (cntUnitInBand = numUnitInBand; cntUnitInBand != 0;
337*e5436536SAndroid Build Coastguard Worker cntUnitInBand--) { /* for every unit in the band */
338*e5436536SAndroid Build Coastguard Worker for (window = 0, group = 0; group < numOfGroups; group++) {
339*e5436536SAndroid Build Coastguard Worker winGroupLen = (SCHAR)GetWindowGroupLength(
340*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo->icsInfo, group);
341*e5436536SAndroid Build Coastguard Worker for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) {
342*e5436536SAndroid Build Coastguard Worker cb = pCodeBook[group * 16 + band];
343*e5436536SAndroid Build Coastguard Worker if (cb != cb_prev) {
344*e5436536SAndroid Build Coastguard Worker errDetectorInHcrSideinfoShrt(cb, numLine,
345*e5436536SAndroid Build Coastguard Worker &pHcr->decInOut.errorLog);
346*e5436536SAndroid Build Coastguard Worker if (pHcr->decInOut.errorLog != 0) {
347*e5436536SAndroid Build Coastguard Worker return (pHcr->decInOut.errorLog);
348*e5436536SAndroid Build Coastguard Worker }
349*e5436536SAndroid Build Coastguard Worker *pCodeBk++ = cb;
350*e5436536SAndroid Build Coastguard Worker *pNumLinesInSec++ = numLine;
351*e5436536SAndroid Build Coastguard Worker numSection++;
352*e5436536SAndroid Build Coastguard Worker
353*e5436536SAndroid Build Coastguard Worker cb_prev = cb;
354*e5436536SAndroid Build Coastguard Worker numLine = LINES_PER_UNIT;
355*e5436536SAndroid Build Coastguard Worker } else {
356*e5436536SAndroid Build Coastguard Worker numLine += LINES_PER_UNIT;
357*e5436536SAndroid Build Coastguard Worker }
358*e5436536SAndroid Build Coastguard Worker }
359*e5436536SAndroid Build Coastguard Worker }
360*e5436536SAndroid Build Coastguard Worker }
361*e5436536SAndroid Build Coastguard Worker }
362*e5436536SAndroid Build Coastguard Worker
363*e5436536SAndroid Build Coastguard Worker numSection++;
364*e5436536SAndroid Build Coastguard Worker
365*e5436536SAndroid Build Coastguard Worker errDetectorInHcrSideinfoShrt(cb, numLine, &pHcr->decInOut.errorLog);
366*e5436536SAndroid Build Coastguard Worker if (numSection <= 0 || numSection > 1024 / 2) {
367*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK;
368*e5436536SAndroid Build Coastguard Worker }
369*e5436536SAndroid Build Coastguard Worker errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
370*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.lengthOfReorderedSpectralData,
371*e5436536SAndroid Build Coastguard Worker &pHcr->decInOut.errorLog);
372*e5436536SAndroid Build Coastguard Worker if (pHcr->decInOut.errorLog != 0) {
373*e5436536SAndroid Build Coastguard Worker return (pHcr->decInOut.errorLog);
374*e5436536SAndroid Build Coastguard Worker }
375*e5436536SAndroid Build Coastguard Worker
376*e5436536SAndroid Build Coastguard Worker *pCodeBk = cb;
377*e5436536SAndroid Build Coastguard Worker *pNumLinesInSec = numLine;
378*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.numSection = numSection;
379*e5436536SAndroid Build Coastguard Worker
380*e5436536SAndroid Build Coastguard Worker } else /* end short block prepare SI */
381*e5436536SAndroid Build Coastguard Worker { /* long block */
382*e5436536SAndroid Build Coastguard Worker errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
383*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.lengthOfReorderedSpectralData,
384*e5436536SAndroid Build Coastguard Worker &pHcr->decInOut.errorLog);
385*e5436536SAndroid Build Coastguard Worker numSection = pHcr->decInOut.numSection;
386*e5436536SAndroid Build Coastguard Worker pNumLinesInSec = pHcr->decInOut.pNumLineInSect;
387*e5436536SAndroid Build Coastguard Worker pCodeBk = pHcr->decInOut.pCodebook;
388*e5436536SAndroid Build Coastguard Worker if (numSection <= 0 || numSection > 64) {
389*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_LONG_BLOCK;
390*e5436536SAndroid Build Coastguard Worker numSection = 0;
391*e5436536SAndroid Build Coastguard Worker }
392*e5436536SAndroid Build Coastguard Worker
393*e5436536SAndroid Build Coastguard Worker for (i = numSection; i != 0; i--) {
394*e5436536SAndroid Build Coastguard Worker cb = *pCodeBk++;
395*e5436536SAndroid Build Coastguard Worker
396*e5436536SAndroid Build Coastguard Worker if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
397*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= CB_OUT_OF_RANGE_LONG_BLOCK;
398*e5436536SAndroid Build Coastguard Worker }
399*e5436536SAndroid Build Coastguard Worker
400*e5436536SAndroid Build Coastguard Worker numLine = *pNumLinesInSec++;
401*e5436536SAndroid Build Coastguard Worker /* FDK_ASSERT(numLine > 0); */
402*e5436536SAndroid Build Coastguard Worker
403*e5436536SAndroid Build Coastguard Worker if ((numLine <= 0) || (numLine > 1024)) {
404*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK;
405*e5436536SAndroid Build Coastguard Worker }
406*e5436536SAndroid Build Coastguard Worker }
407*e5436536SAndroid Build Coastguard Worker if (pHcr->decInOut.errorLog != 0) {
408*e5436536SAndroid Build Coastguard Worker return (pHcr->decInOut.errorLog);
409*e5436536SAndroid Build Coastguard Worker }
410*e5436536SAndroid Build Coastguard Worker }
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker pCodeBk = pHcr->decInOut.pCodebook;
413*e5436536SAndroid Build Coastguard Worker for (i = 0; i < numSection; i++) {
414*e5436536SAndroid Build Coastguard Worker if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) ||
415*e5436536SAndroid Build Coastguard Worker (*pCodeBk == INTENSITY_HCB)) {
416*e5436536SAndroid Build Coastguard Worker *pCodeBk = 0;
417*e5436536SAndroid Build Coastguard Worker }
418*e5436536SAndroid Build Coastguard Worker pCodeBk++;
419*e5436536SAndroid Build Coastguard Worker }
420*e5436536SAndroid Build Coastguard Worker
421*e5436536SAndroid Build Coastguard Worker /* HCR-sideinfo-input is complete and seems to be valid */
422*e5436536SAndroid Build Coastguard Worker
423*e5436536SAndroid Build Coastguard Worker return (pHcr->decInOut.errorLog);
424*e5436536SAndroid Build Coastguard Worker }
425*e5436536SAndroid Build Coastguard Worker
426*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
427*e5436536SAndroid Build Coastguard Worker description: This function decodes the codewords of the spectral
428*e5436536SAndroid Build Coastguard Worker coefficients from the bitstream according to the HCR algorithm and stores the
429*e5436536SAndroid Build Coastguard Worker quantized spectral coefficients in correct order in the output buffer.
430*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
431*e5436536SAndroid Build Coastguard Worker */
432*e5436536SAndroid Build Coastguard Worker
HcrDecoder(H_HCR_INFO pHcr,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,HANDLE_FDK_BITSTREAM bs)433*e5436536SAndroid Build Coastguard Worker UINT HcrDecoder(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
434*e5436536SAndroid Build Coastguard Worker const SamplingRateInfo *pSamplingRateInfo,
435*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM bs) {
436*e5436536SAndroid Build Coastguard Worker int pTmp1, pTmp2, pTmp3, pTmp4;
437*e5436536SAndroid Build Coastguard Worker int pTmp5;
438*e5436536SAndroid Build Coastguard Worker
439*e5436536SAndroid Build Coastguard Worker INT bitCntOffst;
440*e5436536SAndroid Build Coastguard Worker INT saveBitCnt = (INT)FDKgetValidBits(bs); /* save bitstream position */
441*e5436536SAndroid Build Coastguard Worker
442*e5436536SAndroid Build Coastguard Worker HcrCalcNumCodeword(pHcr);
443*e5436536SAndroid Build Coastguard Worker
444*e5436536SAndroid Build Coastguard Worker HcrSortCodebookAndNumCodewordInSection(pHcr);
445*e5436536SAndroid Build Coastguard Worker
446*e5436536SAndroid Build Coastguard Worker HcrPrepareSegmentationGrid(pHcr);
447*e5436536SAndroid Build Coastguard Worker
448*e5436536SAndroid Build Coastguard Worker HcrExtendedSectionInfo(pHcr);
449*e5436536SAndroid Build Coastguard Worker
450*e5436536SAndroid Build Coastguard Worker if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) != 0) {
451*e5436536SAndroid Build Coastguard Worker return (pHcr->decInOut.errorLog); /* sideinfo is massively corrupt, return
452*e5436536SAndroid Build Coastguard Worker from HCR without having decoded
453*e5436536SAndroid Build Coastguard Worker anything */
454*e5436536SAndroid Build Coastguard Worker }
455*e5436536SAndroid Build Coastguard Worker
456*e5436536SAndroid Build Coastguard Worker DeriveNumberOfExtendedSortedSectionsInSets(
457*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.numSegment,
458*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedCodewordInSection,
459*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx,
460*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedSectionsInSets,
461*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx);
462*e5436536SAndroid Build Coastguard Worker
463*e5436536SAndroid Build Coastguard Worker /* store */
464*e5436536SAndroid Build Coastguard Worker pTmp1 = pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
465*e5436536SAndroid Build Coastguard Worker pTmp2 = pHcr->sectionInfo.extendedSortedCodebookIdx;
466*e5436536SAndroid Build Coastguard Worker pTmp3 = pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
467*e5436536SAndroid Build Coastguard Worker pTmp4 = pHcr->decInOut.quantizedSpectralCoefficientsIdx;
468*e5436536SAndroid Build Coastguard Worker pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
469*e5436536SAndroid Build Coastguard Worker
470*e5436536SAndroid Build Coastguard Worker /* ------- decode meaningful PCWs ------ */
471*e5436536SAndroid Build Coastguard Worker DecodePCWs(bs, pHcr);
472*e5436536SAndroid Build Coastguard Worker
473*e5436536SAndroid Build Coastguard Worker if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) {
474*e5436536SAndroid Build Coastguard Worker /* ------ decode the non-PCWs -------- */
475*e5436536SAndroid Build Coastguard Worker DecodeNonPCWs(bs, pHcr);
476*e5436536SAndroid Build Coastguard Worker }
477*e5436536SAndroid Build Coastguard Worker
478*e5436536SAndroid Build Coastguard Worker errDetectWithinSegmentationFinal(pHcr);
479*e5436536SAndroid Build Coastguard Worker
480*e5436536SAndroid Build Coastguard Worker /* restore */
481*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1;
482*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2;
483*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3;
484*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4;
485*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5;
486*e5436536SAndroid Build Coastguard Worker
487*e5436536SAndroid Build Coastguard Worker HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo,
488*e5436536SAndroid Build Coastguard Worker pSamplingRateInfo);
489*e5436536SAndroid Build Coastguard Worker
490*e5436536SAndroid Build Coastguard Worker /* restore bitstream position */
491*e5436536SAndroid Build Coastguard Worker bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
492*e5436536SAndroid Build Coastguard Worker if (bitCntOffst) {
493*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(bs, bitCntOffst);
494*e5436536SAndroid Build Coastguard Worker }
495*e5436536SAndroid Build Coastguard Worker
496*e5436536SAndroid Build Coastguard Worker return (pHcr->decInOut.errorLog);
497*e5436536SAndroid Build Coastguard Worker }
498*e5436536SAndroid Build Coastguard Worker
499*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
500*e5436536SAndroid Build Coastguard Worker description: This function reorders the quantized spectral coefficients
501*e5436536SAndroid Build Coastguard Worker sectionwise for long- and short-blocks and compares to the LAV (Largest Absolute
502*e5436536SAndroid Build Coastguard Worker Value of the current codebook) -- a counter is incremented if there is an error
503*e5436536SAndroid Build Coastguard Worker detected.
504*e5436536SAndroid Build Coastguard Worker Additional for short-blocks a unit-based-deinterleaving is
505*e5436536SAndroid Build Coastguard Worker applied. Moreover (for short blocks) the scaling is derived (compare plain
506*e5436536SAndroid Build Coastguard Worker huffman decoder).
507*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
508*e5436536SAndroid Build Coastguard Worker */
509*e5436536SAndroid Build Coastguard Worker
HcrReorderQuantizedSpectralCoefficients(H_HCR_INFO pHcr,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo)510*e5436536SAndroid Build Coastguard Worker static void HcrReorderQuantizedSpectralCoefficients(
511*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
512*e5436536SAndroid Build Coastguard Worker const SamplingRateInfo *pSamplingRateInfo) {
513*e5436536SAndroid Build Coastguard Worker INT qsc;
514*e5436536SAndroid Build Coastguard Worker UINT abs_qsc;
515*e5436536SAndroid Build Coastguard Worker UINT i, j;
516*e5436536SAndroid Build Coastguard Worker USHORT numSpectralValuesInSection;
517*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pTeVa;
518*e5436536SAndroid Build Coastguard Worker USHORT lavErrorCnt = 0;
519*e5436536SAndroid Build Coastguard Worker
520*e5436536SAndroid Build Coastguard Worker UINT numSection = pHcr->decInOut.numSection;
521*e5436536SAndroid Build Coastguard Worker SPECTRAL_PTR pQuantizedSpectralCoefficientsBase =
522*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.pQuantizedSpectralCoefficientsBase;
523*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQuantizedSpectralCoefficients =
524*e5436536SAndroid Build Coastguard Worker SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
525*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimShift = aDimCbShift;
526*e5436536SAndroid Build Coastguard Worker const USHORT *pLargestAbsVal = aLargestAbsoluteValue;
527*e5436536SAndroid Build Coastguard Worker UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
528*e5436536SAndroid Build Coastguard Worker USHORT *pNumSortedCodewordInSection =
529*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumSortedCodewordInSection;
530*e5436536SAndroid Build Coastguard Worker USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
531*e5436536SAndroid Build Coastguard Worker FIXP_DBL pTempValues[1024];
532*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pBak = pTempValues;
533*e5436536SAndroid Build Coastguard Worker
534*e5436536SAndroid Build Coastguard Worker FDKmemclear(pTempValues, 1024 * sizeof(FIXP_DBL));
535*e5436536SAndroid Build Coastguard Worker
536*e5436536SAndroid Build Coastguard Worker /* long and short: check if decoded huffman-values (quantized spectral
537*e5436536SAndroid Build Coastguard Worker * coefficients) are within range */
538*e5436536SAndroid Build Coastguard Worker for (i = numSection; i != 0; i--) {
539*e5436536SAndroid Build Coastguard Worker numSpectralValuesInSection = *pNumSortedCodewordInSection++
540*e5436536SAndroid Build Coastguard Worker << pCbDimShift[*pSortedCodebook];
541*e5436536SAndroid Build Coastguard Worker pTeVa = &pTempValues[*pReorderOffset++];
542*e5436536SAndroid Build Coastguard Worker for (j = numSpectralValuesInSection; j != 0; j--) {
543*e5436536SAndroid Build Coastguard Worker qsc = *pQuantizedSpectralCoefficients++;
544*e5436536SAndroid Build Coastguard Worker abs_qsc = fAbs(qsc);
545*e5436536SAndroid Build Coastguard Worker if (abs_qsc <= pLargestAbsVal[*pSortedCodebook]) {
546*e5436536SAndroid Build Coastguard Worker *pTeVa++ = (FIXP_DBL)qsc; /* the qsc value is within range */
547*e5436536SAndroid Build Coastguard Worker } else { /* line is too high .. */
548*e5436536SAndroid Build Coastguard Worker if (abs_qsc ==
549*e5436536SAndroid Build Coastguard Worker Q_VALUE_INVALID) { /* .. because of previous marking --> dont set
550*e5436536SAndroid Build Coastguard Worker LAV flag (would be confusing), just copy out
551*e5436536SAndroid Build Coastguard Worker the already marked value */
552*e5436536SAndroid Build Coastguard Worker *pTeVa++ = (FIXP_DBL)qsc;
553*e5436536SAndroid Build Coastguard Worker } else { /* .. because a too high value was decoded for this cb --> set
554*e5436536SAndroid Build Coastguard Worker LAV flag */
555*e5436536SAndroid Build Coastguard Worker *pTeVa++ = (FIXP_DBL)Q_VALUE_INVALID;
556*e5436536SAndroid Build Coastguard Worker lavErrorCnt += 1;
557*e5436536SAndroid Build Coastguard Worker }
558*e5436536SAndroid Build Coastguard Worker }
559*e5436536SAndroid Build Coastguard Worker }
560*e5436536SAndroid Build Coastguard Worker pSortedCodebook++;
561*e5436536SAndroid Build Coastguard Worker }
562*e5436536SAndroid Build Coastguard Worker
563*e5436536SAndroid Build Coastguard Worker if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
564*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pOut;
565*e5436536SAndroid Build Coastguard Worker FIXP_DBL locMax;
566*e5436536SAndroid Build Coastguard Worker FIXP_DBL tmp;
567*e5436536SAndroid Build Coastguard Worker SCHAR groupoffset;
568*e5436536SAndroid Build Coastguard Worker SCHAR group;
569*e5436536SAndroid Build Coastguard Worker SCHAR band;
570*e5436536SAndroid Build Coastguard Worker SCHAR groupwin;
571*e5436536SAndroid Build Coastguard Worker SCHAR window;
572*e5436536SAndroid Build Coastguard Worker SCHAR numWinGroup;
573*e5436536SAndroid Build Coastguard Worker SHORT interm;
574*e5436536SAndroid Build Coastguard Worker SCHAR numSfbTransm;
575*e5436536SAndroid Build Coastguard Worker SCHAR winGroupLen;
576*e5436536SAndroid Build Coastguard Worker SHORT index;
577*e5436536SAndroid Build Coastguard Worker INT msb;
578*e5436536SAndroid Build Coastguard Worker INT lsb;
579*e5436536SAndroid Build Coastguard Worker
580*e5436536SAndroid Build Coastguard Worker SHORT *pScaleFacHcr = pAacDecoderChannelInfo->pDynData->aScaleFactor;
581*e5436536SAndroid Build Coastguard Worker SHORT *pSfbSclHcr = pAacDecoderChannelInfo->pDynData->aSfbScale;
582*e5436536SAndroid Build Coastguard Worker const SHORT *BandOffsets = GetScaleFactorBandOffsets(
583*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
584*e5436536SAndroid Build Coastguard Worker
585*e5436536SAndroid Build Coastguard Worker pBak = pTempValues;
586*e5436536SAndroid Build Coastguard Worker /* deinterleave unitwise for short blocks */
587*e5436536SAndroid Build Coastguard Worker for (window = 0; window < (8); window++) {
588*e5436536SAndroid Build Coastguard Worker pOut = SPEC(pQuantizedSpectralCoefficientsBase, window,
589*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->granuleLength);
590*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
591*e5436536SAndroid Build Coastguard Worker pTeVa = pBak + (window << FOUR_LOG_DIV_TWO_LOG) +
592*e5436536SAndroid Build Coastguard Worker i * 32; /* distance of lines between unit groups has to be
593*e5436536SAndroid Build Coastguard Worker constant for every framelength (32)! */
594*e5436536SAndroid Build Coastguard Worker for (j = (LINES_PER_UNIT); j != 0; j--) {
595*e5436536SAndroid Build Coastguard Worker *pOut++ = *pTeVa++;
596*e5436536SAndroid Build Coastguard Worker }
597*e5436536SAndroid Build Coastguard Worker }
598*e5436536SAndroid Build Coastguard Worker }
599*e5436536SAndroid Build Coastguard Worker
600*e5436536SAndroid Build Coastguard Worker /* short blocks only */
601*e5436536SAndroid Build Coastguard Worker /* derive global scaling-value for every sfb and every window (as it is done
602*e5436536SAndroid Build Coastguard Worker * in plain-huffman-decoder at short blocks) */
603*e5436536SAndroid Build Coastguard Worker groupoffset = 0;
604*e5436536SAndroid Build Coastguard Worker
605*e5436536SAndroid Build Coastguard Worker numWinGroup = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
606*e5436536SAndroid Build Coastguard Worker numSfbTransm =
607*e5436536SAndroid Build Coastguard Worker GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
608*e5436536SAndroid Build Coastguard Worker
609*e5436536SAndroid Build Coastguard Worker for (group = 0; group < numWinGroup; group++) {
610*e5436536SAndroid Build Coastguard Worker winGroupLen =
611*e5436536SAndroid Build Coastguard Worker GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
612*e5436536SAndroid Build Coastguard Worker for (band = 0; band < numSfbTransm; band++) {
613*e5436536SAndroid Build Coastguard Worker interm = group * 16 + band;
614*e5436536SAndroid Build Coastguard Worker msb = pScaleFacHcr[interm] >> 2;
615*e5436536SAndroid Build Coastguard Worker lsb = pScaleFacHcr[interm] & 3;
616*e5436536SAndroid Build Coastguard Worker for (groupwin = 0; groupwin < winGroupLen; groupwin++) {
617*e5436536SAndroid Build Coastguard Worker window = groupoffset + groupwin;
618*e5436536SAndroid Build Coastguard Worker pBak = SPEC(pQuantizedSpectralCoefficientsBase, window,
619*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->granuleLength);
620*e5436536SAndroid Build Coastguard Worker locMax = FL2FXCONST_DBL(0.0f);
621*e5436536SAndroid Build Coastguard Worker for (index = BandOffsets[band]; index < BandOffsets[band + 1];
622*e5436536SAndroid Build Coastguard Worker index += LINES_PER_UNIT) {
623*e5436536SAndroid Build Coastguard Worker pTeVa = &pBak[index];
624*e5436536SAndroid Build Coastguard Worker for (i = LINES_PER_UNIT; i != 0; i--) {
625*e5436536SAndroid Build Coastguard Worker tmp = (*pTeVa < FL2FXCONST_DBL(0.0f)) ? -*pTeVa++ : *pTeVa++;
626*e5436536SAndroid Build Coastguard Worker locMax = fixMax(tmp, locMax);
627*e5436536SAndroid Build Coastguard Worker }
628*e5436536SAndroid Build Coastguard Worker }
629*e5436536SAndroid Build Coastguard Worker if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
630*e5436536SAndroid Build Coastguard Worker locMax = (FIXP_DBL)MAX_QUANTIZED_VALUE;
631*e5436536SAndroid Build Coastguard Worker }
632*e5436536SAndroid Build Coastguard Worker pSfbSclHcr[window * 16 + band] =
633*e5436536SAndroid Build Coastguard Worker msb - GetScaleFromValue(
634*e5436536SAndroid Build Coastguard Worker locMax, lsb); /* save global scale maxima in this sfb */
635*e5436536SAndroid Build Coastguard Worker }
636*e5436536SAndroid Build Coastguard Worker }
637*e5436536SAndroid Build Coastguard Worker groupoffset +=
638*e5436536SAndroid Build Coastguard Worker GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
639*e5436536SAndroid Build Coastguard Worker }
640*e5436536SAndroid Build Coastguard Worker } else {
641*e5436536SAndroid Build Coastguard Worker /* copy straight for long-blocks */
642*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients =
643*e5436536SAndroid Build Coastguard Worker SPEC_LONG(pQuantizedSpectralCoefficientsBase);
644*e5436536SAndroid Build Coastguard Worker for (i = 1024; i != 0; i--) {
645*e5436536SAndroid Build Coastguard Worker *pQuantizedSpectralCoefficients++ = *pBak++;
646*e5436536SAndroid Build Coastguard Worker }
647*e5436536SAndroid Build Coastguard Worker }
648*e5436536SAndroid Build Coastguard Worker
649*e5436536SAndroid Build Coastguard Worker if (lavErrorCnt != 0) {
650*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= LAV_VIOLATION;
651*e5436536SAndroid Build Coastguard Worker }
652*e5436536SAndroid Build Coastguard Worker }
653*e5436536SAndroid Build Coastguard Worker
654*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
655*e5436536SAndroid Build Coastguard Worker description: This function calculates the number of codewords
656*e5436536SAndroid Build Coastguard Worker for each section (numCodewordInSection) and the number of
657*e5436536SAndroid Build Coastguard Worker codewords for all sections (numCodeword). For zero and intensity codebooks a
658*e5436536SAndroid Build Coastguard Worker entry is also done in the variable numCodewordInSection. It is assumed that the
659*e5436536SAndroid Build Coastguard Worker codebook is a two tuples codebook. This is needed later for the calculation of
660*e5436536SAndroid Build Coastguard Worker the base addresses for the reordering of the quantize spectral coefficients at
661*e5436536SAndroid Build Coastguard Worker the end of the hcr tool. The variable numCodeword contain the number of
662*e5436536SAndroid Build Coastguard Worker codewords which are really in the bitstream. Zero or intensity codebooks does
663*e5436536SAndroid Build Coastguard Worker not increase the variable numCodewords.
664*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
665*e5436536SAndroid Build Coastguard Worker return: -
666*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
667*e5436536SAndroid Build Coastguard Worker */
668*e5436536SAndroid Build Coastguard Worker
HcrCalcNumCodeword(H_HCR_INFO pHcr)669*e5436536SAndroid Build Coastguard Worker static void HcrCalcNumCodeword(H_HCR_INFO pHcr) {
670*e5436536SAndroid Build Coastguard Worker int hcrSection;
671*e5436536SAndroid Build Coastguard Worker UINT numCodeword;
672*e5436536SAndroid Build Coastguard Worker
673*e5436536SAndroid Build Coastguard Worker UINT numSection = pHcr->decInOut.numSection;
674*e5436536SAndroid Build Coastguard Worker UCHAR *pCodebook = pHcr->decInOut.pCodebook;
675*e5436536SAndroid Build Coastguard Worker SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect;
676*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimShift = aDimCbShift;
677*e5436536SAndroid Build Coastguard Worker
678*e5436536SAndroid Build Coastguard Worker USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
679*e5436536SAndroid Build Coastguard Worker
680*e5436536SAndroid Build Coastguard Worker numCodeword = 0;
681*e5436536SAndroid Build Coastguard Worker for (hcrSection = numSection; hcrSection != 0; hcrSection--) {
682*e5436536SAndroid Build Coastguard Worker *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook];
683*e5436536SAndroid Build Coastguard Worker if (*pCodebook != 0) {
684*e5436536SAndroid Build Coastguard Worker numCodeword += *pNumCodewordInSection;
685*e5436536SAndroid Build Coastguard Worker }
686*e5436536SAndroid Build Coastguard Worker pNumCodewordInSection++;
687*e5436536SAndroid Build Coastguard Worker pCodebook++;
688*e5436536SAndroid Build Coastguard Worker }
689*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numCodeword = numCodeword;
690*e5436536SAndroid Build Coastguard Worker }
691*e5436536SAndroid Build Coastguard Worker
692*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
693*e5436536SAndroid Build Coastguard Worker description: This function calculates the number
694*e5436536SAndroid Build Coastguard Worker of sorted codebooks and sorts the codebooks and the
695*e5436536SAndroid Build Coastguard Worker numCodewordInSection according to the priority.
696*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
697*e5436536SAndroid Build Coastguard Worker */
698*e5436536SAndroid Build Coastguard Worker
HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr)699*e5436536SAndroid Build Coastguard Worker static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) {
700*e5436536SAndroid Build Coastguard Worker UINT i, j, k;
701*e5436536SAndroid Build Coastguard Worker UCHAR temp;
702*e5436536SAndroid Build Coastguard Worker UINT counter;
703*e5436536SAndroid Build Coastguard Worker UINT startOffset;
704*e5436536SAndroid Build Coastguard Worker UINT numZeroSection;
705*e5436536SAndroid Build Coastguard Worker UCHAR *pDest;
706*e5436536SAndroid Build Coastguard Worker UINT numSectionDec;
707*e5436536SAndroid Build Coastguard Worker
708*e5436536SAndroid Build Coastguard Worker UINT numSection = pHcr->decInOut.numSection;
709*e5436536SAndroid Build Coastguard Worker UCHAR *pCodebook = pHcr->decInOut.pCodebook;
710*e5436536SAndroid Build Coastguard Worker UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
711*e5436536SAndroid Build Coastguard Worker USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
712*e5436536SAndroid Build Coastguard Worker USHORT *pNumSortedCodewordInSection =
713*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumSortedCodewordInSection;
714*e5436536SAndroid Build Coastguard Worker UCHAR *pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
715*e5436536SAndroid Build Coastguard Worker USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
716*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbPriority = aCbPriority;
717*e5436536SAndroid Build Coastguard Worker const UCHAR *pMinOfCbPair = aMinOfCbPair;
718*e5436536SAndroid Build Coastguard Worker const UCHAR *pMaxOfCbPair = aMaxOfCbPair;
719*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimShift = aDimCbShift;
720*e5436536SAndroid Build Coastguard Worker
721*e5436536SAndroid Build Coastguard Worker UINT searchStart = 0;
722*e5436536SAndroid Build Coastguard Worker
723*e5436536SAndroid Build Coastguard Worker /* calculate *pNumSortedSection and store the priorities in array
724*e5436536SAndroid Build Coastguard Worker * pSortedCdebook */
725*e5436536SAndroid Build Coastguard Worker pDest = pSortedCodebook;
726*e5436536SAndroid Build Coastguard Worker numZeroSection = 0;
727*e5436536SAndroid Build Coastguard Worker for (i = numSection; i != 0; i--) {
728*e5436536SAndroid Build Coastguard Worker if (pCbPriority[*pCodebook] == 0) {
729*e5436536SAndroid Build Coastguard Worker numZeroSection += 1;
730*e5436536SAndroid Build Coastguard Worker }
731*e5436536SAndroid Build Coastguard Worker *pDest++ = pCbPriority[*pCodebook++];
732*e5436536SAndroid Build Coastguard Worker }
733*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numSortedSection =
734*e5436536SAndroid Build Coastguard Worker numSection - numZeroSection; /* numSortedSection contains no zero or
735*e5436536SAndroid Build Coastguard Worker intensity section */
736*e5436536SAndroid Build Coastguard Worker pCodebook = pHcr->decInOut.pCodebook;
737*e5436536SAndroid Build Coastguard Worker
738*e5436536SAndroid Build Coastguard Worker /* sort priorities of the codebooks in array pSortedCdebook[] */
739*e5436536SAndroid Build Coastguard Worker numSectionDec = numSection - 1;
740*e5436536SAndroid Build Coastguard Worker if (numSectionDec > 0) {
741*e5436536SAndroid Build Coastguard Worker counter = numSectionDec;
742*e5436536SAndroid Build Coastguard Worker for (j = numSectionDec; j != 0; j--) {
743*e5436536SAndroid Build Coastguard Worker for (i = 0; i < counter; i++) {
744*e5436536SAndroid Build Coastguard Worker /* swap priorities */
745*e5436536SAndroid Build Coastguard Worker if (pSortedCodebook[i + 1] > pSortedCodebook[i]) {
746*e5436536SAndroid Build Coastguard Worker temp = pSortedCodebook[i];
747*e5436536SAndroid Build Coastguard Worker pSortedCodebook[i] = pSortedCodebook[i + 1];
748*e5436536SAndroid Build Coastguard Worker pSortedCodebook[i + 1] = temp;
749*e5436536SAndroid Build Coastguard Worker }
750*e5436536SAndroid Build Coastguard Worker }
751*e5436536SAndroid Build Coastguard Worker counter -= 1;
752*e5436536SAndroid Build Coastguard Worker }
753*e5436536SAndroid Build Coastguard Worker }
754*e5436536SAndroid Build Coastguard Worker
755*e5436536SAndroid Build Coastguard Worker /* clear codebookSwitch array */
756*e5436536SAndroid Build Coastguard Worker for (i = numSection; i != 0; i--) {
757*e5436536SAndroid Build Coastguard Worker *pCodebookSwitch++ = 0;
758*e5436536SAndroid Build Coastguard Worker }
759*e5436536SAndroid Build Coastguard Worker pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
760*e5436536SAndroid Build Coastguard Worker
761*e5436536SAndroid Build Coastguard Worker /* sort sectionCodebooks and numCodwordsInSection and calculate
762*e5436536SAndroid Build Coastguard Worker * pReorderOffst[j] */
763*e5436536SAndroid Build Coastguard Worker for (j = 0; j < numSection; j++) {
764*e5436536SAndroid Build Coastguard Worker for (i = searchStart; i < numSection; i++) {
765*e5436536SAndroid Build Coastguard Worker if (pCodebookSwitch[i] == 0 &&
766*e5436536SAndroid Build Coastguard Worker (pMinOfCbPair[pSortedCodebook[j]] == pCodebook[i] ||
767*e5436536SAndroid Build Coastguard Worker pMaxOfCbPair[pSortedCodebook[j]] == pCodebook[i])) {
768*e5436536SAndroid Build Coastguard Worker pCodebookSwitch[i] = 1;
769*e5436536SAndroid Build Coastguard Worker pSortedCodebook[j] = pCodebook[i]; /* sort codebook */
770*e5436536SAndroid Build Coastguard Worker pNumSortedCodewordInSection[j] =
771*e5436536SAndroid Build Coastguard Worker pNumCodewordInSection[i]; /* sort NumCodewordInSection */
772*e5436536SAndroid Build Coastguard Worker
773*e5436536SAndroid Build Coastguard Worker startOffset = 0;
774*e5436536SAndroid Build Coastguard Worker for (k = 0; k < i; k++) { /* make entry in pReorderOffst */
775*e5436536SAndroid Build Coastguard Worker startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]];
776*e5436536SAndroid Build Coastguard Worker }
777*e5436536SAndroid Build Coastguard Worker pReorderOffset[j] =
778*e5436536SAndroid Build Coastguard Worker startOffset; /* offset for reordering the codewords */
779*e5436536SAndroid Build Coastguard Worker
780*e5436536SAndroid Build Coastguard Worker if (i == searchStart) {
781*e5436536SAndroid Build Coastguard Worker k = i;
782*e5436536SAndroid Build Coastguard Worker while (pCodebookSwitch[k++] == 1) searchStart++;
783*e5436536SAndroid Build Coastguard Worker }
784*e5436536SAndroid Build Coastguard Worker break;
785*e5436536SAndroid Build Coastguard Worker }
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 description: This function calculates the segmentation, which includes
792*e5436536SAndroid Build Coastguard Worker numSegment, leftStartOfSegment, rightStartOfSegment and remainingBitsInSegment.
793*e5436536SAndroid Build Coastguard Worker The segmentation could be visualized a as kind of
794*e5436536SAndroid Build Coastguard Worker 'overlay-grid' for the bitstream-block holding the HCR-encoded
795*e5436536SAndroid Build Coastguard Worker quantized-spectral-coefficients.
796*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
797*e5436536SAndroid Build Coastguard Worker */
798*e5436536SAndroid Build Coastguard Worker
HcrPrepareSegmentationGrid(H_HCR_INFO pHcr)799*e5436536SAndroid Build Coastguard Worker static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) {
800*e5436536SAndroid Build Coastguard Worker USHORT i, j;
801*e5436536SAndroid Build Coastguard Worker USHORT numSegment = 0;
802*e5436536SAndroid Build Coastguard Worker INT segmentStart = 0;
803*e5436536SAndroid Build Coastguard Worker UCHAR segmentWidth;
804*e5436536SAndroid Build Coastguard Worker UCHAR lastSegmentWidth;
805*e5436536SAndroid Build Coastguard Worker UCHAR sortedCodebook;
806*e5436536SAndroid Build Coastguard Worker UCHAR endFlag = 0;
807*e5436536SAndroid Build Coastguard Worker INT intermediateResult;
808*e5436536SAndroid Build Coastguard Worker
809*e5436536SAndroid Build Coastguard Worker SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
810*e5436536SAndroid Build Coastguard Worker SHORT lengthOfReorderedSpectralData =
811*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.lengthOfReorderedSpectralData;
812*e5436536SAndroid Build Coastguard Worker UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
813*e5436536SAndroid Build Coastguard Worker UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
814*e5436536SAndroid Build Coastguard Worker USHORT *pNumSortedCodewordInSection =
815*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumSortedCodewordInSection;
816*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
817*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
818*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
819*e5436536SAndroid Build Coastguard Worker const UCHAR *pMaxCwLength = aMaxCwLen;
820*e5436536SAndroid Build Coastguard Worker
821*e5436536SAndroid Build Coastguard Worker for (i = numSortedSection; i != 0; i--) {
822*e5436536SAndroid Build Coastguard Worker sortedCodebook = *pSortedCodebook++;
823*e5436536SAndroid Build Coastguard Worker segmentWidth =
824*e5436536SAndroid Build Coastguard Worker fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword);
825*e5436536SAndroid Build Coastguard Worker
826*e5436536SAndroid Build Coastguard Worker for (j = *pNumSortedCodewordInSection; j != 0; j--) {
827*e5436536SAndroid Build Coastguard Worker /* width allows a new segment */
828*e5436536SAndroid Build Coastguard Worker intermediateResult = segmentStart;
829*e5436536SAndroid Build Coastguard Worker if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) {
830*e5436536SAndroid Build Coastguard Worker /* store segment start, segment length and increment the number of
831*e5436536SAndroid Build Coastguard Worker * segments */
832*e5436536SAndroid Build Coastguard Worker *pLeftStartOfSegment++ = intermediateResult;
833*e5436536SAndroid Build Coastguard Worker *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1;
834*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment++ = segmentWidth;
835*e5436536SAndroid Build Coastguard Worker segmentStart += segmentWidth;
836*e5436536SAndroid Build Coastguard Worker numSegment += 1;
837*e5436536SAndroid Build Coastguard Worker }
838*e5436536SAndroid Build Coastguard Worker /* width does not allow a new segment */
839*e5436536SAndroid Build Coastguard Worker else {
840*e5436536SAndroid Build Coastguard Worker /* correct the last segment length */
841*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment--;
842*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment--;
843*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment--;
844*e5436536SAndroid Build Coastguard Worker segmentStart = *pLeftStartOfSegment;
845*e5436536SAndroid Build Coastguard Worker
846*e5436536SAndroid Build Coastguard Worker lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart;
847*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment = lastSegmentWidth;
848*e5436536SAndroid Build Coastguard Worker *pRightStartOfSegment = segmentStart + lastSegmentWidth - 1;
849*e5436536SAndroid Build Coastguard Worker endFlag = 1;
850*e5436536SAndroid Build Coastguard Worker break;
851*e5436536SAndroid Build Coastguard Worker }
852*e5436536SAndroid Build Coastguard Worker }
853*e5436536SAndroid Build Coastguard Worker pNumSortedCodewordInSection++;
854*e5436536SAndroid Build Coastguard Worker if (endFlag != 0) {
855*e5436536SAndroid Build Coastguard Worker break;
856*e5436536SAndroid Build Coastguard Worker }
857*e5436536SAndroid Build Coastguard Worker }
858*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.numSegment = numSegment;
859*e5436536SAndroid Build Coastguard Worker }
860*e5436536SAndroid Build Coastguard Worker
861*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
862*e5436536SAndroid Build Coastguard Worker description: This function adapts the sorted section boundaries to the
863*e5436536SAndroid Build Coastguard Worker boundaries of segmentation. If the section lengths does not fit completely into
864*e5436536SAndroid Build Coastguard Worker the current segment, the section is spitted into two so called 'extended
865*e5436536SAndroid Build Coastguard Worker sections'. The extended-section-info
866*e5436536SAndroid Build Coastguard Worker (pNumExtendedSortedCodewordInSectin and pExtendedSortedCodebook) is updated in
867*e5436536SAndroid Build Coastguard Worker this case.
868*e5436536SAndroid Build Coastguard Worker
869*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
870*e5436536SAndroid Build Coastguard Worker */
871*e5436536SAndroid Build Coastguard Worker
HcrExtendedSectionInfo(H_HCR_INFO pHcr)872*e5436536SAndroid Build Coastguard Worker static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) {
873*e5436536SAndroid Build Coastguard Worker UINT srtSecCnt = 0; /* counter for sorted sections */
874*e5436536SAndroid Build Coastguard Worker UINT xSrtScCnt = 0; /* counter for extended sorted sections */
875*e5436536SAndroid Build Coastguard Worker UINT remainNumCwInSortSec;
876*e5436536SAndroid Build Coastguard Worker UINT inSegmentRemainNumCW;
877*e5436536SAndroid Build Coastguard Worker
878*e5436536SAndroid Build Coastguard Worker UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
879*e5436536SAndroid Build Coastguard Worker UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
880*e5436536SAndroid Build Coastguard Worker USHORT *pNumSortedCodewordInSection =
881*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumSortedCodewordInSection;
882*e5436536SAndroid Build Coastguard Worker UCHAR *pExtendedSortedCoBo = pHcr->sectionInfo.pExtendedSortedCodebook;
883*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtSortCwInSect =
884*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
885*e5436536SAndroid Build Coastguard Worker UINT numSegment = pHcr->segmentInfo.numSegment;
886*e5436536SAndroid Build Coastguard Worker UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
887*e5436536SAndroid Build Coastguard Worker SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
888*e5436536SAndroid Build Coastguard Worker const UCHAR *pMaxCwLength = aMaxCwLen;
889*e5436536SAndroid Build Coastguard Worker
890*e5436536SAndroid Build Coastguard Worker remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
891*e5436536SAndroid Build Coastguard Worker inSegmentRemainNumCW = numSegment;
892*e5436536SAndroid Build Coastguard Worker
893*e5436536SAndroid Build Coastguard Worker while (srtSecCnt < numSortedSection) {
894*e5436536SAndroid Build Coastguard Worker if (inSegmentRemainNumCW < remainNumCwInSortSec) {
895*e5436536SAndroid Build Coastguard Worker pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
896*e5436536SAndroid Build Coastguard Worker pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
897*e5436536SAndroid Build Coastguard Worker
898*e5436536SAndroid Build Coastguard Worker remainNumCwInSortSec -= inSegmentRemainNumCW;
899*e5436536SAndroid Build Coastguard Worker inSegmentRemainNumCW = numSegment;
900*e5436536SAndroid Build Coastguard Worker /* data of a sorted section was not integrated in extended sorted section
901*e5436536SAndroid Build Coastguard Worker */
902*e5436536SAndroid Build Coastguard Worker } else if (inSegmentRemainNumCW == remainNumCwInSortSec) {
903*e5436536SAndroid Build Coastguard Worker pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
904*e5436536SAndroid Build Coastguard Worker pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
905*e5436536SAndroid Build Coastguard Worker
906*e5436536SAndroid Build Coastguard Worker srtSecCnt++;
907*e5436536SAndroid Build Coastguard Worker remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
908*e5436536SAndroid Build Coastguard Worker inSegmentRemainNumCW = numSegment;
909*e5436536SAndroid Build Coastguard Worker /* data of a sorted section was integrated in extended sorted section */
910*e5436536SAndroid Build Coastguard Worker } else { /* inSegmentRemainNumCW > remainNumCwInSortSec */
911*e5436536SAndroid Build Coastguard Worker pNumExtSortCwInSect[xSrtScCnt] = remainNumCwInSortSec;
912*e5436536SAndroid Build Coastguard Worker pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
913*e5436536SAndroid Build Coastguard Worker
914*e5436536SAndroid Build Coastguard Worker inSegmentRemainNumCW -= remainNumCwInSortSec;
915*e5436536SAndroid Build Coastguard Worker srtSecCnt++;
916*e5436536SAndroid Build Coastguard Worker remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
917*e5436536SAndroid Build Coastguard Worker /* data of a sorted section was integrated in extended sorted section */
918*e5436536SAndroid Build Coastguard Worker }
919*e5436536SAndroid Build Coastguard Worker pMaxLenOfCbInExtSrtSec[xSrtScCnt] =
920*e5436536SAndroid Build Coastguard Worker fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]],
921*e5436536SAndroid Build Coastguard Worker (INT)lengthOfLongestCodeword);
922*e5436536SAndroid Build Coastguard Worker
923*e5436536SAndroid Build Coastguard Worker xSrtScCnt += 1;
924*e5436536SAndroid Build Coastguard Worker
925*e5436536SAndroid Build Coastguard Worker if (xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
926*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= EXTENDED_SORTED_COUNTER_OVERFLOW;
927*e5436536SAndroid Build Coastguard Worker return;
928*e5436536SAndroid Build Coastguard Worker }
929*e5436536SAndroid Build Coastguard Worker }
930*e5436536SAndroid Build Coastguard Worker pNumExtSortCwInSect[xSrtScCnt] = 0;
931*e5436536SAndroid Build Coastguard Worker }
932*e5436536SAndroid Build Coastguard Worker
933*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
934*e5436536SAndroid Build Coastguard Worker description: This function calculates the number of extended sorted
935*e5436536SAndroid Build Coastguard Worker sections which belong to the sets. Each set from set 0 (one and only set for the
936*e5436536SAndroid Build Coastguard Worker PCWs) till to the last set gets a entry in the array to which
937*e5436536SAndroid Build Coastguard Worker 'pNumExtendedSortedSectinsInSets' points to.
938*e5436536SAndroid Build Coastguard Worker
939*e5436536SAndroid Build Coastguard Worker Calculation: The entrys in
940*e5436536SAndroid Build Coastguard Worker pNumExtendedSortedCodewordInSectin are added untill the value numSegment is
941*e5436536SAndroid Build Coastguard Worker reached. Then the sum_variable is cleared and the calculation starts from the
942*e5436536SAndroid Build Coastguard Worker beginning. As much extended sorted Sections are summed up to reach the value
943*e5436536SAndroid Build Coastguard Worker numSegment, as much is the current entry in *pNumExtendedSortedCodewordInSectin.
944*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
945*e5436536SAndroid Build Coastguard Worker */
DeriveNumberOfExtendedSortedSectionsInSets(UINT numSegment,USHORT * pNumExtendedSortedCodewordInSection,int numExtendedSortedCodewordInSectionIdx,USHORT * pNumExtendedSortedSectionsInSets,int numExtendedSortedSectionsInSetsIdx)946*e5436536SAndroid Build Coastguard Worker static void DeriveNumberOfExtendedSortedSectionsInSets(
947*e5436536SAndroid Build Coastguard Worker UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
948*e5436536SAndroid Build Coastguard Worker int numExtendedSortedCodewordInSectionIdx,
949*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtendedSortedSectionsInSets,
950*e5436536SAndroid Build Coastguard Worker int numExtendedSortedSectionsInSetsIdx) {
951*e5436536SAndroid Build Coastguard Worker USHORT counter = 0;
952*e5436536SAndroid Build Coastguard Worker UINT cwSum = 0;
953*e5436536SAndroid Build Coastguard Worker USHORT *pNumExSortCwInSec = pNumExtendedSortedCodewordInSection;
954*e5436536SAndroid Build Coastguard Worker USHORT *pNumExSortSecInSets = pNumExtendedSortedSectionsInSets;
955*e5436536SAndroid Build Coastguard Worker
956*e5436536SAndroid Build Coastguard Worker while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) {
957*e5436536SAndroid Build Coastguard Worker cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx];
958*e5436536SAndroid Build Coastguard Worker numExtendedSortedCodewordInSectionIdx++;
959*e5436536SAndroid Build Coastguard Worker if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
960*e5436536SAndroid Build Coastguard Worker return;
961*e5436536SAndroid Build Coastguard Worker }
962*e5436536SAndroid Build Coastguard Worker if (cwSum > numSegment) {
963*e5436536SAndroid Build Coastguard Worker return;
964*e5436536SAndroid Build Coastguard Worker }
965*e5436536SAndroid Build Coastguard Worker counter++;
966*e5436536SAndroid Build Coastguard Worker if (counter > 1024 / 4) {
967*e5436536SAndroid Build Coastguard Worker return;
968*e5436536SAndroid Build Coastguard Worker }
969*e5436536SAndroid Build Coastguard Worker if (cwSum == numSegment) {
970*e5436536SAndroid Build Coastguard Worker pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter;
971*e5436536SAndroid Build Coastguard Worker numExtendedSortedSectionsInSetsIdx++;
972*e5436536SAndroid Build Coastguard Worker if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
973*e5436536SAndroid Build Coastguard Worker return;
974*e5436536SAndroid Build Coastguard Worker }
975*e5436536SAndroid Build Coastguard Worker counter = 0;
976*e5436536SAndroid Build Coastguard Worker cwSum = 0;
977*e5436536SAndroid Build Coastguard Worker }
978*e5436536SAndroid Build Coastguard Worker }
979*e5436536SAndroid Build Coastguard Worker pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] =
980*e5436536SAndroid Build Coastguard Worker counter; /* save last entry for the last - probably shorter - set */
981*e5436536SAndroid Build Coastguard Worker }
982*e5436536SAndroid Build Coastguard Worker
983*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
984*e5436536SAndroid Build Coastguard Worker description: This function decodes all priority codewords (PCWs) in a
985*e5436536SAndroid Build Coastguard Worker spectrum (within set 0). The calculation of the PCWs is managed in two loops.
986*e5436536SAndroid Build Coastguard Worker The loopcounter of the outer loop is set to the first value pointer
987*e5436536SAndroid Build Coastguard Worker pNumExtendedSortedSectionsInSets points to. This value
988*e5436536SAndroid Build Coastguard Worker represents the number of extended sorted sections within set 0. The loopcounter
989*e5436536SAndroid Build Coastguard Worker of the inner loop is set to the first value pointer
990*e5436536SAndroid Build Coastguard Worker pNumExtendedSortedCodewordInSectin points to. The value
991*e5436536SAndroid Build Coastguard Worker represents the number of extended sorted codewords in sections (the original
992*e5436536SAndroid Build Coastguard Worker sections have been splitted to go along with the borders of the sets). Each time
993*e5436536SAndroid Build Coastguard Worker the number of the extended sorted codewords in sections are de- coded, the
994*e5436536SAndroid Build Coastguard Worker pointer 'pNumExtendedSortedCodewordInSectin' is incremented by one.
995*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
996*e5436536SAndroid Build Coastguard Worker */
DecodePCWs(HANDLE_FDK_BITSTREAM bs,H_HCR_INFO pHcr)997*e5436536SAndroid Build Coastguard Worker static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
998*e5436536SAndroid Build Coastguard Worker UINT i;
999*e5436536SAndroid Build Coastguard Worker USHORT extSortSec;
1000*e5436536SAndroid Build Coastguard Worker USHORT curExtSortCwInSec;
1001*e5436536SAndroid Build Coastguard Worker UCHAR codebook;
1002*e5436536SAndroid Build Coastguard Worker UCHAR dimension;
1003*e5436536SAndroid Build Coastguard Worker const UINT *pCurrentTree;
1004*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantValBase;
1005*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantVal;
1006*e5436536SAndroid Build Coastguard Worker
1007*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtendedSortedCodewordInSection =
1008*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
1009*e5436536SAndroid Build Coastguard Worker int numExtendedSortedCodewordInSectionIdx =
1010*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
1011*e5436536SAndroid Build Coastguard Worker UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
1012*e5436536SAndroid Build Coastguard Worker int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
1013*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtendedSortedSectionsInSets =
1014*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
1015*e5436536SAndroid Build Coastguard Worker int numExtendedSortedSectionsInSetsIdx =
1016*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
1017*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQuantizedSpectralCoefficients =
1018*e5436536SAndroid Build Coastguard Worker SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
1019*e5436536SAndroid Build Coastguard Worker int quantizedSpectralCoefficientsIdx =
1020*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.quantizedSpectralCoefficientsIdx;
1021*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
1022*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1023*e5436536SAndroid Build Coastguard Worker UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
1024*e5436536SAndroid Build Coastguard Worker int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
1025*e5436536SAndroid Build Coastguard Worker UCHAR maxAllowedCwLen;
1026*e5436536SAndroid Build Coastguard Worker int numDecodedBits;
1027*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimension = aDimCb;
1028*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbSign = aSignCb;
1029*e5436536SAndroid Build Coastguard Worker
1030*e5436536SAndroid Build Coastguard Worker /* clear result array */
1031*e5436536SAndroid Build Coastguard Worker FDKmemclear(pQuantizedSpectralCoefficients + quantizedSpectralCoefficientsIdx,
1032*e5436536SAndroid Build Coastguard Worker 1024 * sizeof(FIXP_DBL));
1033*e5436536SAndroid Build Coastguard Worker
1034*e5436536SAndroid Build Coastguard Worker /* decode all PCWs in the extended sorted section(s) belonging to set 0 */
1035*e5436536SAndroid Build Coastguard Worker for (extSortSec =
1036*e5436536SAndroid Build Coastguard Worker pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
1037*e5436536SAndroid Build Coastguard Worker extSortSec != 0; extSortSec--) {
1038*e5436536SAndroid Build Coastguard Worker codebook =
1039*e5436536SAndroid Build Coastguard Worker pExtendedSortedCodebook[extendedSortedCodebookIdx]; /* get codebook for
1040*e5436536SAndroid Build Coastguard Worker this extended
1041*e5436536SAndroid Build Coastguard Worker sorted section
1042*e5436536SAndroid Build Coastguard Worker and increment ptr
1043*e5436536SAndroid Build Coastguard Worker to cb of next
1044*e5436536SAndroid Build Coastguard Worker ext. sort sec */
1045*e5436536SAndroid Build Coastguard Worker extendedSortedCodebookIdx++;
1046*e5436536SAndroid Build Coastguard Worker if (extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
1047*e5436536SAndroid Build Coastguard Worker return;
1048*e5436536SAndroid Build Coastguard Worker }
1049*e5436536SAndroid Build Coastguard Worker dimension = pCbDimension[codebook]; /* get dimension of codebook of this
1050*e5436536SAndroid Build Coastguard Worker extended sort. sec. */
1051*e5436536SAndroid Build Coastguard Worker pCurrentTree =
1052*e5436536SAndroid Build Coastguard Worker aHuffTable[codebook]; /* convert codebook to pointer to QSCs */
1053*e5436536SAndroid Build Coastguard Worker pQuantValBase =
1054*e5436536SAndroid Build Coastguard Worker aQuantTable[codebook]; /* convert codebook to index to table of QSCs */
1055*e5436536SAndroid Build Coastguard Worker maxAllowedCwLen = pMaxLenOfCbInExtSrtSec[maxLenOfCbInExtSrtSecIdx];
1056*e5436536SAndroid Build Coastguard Worker maxLenOfCbInExtSrtSecIdx++;
1057*e5436536SAndroid Build Coastguard Worker if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
1058*e5436536SAndroid Build Coastguard Worker return;
1059*e5436536SAndroid Build Coastguard Worker }
1060*e5436536SAndroid Build Coastguard Worker
1061*e5436536SAndroid Build Coastguard Worker /* switch for decoding with different codebooks: */
1062*e5436536SAndroid Build Coastguard Worker if (pCbSign[codebook] ==
1063*e5436536SAndroid Build Coastguard Worker 0) { /* no sign bits follow after the codeword-body */
1064*e5436536SAndroid Build Coastguard Worker /* PCW_BodyONLY */
1065*e5436536SAndroid Build Coastguard Worker /*==============*/
1066*e5436536SAndroid Build Coastguard Worker
1067*e5436536SAndroid Build Coastguard Worker for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
1068*e5436536SAndroid Build Coastguard Worker [numExtendedSortedCodewordInSectionIdx];
1069*e5436536SAndroid Build Coastguard Worker curExtSortCwInSec != 0; curExtSortCwInSec--) {
1070*e5436536SAndroid Build Coastguard Worker numDecodedBits = 0;
1071*e5436536SAndroid Build Coastguard Worker
1072*e5436536SAndroid Build Coastguard Worker /* decode PCW_BODY */
1073*e5436536SAndroid Build Coastguard Worker pQuantVal = DecodePCW_Body(
1074*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
1075*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1076*e5436536SAndroid Build Coastguard Worker
1077*e5436536SAndroid Build Coastguard Worker /* result is written out here because NO sign bits follow the body */
1078*e5436536SAndroid Build Coastguard Worker for (i = dimension; i != 0; i--) {
1079*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
1080*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)*pQuantVal++; /* write quant. spec. coef. into
1081*e5436536SAndroid Build Coastguard Worker spectrum; sign is already valid */
1082*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx++;
1083*e5436536SAndroid Build Coastguard Worker if (quantizedSpectralCoefficientsIdx >= 1024) {
1084*e5436536SAndroid Build Coastguard Worker return;
1085*e5436536SAndroid Build Coastguard Worker }
1086*e5436536SAndroid Build Coastguard Worker }
1087*e5436536SAndroid Build Coastguard Worker
1088*e5436536SAndroid Build Coastguard Worker /* one more PCW should be decoded */
1089*e5436536SAndroid Build Coastguard Worker
1090*e5436536SAndroid Build Coastguard Worker if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) {
1091*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED;
1092*e5436536SAndroid Build Coastguard Worker }
1093*e5436536SAndroid Build Coastguard Worker
1094*e5436536SAndroid Build Coastguard Worker if (1 == errDetectPcwSegmentation(
1095*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY,
1096*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients +
1097*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx - dimension,
1098*e5436536SAndroid Build Coastguard Worker dimension)) {
1099*e5436536SAndroid Build Coastguard Worker return;
1100*e5436536SAndroid Build Coastguard Worker }
1101*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment++; /* update pointer for decoding the next PCW */
1102*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment++; /* update pointer for decoding the next PCW
1103*e5436536SAndroid Build Coastguard Worker */
1104*e5436536SAndroid Build Coastguard Worker }
1105*e5436536SAndroid Build Coastguard Worker } else if ((codebook < 11) && (pCbSign[codebook] ==
1106*e5436536SAndroid Build Coastguard Worker 1)) { /* possibly there follow 1,2,3 or 4
1107*e5436536SAndroid Build Coastguard Worker sign bits after the codeword-body */
1108*e5436536SAndroid Build Coastguard Worker /* PCW_Body and PCW_Sign */
1109*e5436536SAndroid Build Coastguard Worker /*=======================*/
1110*e5436536SAndroid Build Coastguard Worker
1111*e5436536SAndroid Build Coastguard Worker for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
1112*e5436536SAndroid Build Coastguard Worker [numExtendedSortedCodewordInSectionIdx];
1113*e5436536SAndroid Build Coastguard Worker curExtSortCwInSec != 0; curExtSortCwInSec--) {
1114*e5436536SAndroid Build Coastguard Worker int err;
1115*e5436536SAndroid Build Coastguard Worker numDecodedBits = 0;
1116*e5436536SAndroid Build Coastguard Worker
1117*e5436536SAndroid Build Coastguard Worker pQuantVal = DecodePCW_Body(
1118*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
1119*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1120*e5436536SAndroid Build Coastguard Worker
1121*e5436536SAndroid Build Coastguard Worker err = DecodePCW_Sign(
1122*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
1123*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
1124*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1125*e5436536SAndroid Build Coastguard Worker if (err != 0) {
1126*e5436536SAndroid Build Coastguard Worker return;
1127*e5436536SAndroid Build Coastguard Worker }
1128*e5436536SAndroid Build Coastguard Worker /* one more PCW should be decoded */
1129*e5436536SAndroid Build Coastguard Worker
1130*e5436536SAndroid Build Coastguard Worker if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) {
1131*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED;
1132*e5436536SAndroid Build Coastguard Worker }
1133*e5436536SAndroid Build Coastguard Worker
1134*e5436536SAndroid Build Coastguard Worker if (1 == errDetectPcwSegmentation(
1135*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr,
1136*e5436536SAndroid Build Coastguard Worker PCW_BODY_SIGN,
1137*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients +
1138*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx - dimension,
1139*e5436536SAndroid Build Coastguard Worker dimension)) {
1140*e5436536SAndroid Build Coastguard Worker return;
1141*e5436536SAndroid Build Coastguard Worker }
1142*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment++;
1143*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment++;
1144*e5436536SAndroid Build Coastguard Worker }
1145*e5436536SAndroid Build Coastguard Worker } else if ((pCbSign[codebook] == 1) &&
1146*e5436536SAndroid Build Coastguard Worker (codebook >= 11)) { /* possibly there follow some sign bits and
1147*e5436536SAndroid Build Coastguard Worker maybe one or two escape sequences after
1148*e5436536SAndroid Build Coastguard Worker the cw-body */
1149*e5436536SAndroid Build Coastguard Worker /* PCW_Body, PCW_Sign and maybe PCW_Escape */
1150*e5436536SAndroid Build Coastguard Worker /*=========================================*/
1151*e5436536SAndroid Build Coastguard Worker
1152*e5436536SAndroid Build Coastguard Worker for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
1153*e5436536SAndroid Build Coastguard Worker [numExtendedSortedCodewordInSectionIdx];
1154*e5436536SAndroid Build Coastguard Worker curExtSortCwInSec != 0; curExtSortCwInSec--) {
1155*e5436536SAndroid Build Coastguard Worker int err;
1156*e5436536SAndroid Build Coastguard Worker numDecodedBits = 0;
1157*e5436536SAndroid Build Coastguard Worker
1158*e5436536SAndroid Build Coastguard Worker /* decode PCW_BODY */
1159*e5436536SAndroid Build Coastguard Worker pQuantVal = DecodePCW_Body(
1160*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
1161*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1162*e5436536SAndroid Build Coastguard Worker
1163*e5436536SAndroid Build Coastguard Worker err = DecodePCW_Sign(
1164*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
1165*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
1166*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1167*e5436536SAndroid Build Coastguard Worker if (err != 0) {
1168*e5436536SAndroid Build Coastguard Worker return;
1169*e5436536SAndroid Build Coastguard Worker }
1170*e5436536SAndroid Build Coastguard Worker
1171*e5436536SAndroid Build Coastguard Worker /* decode PCW_ESCAPE if present */
1172*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx -= DIMENSION_OF_ESCAPE_CODEBOOK;
1173*e5436536SAndroid Build Coastguard Worker
1174*e5436536SAndroid Build Coastguard Worker if (fixp_abs(pQuantizedSpectralCoefficients
1175*e5436536SAndroid Build Coastguard Worker [quantizedSpectralCoefficientsIdx]) ==
1176*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)ESCAPE_VALUE) {
1177*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
1178*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)DecodeEscapeSequence(
1179*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor,
1180*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients
1181*e5436536SAndroid Build Coastguard Worker [quantizedSpectralCoefficientsIdx],
1182*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
1183*e5436536SAndroid Build Coastguard Worker &pHcr->decInOut.errorLog);
1184*e5436536SAndroid Build Coastguard Worker }
1185*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx++;
1186*e5436536SAndroid Build Coastguard Worker if (quantizedSpectralCoefficientsIdx >= 1024) {
1187*e5436536SAndroid Build Coastguard Worker return;
1188*e5436536SAndroid Build Coastguard Worker }
1189*e5436536SAndroid Build Coastguard Worker
1190*e5436536SAndroid Build Coastguard Worker if (fixp_abs(pQuantizedSpectralCoefficients
1191*e5436536SAndroid Build Coastguard Worker [quantizedSpectralCoefficientsIdx]) ==
1192*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)ESCAPE_VALUE) {
1193*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
1194*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)DecodeEscapeSequence(
1195*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor,
1196*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients
1197*e5436536SAndroid Build Coastguard Worker [quantizedSpectralCoefficientsIdx],
1198*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
1199*e5436536SAndroid Build Coastguard Worker &pHcr->decInOut.errorLog);
1200*e5436536SAndroid Build Coastguard Worker }
1201*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx++;
1202*e5436536SAndroid Build Coastguard Worker if (quantizedSpectralCoefficientsIdx >= 1024) {
1203*e5436536SAndroid Build Coastguard Worker return;
1204*e5436536SAndroid Build Coastguard Worker }
1205*e5436536SAndroid Build Coastguard Worker
1206*e5436536SAndroid Build Coastguard Worker /* one more PCW should be decoded */
1207*e5436536SAndroid Build Coastguard Worker
1208*e5436536SAndroid Build Coastguard Worker if (maxAllowedCwLen <
1209*e5436536SAndroid Build Coastguard Worker (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) {
1210*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
1211*e5436536SAndroid Build Coastguard Worker }
1212*e5436536SAndroid Build Coastguard Worker
1213*e5436536SAndroid Build Coastguard Worker if (1 == errDetectPcwSegmentation(
1214*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN_ESC, pHcr,
1215*e5436536SAndroid Build Coastguard Worker PCW_BODY_SIGN_ESC,
1216*e5436536SAndroid Build Coastguard Worker pQuantizedSpectralCoefficients +
1217*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx -
1218*e5436536SAndroid Build Coastguard Worker DIMENSION_OF_ESCAPE_CODEBOOK,
1219*e5436536SAndroid Build Coastguard Worker DIMENSION_OF_ESCAPE_CODEBOOK)) {
1220*e5436536SAndroid Build Coastguard Worker return;
1221*e5436536SAndroid Build Coastguard Worker }
1222*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment++;
1223*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment++;
1224*e5436536SAndroid Build Coastguard Worker }
1225*e5436536SAndroid Build Coastguard Worker }
1226*e5436536SAndroid Build Coastguard Worker
1227*e5436536SAndroid Build Coastguard Worker /* all PCWs belonging to this extended section should be decoded */
1228*e5436536SAndroid Build Coastguard Worker numExtendedSortedCodewordInSectionIdx++;
1229*e5436536SAndroid Build Coastguard Worker if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) {
1230*e5436536SAndroid Build Coastguard Worker return;
1231*e5436536SAndroid Build Coastguard Worker }
1232*e5436536SAndroid Build Coastguard Worker }
1233*e5436536SAndroid Build Coastguard Worker /* all PCWs should be decoded */
1234*e5436536SAndroid Build Coastguard Worker
1235*e5436536SAndroid Build Coastguard Worker numExtendedSortedSectionsInSetsIdx++;
1236*e5436536SAndroid Build Coastguard Worker if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
1237*e5436536SAndroid Build Coastguard Worker return;
1238*e5436536SAndroid Build Coastguard Worker }
1239*e5436536SAndroid Build Coastguard Worker
1240*e5436536SAndroid Build Coastguard Worker /* Write back indexes into structure */
1241*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
1242*e5436536SAndroid Build Coastguard Worker numExtendedSortedCodewordInSectionIdx;
1243*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
1244*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
1245*e5436536SAndroid Build Coastguard Worker numExtendedSortedSectionsInSetsIdx;
1246*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.quantizedSpectralCoefficientsIdx =
1247*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx;
1248*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx;
1249*e5436536SAndroid Build Coastguard Worker }
1250*e5436536SAndroid Build Coastguard Worker
1251*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1252*e5436536SAndroid Build Coastguard Worker description: This function checks immediately after every decoded PCW,
1253*e5436536SAndroid Build Coastguard Worker whether out of the current segment too many bits have been read or not. If an
1254*e5436536SAndroid Build Coastguard Worker error occurrs, probably the sideinfo or the HCR-bitstream block holding the
1255*e5436536SAndroid Build Coastguard Worker huffman encoded quantized spectral coefficients is distorted. In this case the
1256*e5436536SAndroid Build Coastguard Worker two or four quantized spectral coefficients belonging to the current codeword
1257*e5436536SAndroid Build Coastguard Worker are marked (for being detected by concealment later).
1258*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1259*e5436536SAndroid Build Coastguard Worker */
errDetectPcwSegmentation(SCHAR remainingBitsInSegment,H_HCR_INFO pHcr,PCW_TYPE kind,FIXP_DBL * qsc_base_of_cw,UCHAR dimension)1260*e5436536SAndroid Build Coastguard Worker static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
1261*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr, PCW_TYPE kind,
1262*e5436536SAndroid Build Coastguard Worker FIXP_DBL *qsc_base_of_cw,
1263*e5436536SAndroid Build Coastguard Worker UCHAR dimension) {
1264*e5436536SAndroid Build Coastguard Worker SCHAR i;
1265*e5436536SAndroid Build Coastguard Worker if (remainingBitsInSegment < 0) {
1266*e5436536SAndroid Build Coastguard Worker /* log the error */
1267*e5436536SAndroid Build Coastguard Worker switch (kind) {
1268*e5436536SAndroid Build Coastguard Worker case PCW_BODY:
1269*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY;
1270*e5436536SAndroid Build Coastguard Worker break;
1271*e5436536SAndroid Build Coastguard Worker case PCW_BODY_SIGN:
1272*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN;
1273*e5436536SAndroid Build Coastguard Worker break;
1274*e5436536SAndroid Build Coastguard Worker case PCW_BODY_SIGN_ESC:
1275*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC;
1276*e5436536SAndroid Build Coastguard Worker break;
1277*e5436536SAndroid Build Coastguard Worker }
1278*e5436536SAndroid Build Coastguard Worker /* mark the erred lines */
1279*e5436536SAndroid Build Coastguard Worker for (i = dimension; i != 0; i--) {
1280*e5436536SAndroid Build Coastguard Worker *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID;
1281*e5436536SAndroid Build Coastguard Worker }
1282*e5436536SAndroid Build Coastguard Worker return 1;
1283*e5436536SAndroid Build Coastguard Worker }
1284*e5436536SAndroid Build Coastguard Worker return 0;
1285*e5436536SAndroid Build Coastguard Worker }
1286*e5436536SAndroid Build Coastguard Worker
1287*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1288*e5436536SAndroid Build Coastguard Worker description: This function checks if all segments are empty after
1289*e5436536SAndroid Build Coastguard Worker decoding. There are _no lines markded_ as invalid because it could not be traced
1290*e5436536SAndroid Build Coastguard Worker back where from the remaining bits are.
1291*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1292*e5436536SAndroid Build Coastguard Worker */
errDetectWithinSegmentationFinal(H_HCR_INFO pHcr)1293*e5436536SAndroid Build Coastguard Worker static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) {
1294*e5436536SAndroid Build Coastguard Worker UCHAR segmentationErrorFlag = 0;
1295*e5436536SAndroid Build Coastguard Worker USHORT i;
1296*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1297*e5436536SAndroid Build Coastguard Worker UINT numSegment = pHcr->segmentInfo.numSegment;
1298*e5436536SAndroid Build Coastguard Worker
1299*e5436536SAndroid Build Coastguard Worker for (i = numSegment; i != 0; i--) {
1300*e5436536SAndroid Build Coastguard Worker if (*pRemainingBitsInSegment++ != 0) {
1301*e5436536SAndroid Build Coastguard Worker segmentationErrorFlag = 1;
1302*e5436536SAndroid Build Coastguard Worker }
1303*e5436536SAndroid Build Coastguard Worker }
1304*e5436536SAndroid Build Coastguard Worker if (segmentationErrorFlag == 1) {
1305*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR;
1306*e5436536SAndroid Build Coastguard Worker }
1307*e5436536SAndroid Build Coastguard Worker }
1308*e5436536SAndroid Build Coastguard Worker
1309*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1310*e5436536SAndroid Build Coastguard Worker description: This function walks one step within the decoding tree. Which
1311*e5436536SAndroid Build Coastguard Worker branch is taken depends on the decoded carryBit input parameter.
1312*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1313*e5436536SAndroid Build Coastguard Worker */
CarryBitToBranchValue(UCHAR carryBit,UINT treeNode,UINT * branchValue,UINT * branchNode)1314*e5436536SAndroid Build Coastguard Worker void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
1315*e5436536SAndroid Build Coastguard Worker UINT *branchNode) {
1316*e5436536SAndroid Build Coastguard Worker if (carryBit == 0) {
1317*e5436536SAndroid Build Coastguard Worker *branchNode =
1318*e5436536SAndroid Build Coastguard Worker (treeNode & MASK_LEFT) >> LEFT_OFFSET; /* MASK_LEFT: 00FFF000 */
1319*e5436536SAndroid Build Coastguard Worker } else {
1320*e5436536SAndroid Build Coastguard Worker *branchNode = treeNode & MASK_RIGHT; /* MASK_RIGHT: 00000FFF */
1321*e5436536SAndroid Build Coastguard Worker }
1322*e5436536SAndroid Build Coastguard Worker
1323*e5436536SAndroid Build Coastguard Worker *branchValue = *branchNode & CLR_BIT_10; /* clear bit 10 (if set) */
1324*e5436536SAndroid Build Coastguard Worker }
1325*e5436536SAndroid Build Coastguard Worker
1326*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1327*e5436536SAndroid Build Coastguard Worker description: Decodes the body of a priority codeword (PCW)
1328*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1329*e5436536SAndroid Build Coastguard Worker return: - return value is pointer to first of two or four quantized
1330*e5436536SAndroid Build Coastguard Worker spectral coefficients
1331*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1332*e5436536SAndroid Build Coastguard Worker */
DecodePCW_Body(HANDLE_FDK_BITSTREAM bs,const INT bsAnchor,const UINT * pCurrentTree,const SCHAR * pQuantValBase,INT * pLeftStartOfSegment,SCHAR * pRemainingBitsInSegment,int * pNumDecodedBits)1333*e5436536SAndroid Build Coastguard Worker static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
1334*e5436536SAndroid Build Coastguard Worker const UINT *pCurrentTree,
1335*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantValBase,
1336*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment,
1337*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
1338*e5436536SAndroid Build Coastguard Worker int *pNumDecodedBits) {
1339*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
1340*e5436536SAndroid Build Coastguard Worker UINT branchNode;
1341*e5436536SAndroid Build Coastguard Worker UINT treeNode;
1342*e5436536SAndroid Build Coastguard Worker UINT branchValue;
1343*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantVal;
1344*e5436536SAndroid Build Coastguard Worker
1345*e5436536SAndroid Build Coastguard Worker /* decode PCW_BODY */
1346*e5436536SAndroid Build Coastguard Worker treeNode = *pCurrentTree; /* get first node of current tree belonging to
1347*e5436536SAndroid Build Coastguard Worker current codebook */
1348*e5436536SAndroid Build Coastguard Worker
1349*e5436536SAndroid Build Coastguard Worker /* decode whole PCW-codeword-body */
1350*e5436536SAndroid Build Coastguard Worker while (1) {
1351*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1352*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, /* dummy */
1353*e5436536SAndroid Build Coastguard Worker FROM_LEFT_TO_RIGHT);
1354*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment -= 1;
1355*e5436536SAndroid Build Coastguard Worker *pNumDecodedBits += 1;
1356*e5436536SAndroid Build Coastguard Worker
1357*e5436536SAndroid Build Coastguard Worker CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
1358*e5436536SAndroid Build Coastguard Worker
1359*e5436536SAndroid Build Coastguard Worker if ((branchNode & TEST_BIT_10) ==
1360*e5436536SAndroid Build Coastguard Worker TEST_BIT_10) { /* test bit 10 ; if set --> codeword-body is complete */
1361*e5436536SAndroid Build Coastguard Worker break; /* end of branch in tree reached i.e. a whole PCW-Body is decoded
1362*e5436536SAndroid Build Coastguard Worker */
1363*e5436536SAndroid Build Coastguard Worker } else {
1364*e5436536SAndroid Build Coastguard Worker treeNode = *(
1365*e5436536SAndroid Build Coastguard Worker pCurrentTree +
1366*e5436536SAndroid Build Coastguard Worker branchValue); /* update treeNode for further step in decoding tree */
1367*e5436536SAndroid Build Coastguard Worker }
1368*e5436536SAndroid Build Coastguard Worker }
1369*e5436536SAndroid Build Coastguard Worker
1370*e5436536SAndroid Build Coastguard Worker pQuantVal =
1371*e5436536SAndroid Build Coastguard Worker pQuantValBase + branchValue; /* update pointer to valid first of 2 or 4
1372*e5436536SAndroid Build Coastguard Worker quantized values */
1373*e5436536SAndroid Build Coastguard Worker
1374*e5436536SAndroid Build Coastguard Worker return pQuantVal;
1375*e5436536SAndroid Build Coastguard Worker }
1376*e5436536SAndroid Build Coastguard Worker
1377*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1378*e5436536SAndroid Build Coastguard Worker description: This function decodes one escape sequence. In case of a
1379*e5436536SAndroid Build Coastguard Worker escape codebook and in case of the absolute value of the quantized spectral
1380*e5436536SAndroid Build Coastguard Worker value == 16, a escapeSequence is decoded in two steps:
1381*e5436536SAndroid Build Coastguard Worker 1. escape prefix
1382*e5436536SAndroid Build Coastguard Worker 2. escape word
1383*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1384*e5436536SAndroid Build Coastguard Worker */
1385*e5436536SAndroid Build Coastguard Worker
DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs,const INT bsAnchor,INT quantSpecCoef,INT * pLeftStartOfSegment,SCHAR * pRemainingBitsInSegment,int * pNumDecodedBits,UINT * errorWord)1386*e5436536SAndroid Build Coastguard Worker static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
1387*e5436536SAndroid Build Coastguard Worker INT quantSpecCoef, INT *pLeftStartOfSegment,
1388*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
1389*e5436536SAndroid Build Coastguard Worker int *pNumDecodedBits, UINT *errorWord) {
1390*e5436536SAndroid Build Coastguard Worker UINT i;
1391*e5436536SAndroid Build Coastguard Worker INT sign;
1392*e5436536SAndroid Build Coastguard Worker UINT escapeOnesCounter = 0;
1393*e5436536SAndroid Build Coastguard Worker UINT carryBit;
1394*e5436536SAndroid Build Coastguard Worker INT escape_word = 0;
1395*e5436536SAndroid Build Coastguard Worker
1396*e5436536SAndroid Build Coastguard Worker /* decode escape prefix */
1397*e5436536SAndroid Build Coastguard Worker while (1) {
1398*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1399*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, /* dummy */
1400*e5436536SAndroid Build Coastguard Worker FROM_LEFT_TO_RIGHT);
1401*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment -= 1;
1402*e5436536SAndroid Build Coastguard Worker *pNumDecodedBits += 1;
1403*e5436536SAndroid Build Coastguard Worker if (*pRemainingBitsInSegment < 0) {
1404*e5436536SAndroid Build Coastguard Worker return Q_VALUE_INVALID;
1405*e5436536SAndroid Build Coastguard Worker }
1406*e5436536SAndroid Build Coastguard Worker
1407*e5436536SAndroid Build Coastguard Worker if (carryBit != 0) {
1408*e5436536SAndroid Build Coastguard Worker escapeOnesCounter += 1;
1409*e5436536SAndroid Build Coastguard Worker } else {
1410*e5436536SAndroid Build Coastguard Worker escapeOnesCounter += 4;
1411*e5436536SAndroid Build Coastguard Worker break;
1412*e5436536SAndroid Build Coastguard Worker }
1413*e5436536SAndroid Build Coastguard Worker }
1414*e5436536SAndroid Build Coastguard Worker
1415*e5436536SAndroid Build Coastguard Worker /* decode escape word */
1416*e5436536SAndroid Build Coastguard Worker for (i = escapeOnesCounter; i != 0; i--) {
1417*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1418*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, /* dummy */
1419*e5436536SAndroid Build Coastguard Worker FROM_LEFT_TO_RIGHT);
1420*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment -= 1;
1421*e5436536SAndroid Build Coastguard Worker *pNumDecodedBits += 1;
1422*e5436536SAndroid Build Coastguard Worker if (*pRemainingBitsInSegment < 0) {
1423*e5436536SAndroid Build Coastguard Worker return Q_VALUE_INVALID;
1424*e5436536SAndroid Build Coastguard Worker }
1425*e5436536SAndroid Build Coastguard Worker
1426*e5436536SAndroid Build Coastguard Worker escape_word <<= 1;
1427*e5436536SAndroid Build Coastguard Worker escape_word = escape_word | carryBit;
1428*e5436536SAndroid Build Coastguard Worker }
1429*e5436536SAndroid Build Coastguard Worker
1430*e5436536SAndroid Build Coastguard Worker sign = (quantSpecCoef >= 0) ? 1 : -1;
1431*e5436536SAndroid Build Coastguard Worker
1432*e5436536SAndroid Build Coastguard Worker if (escapeOnesCounter < 13) {
1433*e5436536SAndroid Build Coastguard Worker quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
1434*e5436536SAndroid Build Coastguard Worker } else {
1435*e5436536SAndroid Build Coastguard Worker *errorWord |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
1436*e5436536SAndroid Build Coastguard Worker quantSpecCoef = Q_VALUE_INVALID;
1437*e5436536SAndroid Build Coastguard Worker }
1438*e5436536SAndroid Build Coastguard Worker return quantSpecCoef;
1439*e5436536SAndroid Build Coastguard Worker }
1440*e5436536SAndroid Build Coastguard Worker
1441*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1442*e5436536SAndroid Build Coastguard Worker description: Decodes the Signbits of a priority codeword (PCW) and writes
1443*e5436536SAndroid Build Coastguard Worker out the resulting quantized spectral values into unsorted sections
1444*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1445*e5436536SAndroid Build Coastguard Worker output: - two or four lines at position in corresponding section
1446*e5436536SAndroid Build Coastguard Worker (which are not located at the desired position, i.e. they must be reordered in
1447*e5436536SAndroid Build Coastguard Worker the last of eight function of HCR)
1448*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1449*e5436536SAndroid Build Coastguard Worker return: - updated pQuantSpecCoef pointer (to next empty storage for a
1450*e5436536SAndroid Build Coastguard Worker line)
1451*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1452*e5436536SAndroid Build Coastguard Worker */
DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs,const INT bsAnchor,UINT codebookDim,const SCHAR * pQuantVal,FIXP_DBL * pQuantSpecCoef,int * quantSpecCoefIdx,INT * pLeftStartOfSegment,SCHAR * pRemainingBitsInSegment,int * pNumDecodedBits)1453*e5436536SAndroid Build Coastguard Worker static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
1454*e5436536SAndroid Build Coastguard Worker UINT codebookDim, const SCHAR *pQuantVal,
1455*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
1456*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment,
1457*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
1458*e5436536SAndroid Build Coastguard Worker int *pNumDecodedBits) {
1459*e5436536SAndroid Build Coastguard Worker UINT i;
1460*e5436536SAndroid Build Coastguard Worker UINT carryBit;
1461*e5436536SAndroid Build Coastguard Worker INT quantSpecCoef;
1462*e5436536SAndroid Build Coastguard Worker
1463*e5436536SAndroid Build Coastguard Worker for (i = codebookDim; i != 0; i--) {
1464*e5436536SAndroid Build Coastguard Worker quantSpecCoef = *pQuantVal++;
1465*e5436536SAndroid Build Coastguard Worker if (quantSpecCoef != 0) {
1466*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1467*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment, /* dummy */
1468*e5436536SAndroid Build Coastguard Worker FROM_LEFT_TO_RIGHT);
1469*e5436536SAndroid Build Coastguard Worker *pRemainingBitsInSegment -= 1;
1470*e5436536SAndroid Build Coastguard Worker *pNumDecodedBits += 1;
1471*e5436536SAndroid Build Coastguard Worker if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024 >> 1)) {
1472*e5436536SAndroid Build Coastguard Worker return -1;
1473*e5436536SAndroid Build Coastguard Worker }
1474*e5436536SAndroid Build Coastguard Worker
1475*e5436536SAndroid Build Coastguard Worker /* adapt sign of values according to the decoded sign bit */
1476*e5436536SAndroid Build Coastguard Worker if (carryBit != 0) {
1477*e5436536SAndroid Build Coastguard Worker pQuantSpecCoef[*quantSpecCoefIdx] = -(FIXP_DBL)quantSpecCoef;
1478*e5436536SAndroid Build Coastguard Worker } else {
1479*e5436536SAndroid Build Coastguard Worker pQuantSpecCoef[*quantSpecCoefIdx] = (FIXP_DBL)quantSpecCoef;
1480*e5436536SAndroid Build Coastguard Worker }
1481*e5436536SAndroid Build Coastguard Worker } else {
1482*e5436536SAndroid Build Coastguard Worker pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f);
1483*e5436536SAndroid Build Coastguard Worker }
1484*e5436536SAndroid Build Coastguard Worker *quantSpecCoefIdx += 1;
1485*e5436536SAndroid Build Coastguard Worker if (*quantSpecCoefIdx >= 1024) {
1486*e5436536SAndroid Build Coastguard Worker return -1;
1487*e5436536SAndroid Build Coastguard Worker }
1488*e5436536SAndroid Build Coastguard Worker }
1489*e5436536SAndroid Build Coastguard Worker return 0;
1490*e5436536SAndroid Build Coastguard Worker }
1491*e5436536SAndroid Build Coastguard Worker
1492*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1493*e5436536SAndroid Build Coastguard Worker description: Mutes spectral lines which have been marked as erroneous
1494*e5436536SAndroid Build Coastguard Worker (Q_VALUE_INVALID)
1495*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1496*e5436536SAndroid Build Coastguard Worker */
HcrMuteErroneousLines(H_HCR_INFO hHcr)1497*e5436536SAndroid Build Coastguard Worker void HcrMuteErroneousLines(H_HCR_INFO hHcr) {
1498*e5436536SAndroid Build Coastguard Worker int c;
1499*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pLong =
1500*e5436536SAndroid Build Coastguard Worker SPEC_LONG(hHcr->decInOut.pQuantizedSpectralCoefficientsBase);
1501*e5436536SAndroid Build Coastguard Worker
1502*e5436536SAndroid Build Coastguard Worker /* if there is a line with value Q_VALUE_INVALID mute it */
1503*e5436536SAndroid Build Coastguard Worker for (c = 0; c < 1024; c++) {
1504*e5436536SAndroid Build Coastguard Worker if (pLong[c] == (FIXP_DBL)Q_VALUE_INVALID) {
1505*e5436536SAndroid Build Coastguard Worker pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */
1506*e5436536SAndroid Build Coastguard Worker }
1507*e5436536SAndroid Build Coastguard Worker }
1508*e5436536SAndroid Build Coastguard Worker }
1509