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