1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 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 /**************************** SBR decoder library ******************************
96
97 Author(s):
98
99 Description:
100
101 *******************************************************************************/
102
103 /*!
104 \file
105 \brief Sbr decoder
106 This module provides the actual decoder implementation. The SBR data (side
107 information) is already decoded. Only three functions are provided:
108
109 \li 1.) createSbrDec(): One time initialization
110 \li 2.) resetSbrDec(): Called by sbr_Apply() when the information contained in
111 an SBR_HEADER_ELEMENT requires a reset and recalculation of important SBR
112 structures. \li 3.) sbr_dec(): The actual decoder. Calls the different tools
113 such as filterbanks, lppTransposer(), and calculateSbrEnvelope() [the envelope
114 adjuster].
115
116 \sa sbr_dec(), \ref documentationOverview
117 */
118
119 #include "sbr_dec.h"
120
121 #include "sbr_ram.h"
122 #include "env_extr.h"
123 #include "env_calc.h"
124 #include "scale.h"
125 #include "FDK_matrixCalloc.h"
126 #include "hbe.h"
127
128 #include "genericStds.h"
129
130 #include "sbrdec_drc.h"
131
copyHarmonicSpectrum(int * xOverQmf,FIXP_DBL ** qmfReal,FIXP_DBL ** qmfImag,int noCols,int overlap,KEEP_STATES_SYNCED_MODE keepStatesSynced)132 static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal,
133 FIXP_DBL **qmfImag, int noCols, int overlap,
134 KEEP_STATES_SYNCED_MODE keepStatesSynced) {
135 int patchBands;
136 int patch, band, col, target, sourceBands, i;
137 int numPatches = 0;
138 int slotOffset = 0;
139
140 FIXP_DBL **ppqmfReal = qmfReal + overlap;
141 FIXP_DBL **ppqmfImag = qmfImag + overlap;
142
143 if (keepStatesSynced == KEEP_STATES_SYNCED_NORMAL) {
144 slotOffset = noCols - overlap - LPC_ORDER;
145 }
146
147 if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) {
148 ppqmfReal = qmfReal;
149 ppqmfImag = qmfImag;
150 }
151
152 for (i = 1; i < MAX_NUM_PATCHES; i++) {
153 if (xOverQmf[i] != 0) {
154 numPatches++;
155 }
156 }
157
158 for (patch = (MAX_STRETCH_HBE - 1); patch < numPatches; patch++) {
159 patchBands = xOverQmf[patch + 1] - xOverQmf[patch];
160 target = xOverQmf[patch];
161 sourceBands = xOverQmf[MAX_STRETCH_HBE - 1] - xOverQmf[MAX_STRETCH_HBE - 2];
162
163 while (patchBands > 0) {
164 int numBands = sourceBands;
165 int startBand = xOverQmf[MAX_STRETCH_HBE - 1] - 1;
166 if (target + numBands >= xOverQmf[patch + 1]) {
167 numBands = xOverQmf[patch + 1] - target;
168 }
169 if ((((target + numBands - 1) % 2) +
170 ((xOverQmf[MAX_STRETCH_HBE - 1] - 1) % 2)) %
171 2) {
172 if (numBands == sourceBands) {
173 numBands--;
174 } else {
175 startBand--;
176 }
177 }
178 if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) {
179 for (col = slotOffset; col < overlap + LPC_ORDER; col++) {
180 i = 0;
181 for (band = numBands; band > 0; band--) {
182 if ((target + band - 1 < 64) &&
183 (target + band - 1 < xOverQmf[patch + 1])) {
184 ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i];
185 ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i];
186 i++;
187 }
188 }
189 }
190 } else {
191 for (col = slotOffset; col < noCols; col++) {
192 i = 0;
193 for (band = numBands; band > 0; band--) {
194 if ((target + band - 1 < 64) &&
195 (target + band - 1 < xOverQmf[patch + 1])) {
196 ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i];
197 ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i];
198 i++;
199 }
200 }
201 }
202 }
203 target += numBands;
204 patchBands -= numBands;
205 }
206 }
207 }
208
209 /*!
210 \brief SBR decoder core function for one channel
211
212 \image html BufferMgmtDetailed-1632.png
213
214 Besides the filter states of the QMF filter bank and the LPC-states of
215 the LPP-Transposer, processing is mainly based on four buffers:
216 #timeIn, #timeOut, #WorkBuffer2 and #OverlapBuffer. The #WorkBuffer2
217 is reused for all channels and might be used by the core decoder, a
218 static overlap buffer is required for each channel. Due to in-place
219 processing, #timeIn and #timeOut point to identical locations.
220
221 The spectral data is organized in so-called slots. Each slot
222 contains 64 bands of complex data. The number of slots per frame
223 depends on the frame size. For mp3PRO, there are 18 slots per frame
224 and 6 slots per #OverlapBuffer. It is not necessary to have the slots
225 in located consecutive address ranges.
226
227 To optimize memory usage and to minimize the number of memory
228 accesses, the memory management is organized as follows (slot numbers
229 based on mp3PRO):
230
231 1.) Input time domain signal is located in #timeIn. The last slots
232 (0..5) of the spectral data of the previous frame are located in the
233 #OverlapBuffer. In addition, #frameData of the current frame resides
234 in the upper part of #timeIn.
235
236 2.) During the cplxAnalysisQmfFiltering(), 32 samples from #timeIn are
237 transformed into a slot of up to 32 complex spectral low band values at a
238 time. The first spectral slot -- nr. 6 -- is written at slot number
239 zero of #WorkBuffer2. #WorkBuffer2 will be completely filled with
240 spectral data.
241
242 3.) LPP-Transposition in lppTransposer() is processed on 24 slots. During the
243 transposition, the high band part of the spectral data is replicated
244 based on the low band data.
245
246 Envelope Adjustment is processed on the high band part of the spectral
247 data only by calculateSbrEnvelope().
248
249 4.) The cplxSynthesisQmfFiltering() creates 64 time domain samples out
250 of a slot of 64 complex spectral values at a time. The first 6 slots
251 in #timeOut are filled from the results of spectral slots 0..5 in the
252 #OverlapBuffer. The consecutive slots in timeOut are now filled with
253 the results of spectral slots 6..17.
254
255 5.) The preprocessed slots 18..23 have to be stored in the
256 #OverlapBuffer.
257
258 */
259
sbr_dec(HANDLE_SBR_DEC hSbrDec,INT_PCM * timeIn,INT_PCM * timeOut,HANDLE_SBR_DEC hSbrDecRight,INT_PCM * timeOutRight,const int strideOut,HANDLE_SBR_HEADER_DATA hHeaderData,HANDLE_SBR_FRAME_DATA hFrameData,HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData,const int applyProcessing,HANDLE_PS_DEC h_ps_d,const UINT flags,const int codecFrameSize)260 void sbr_dec(
261 HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
262 INT_PCM *timeIn, /*!< pointer to input time signal */
263 INT_PCM *timeOut, /*!< pointer to output time signal */
264 HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
265 INT_PCM *timeOutRight, /*!< pointer to output time signal */
266 const int strideOut, /*!< Time data traversal strideOut */
267 HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
268 HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
269 HANDLE_SBR_PREV_FRAME_DATA
270 hPrevFrameData, /*!< Some control data of last frame */
271 const int applyProcessing, /*!< Flag for SBR operation */
272 HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) {
273 int i, slot, reserve;
274 int saveLbScale;
275 int lastSlotOffs;
276 FIXP_DBL maxVal;
277
278 /* temporary pointer / variable for QMF;
279 required as we want to use temporary buffer
280 creating one frame delay for HBE in LP mode */
281 INT_PCM *pTimeInQmf = timeIn;
282
283 /* Number of QMF timeslots in the overlap buffer: */
284 int ov_len = hSbrDec->LppTrans.pSettings->overlap;
285
286 /* Number of QMF slots per frame */
287 int noCols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
288
289 /* create pointer array for data to use for HBE and legacy sbr */
290 FIXP_DBL *pLowBandReal[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)];
291 FIXP_DBL *pLowBandImag[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)];
292
293 /* set pReal to where QMF analysis writes in case of legacy SBR */
294 FIXP_DBL **pReal = pLowBandReal + ov_len;
295 FIXP_DBL **pImag = pLowBandImag + ov_len;
296
297 /* map QMF buffer to pointer array (Overlap + Frame)*/
298 for (i = 0; i < noCols + ov_len; i++) {
299 pLowBandReal[i] = hSbrDec->qmfDomainInCh->hQmfSlotsReal[i];
300 pLowBandImag[i] = hSbrDec->qmfDomainInCh->hQmfSlotsImag[i];
301 }
302
303 if ((flags & SBRDEC_USAC_HARMONICSBR)) {
304 /* in case of harmonic SBR and no HBE_LP map additional buffer for
305 one more frame to pointer arry */
306 for (i = 0; i < noCols; i++) {
307 pLowBandReal[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsReal[i];
308 pLowBandImag[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsImag[i];
309 }
310
311 /* shift scale values according to buffer */
312 hSbrDec->scale_ov = hSbrDec->scale_lb;
313 hSbrDec->scale_lb = hSbrDec->scale_hbe;
314
315 /* set pReal to where QMF analysis writes in case of HBE */
316 pReal += noCols;
317 pImag += noCols;
318 if (flags & SBRDEC_SKIP_QMF_ANA) {
319 /* stereoCfgIndex3 with HBE */
320 FDK_QmfDomain_QmfData2HBE(hSbrDec->qmfDomainInCh,
321 hSbrDec->hQmfHBESlotsReal,
322 hSbrDec->hQmfHBESlotsImag);
323 } else {
324 /* We have to move old hbe frame data to lb area of buffer */
325 for (i = 0; i < noCols; i++) {
326 FDKmemcpy(pLowBandReal[ov_len + i], hSbrDec->hQmfHBESlotsReal[i],
327 hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL));
328 FDKmemcpy(pLowBandImag[ov_len + i], hSbrDec->hQmfHBESlotsImag[i],
329 hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL));
330 }
331 }
332 }
333
334 /*
335 low band codec signal subband filtering
336 */
337
338 if (flags & SBRDEC_SKIP_QMF_ANA) {
339 if (!(flags & SBRDEC_USAC_HARMONICSBR)) /* stereoCfgIndex3 w/o HBE */
340 FDK_QmfDomain_WorkBuffer2ProcChannel(hSbrDec->qmfDomainInCh);
341 } else {
342 C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
343 qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
344 &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1,
345 qmfTemp);
346
347 C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
348 }
349
350 /*
351 Clear upper half of spectrum
352 */
353 if (!((flags & SBRDEC_USAC_HARMONICSBR) &&
354 (hFrameData->sbrPatchingMode == 0))) {
355 int nAnalysisBands = hHeaderData->numberOfAnalysisBands;
356
357 if (!(flags & SBRDEC_LOW_POWER)) {
358 for (slot = ov_len; slot < noCols + ov_len; slot++) {
359 FDKmemclear(&pLowBandReal[slot][nAnalysisBands],
360 ((64) - nAnalysisBands) * sizeof(FIXP_DBL));
361 FDKmemclear(&pLowBandImag[slot][nAnalysisBands],
362 ((64) - nAnalysisBands) * sizeof(FIXP_DBL));
363 }
364 } else {
365 for (slot = ov_len; slot < noCols + ov_len; slot++) {
366 FDKmemclear(&pLowBandReal[slot][nAnalysisBands],
367 ((64) - nAnalysisBands) * sizeof(FIXP_DBL));
368 }
369 }
370 }
371
372 /*
373 Shift spectral data left to gain accuracy in transposer and adjustor
374 */
375 /* Range was increased from lsb to no_channels because in some cases (e.g.
376 USAC conf eSbr_4_Pvc.mp4 and some HBE cases) it could be observed that the
377 signal between lsb and no_channels is used for the patching process.
378 */
379 maxVal = maxSubbandSample(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0,
380 hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols);
381
382 reserve = fixMax(0, CntLeadingZeros(maxVal) - 1);
383 reserve = fixMin(reserve,
384 DFRACT_BITS - 1 - hSbrDec->qmfDomainInCh->scaling.lb_scale);
385
386 /* If all data is zero, lb_scale could become too large */
387 rescaleSubbandSamples(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0,
388 hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols,
389 reserve);
390
391 hSbrDec->qmfDomainInCh->scaling.lb_scale += reserve;
392
393 if ((flags & SBRDEC_USAC_HARMONICSBR)) {
394 /* actually this is our hbe_scale */
395 hSbrDec->scale_hbe = hSbrDec->qmfDomainInCh->scaling.lb_scale;
396 /* the real lb_scale is stored in scale_lb from sbr */
397 hSbrDec->qmfDomainInCh->scaling.lb_scale = hSbrDec->scale_lb;
398 }
399 /*
400 save low band scale, wavecoding or parametric stereo may modify it
401 */
402 saveLbScale = hSbrDec->qmfDomainInCh->scaling.lb_scale;
403
404 if (applyProcessing) {
405 UCHAR *borders = hFrameData->frameInfo.borders;
406 lastSlotOffs = borders[hFrameData->frameInfo.nEnvelopes] -
407 hHeaderData->numberTimeSlots;
408
409 FIXP_DBL degreeAlias[(64)];
410 PVC_DYNAMIC_DATA pvcDynamicData;
411 pvcInitFrame(
412 &hSbrDec->PvcStaticData, &pvcDynamicData,
413 (hHeaderData->frameErrorFlag ? 0 : hHeaderData->bs_info.pvc_mode),
414 hFrameData->ns, hHeaderData->timeStep,
415 hHeaderData->freqBandData.lowSubband,
416 hFrameData->frameInfo.pvcBorders[0], hFrameData->pvcID);
417
418 if (!hHeaderData->frameErrorFlag && (hHeaderData->bs_info.pvc_mode > 0)) {
419 pvcDecodeFrame(&hSbrDec->PvcStaticData, &pvcDynamicData, pLowBandReal,
420 pLowBandImag, ov_len,
421 SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale),
422 SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale));
423 }
424 pvcEndFrame(&hSbrDec->PvcStaticData, &pvcDynamicData);
425
426 /* The transposer will override most values in degreeAlias[].
427 The array needs to be cleared at least from lowSubband to highSubband
428 before. */
429 if (flags & SBRDEC_LOW_POWER)
430 FDKmemclear(°reeAlias[hHeaderData->freqBandData.lowSubband],
431 (hHeaderData->freqBandData.highSubband -
432 hHeaderData->freqBandData.lowSubband) *
433 sizeof(FIXP_DBL));
434
435 /*
436 Inverse filtering of lowband and transposition into the SBR-frequency
437 range
438 */
439
440 {
441 KEEP_STATES_SYNCED_MODE keepStatesSyncedMode =
442 ((flags & SBRDEC_USAC_HARMONICSBR) &&
443 (hFrameData->sbrPatchingMode != 0))
444 ? KEEP_STATES_SYNCED_NORMAL
445 : KEEP_STATES_SYNCED_OFF;
446
447 if (flags & SBRDEC_USAC_HARMONICSBR) {
448 if (flags & SBRDEC_QUAD_RATE) {
449 pReal -= 32;
450 pImag -= 32;
451 }
452
453 if ((hSbrDec->savedStates == 0) && (hFrameData->sbrPatchingMode == 1)) {
454 /* copy saved states from previous frame to legacy SBR lpc filterstate
455 * buffer */
456 for (i = 0; i < LPC_ORDER + ov_len; i++) {
457 FDKmemcpy(
458 hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
459 hSbrDec->codecQMFBufferReal[noCols - LPC_ORDER - ov_len + i],
460 hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
461 FDKmemcpy(
462 hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i],
463 hSbrDec->codecQMFBufferImag[noCols - LPC_ORDER - ov_len + i],
464 hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
465 }
466 }
467
468 /* saving unmodified QMF states in case we are switching from legacy SBR
469 * to HBE */
470 for (i = 0; i < hSbrDec->hHBE->noCols; i++) {
471 FDKmemcpy(hSbrDec->codecQMFBufferReal[i], pLowBandReal[ov_len + i],
472 hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
473 FDKmemcpy(hSbrDec->codecQMFBufferImag[i], pLowBandImag[ov_len + i],
474 hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
475 }
476
477 QmfTransposerApply(
478 hSbrDec->hHBE, pReal, pImag, noCols, pLowBandReal, pLowBandImag,
479 hSbrDec->LppTrans.lpcFilterStatesRealHBE,
480 hSbrDec->LppTrans.lpcFilterStatesImagHBE,
481 hFrameData->sbrPitchInBins, hSbrDec->scale_lb, hSbrDec->scale_hbe,
482 &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep,
483 borders[0], ov_len, keepStatesSyncedMode);
484
485 if (flags & SBRDEC_QUAD_RATE) {
486 int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE);
487
488 copyHarmonicSpectrum(xOverQmf, pLowBandReal, pLowBandImag, noCols,
489 ov_len, keepStatesSyncedMode);
490 }
491 }
492 }
493
494 if ((flags & SBRDEC_USAC_HARMONICSBR) &&
495 (hFrameData->sbrPatchingMode == 0)) {
496 hSbrDec->prev_frame_lSbr = 0;
497 hSbrDec->prev_frame_hbeSbr = 1;
498
499 lppTransposerHBE(
500 &hSbrDec->LppTrans, hSbrDec->hHBE, &hSbrDec->qmfDomainInCh->scaling,
501 pLowBandReal, pLowBandImag, hHeaderData->timeStep, borders[0],
502 lastSlotOffs, hHeaderData->freqBandData.nInvfBands,
503 hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode);
504
505 } else {
506 if (flags & SBRDEC_USAC_HARMONICSBR) {
507 for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) {
508 /*
509 Store the unmodified qmf Slots values for upper part of spectrum
510 (required for LPC filtering) required if next frame is a HBE frame
511 */
512 FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealHBE[i],
513 hSbrDec->qmfDomainInCh
514 ->hQmfSlotsReal[hSbrDec->hHBE->noCols - LPC_ORDER + i],
515 (64) * sizeof(FIXP_DBL));
516 FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagHBE[i],
517 hSbrDec->qmfDomainInCh
518 ->hQmfSlotsImag[hSbrDec->hHBE->noCols - LPC_ORDER + i],
519 (64) * sizeof(FIXP_DBL));
520 }
521 }
522 {
523 hSbrDec->prev_frame_lSbr = 1;
524 hSbrDec->prev_frame_hbeSbr = 0;
525 }
526
527 lppTransposer(
528 &hSbrDec->LppTrans, &hSbrDec->qmfDomainInCh->scaling, pLowBandReal,
529 degreeAlias, // only used if useLP = 1
530 pLowBandImag, flags & SBRDEC_LOW_POWER,
531 hHeaderData->bs_info.sbr_preprocessing,
532 hHeaderData->freqBandData.v_k_master[0], hHeaderData->timeStep,
533 borders[0], lastSlotOffs, hHeaderData->freqBandData.nInvfBands,
534 hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode);
535 }
536
537 /*
538 Adjust envelope of current frame.
539 */
540
541 if ((hFrameData->sbrPatchingMode !=
542 hSbrDec->SbrCalculateEnvelope.sbrPatchingMode)) {
543 ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable,
544 &hHeaderData->freqBandData.noLimiterBands,
545 hHeaderData->freqBandData.freqBandTable[0],
546 hHeaderData->freqBandData.nSfb[0],
547 hSbrDec->LppTrans.pSettings->patchParam,
548 hSbrDec->LppTrans.pSettings->noOfPatches,
549 hHeaderData->bs_data.limiterBands,
550 hFrameData->sbrPatchingMode,
551 (flags & SBRDEC_USAC_HARMONICSBR) &&
552 (hFrameData->sbrPatchingMode == 0)
553 ? GetxOverBandQmfTransposer(hSbrDec->hHBE)
554 : NULL,
555 Get41SbrQmfTransposer(hSbrDec->hHBE));
556
557 hSbrDec->SbrCalculateEnvelope.sbrPatchingMode =
558 hFrameData->sbrPatchingMode;
559 }
560
561 calculateSbrEnvelope(
562 &hSbrDec->qmfDomainInCh->scaling, &hSbrDec->SbrCalculateEnvelope,
563 hHeaderData, hFrameData, &pvcDynamicData, pLowBandReal, pLowBandImag,
564 flags & SBRDEC_LOW_POWER,
565
566 degreeAlias, flags,
567 (hHeaderData->frameErrorFlag || hPrevFrameData->frameErrorFlag));
568
569 #if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
570 /* Avoid hard onsets of high band */
571 if (hHeaderData->frameErrorFlag) {
572 if (hSbrDec->highBandFadeCnt < SBRDEC_MAX_HB_FADE_FRAMES) {
573 hSbrDec->highBandFadeCnt += 1;
574 }
575 } else {
576 if (hSbrDec->highBandFadeCnt >
577 0) { /* Manipulate high band scale factor to get a smooth fade-in */
578 hSbrDec->qmfDomainInCh->scaling.hb_scale += hSbrDec->highBandFadeCnt;
579 hSbrDec->qmfDomainInCh->scaling.hb_scale =
580 fMin(hSbrDec->qmfDomainInCh->scaling.hb_scale, DFRACT_BITS - 1);
581 hSbrDec->highBandFadeCnt -= 1;
582 }
583 }
584
585 #endif
586 /*
587 Update hPrevFrameData (to be used in the next frame)
588 */
589 for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
590 hPrevFrameData->sbr_invf_mode[i] = hFrameData->sbr_invf_mode[i];
591 }
592 hPrevFrameData->coupling = hFrameData->coupling;
593 hPrevFrameData->stopPos = borders[hFrameData->frameInfo.nEnvelopes];
594 hPrevFrameData->ampRes = hFrameData->ampResolutionCurrentFrame;
595 hPrevFrameData->prevSbrPitchInBins = hFrameData->sbrPitchInBins;
596 /* could be done in extractFrameInfo_pvc() but hPrevFrameData is not
597 * available there */
598 FDKmemcpy(&hPrevFrameData->prevFrameInfo, &hFrameData->frameInfo,
599 sizeof(FRAME_INFO));
600 } else {
601 /* rescale from lsb to nAnalysisBands in order to compensate scaling with
602 * hb_scale in this area, done by synthesisFiltering*/
603 int rescale;
604 int lsb;
605 int length;
606
607 /* Reset hb_scale if no highband is present, because hb_scale is considered
608 * in the QMF-synthesis */
609 hSbrDec->qmfDomainInCh->scaling.hb_scale = saveLbScale;
610
611 rescale = hSbrDec->qmfDomainInCh->scaling.hb_scale -
612 hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
613 lsb = hSbrDec->qmfDomainOutCh->fb.lsb;
614 length = (hSbrDec->qmfDomainInCh->fb.no_channels - lsb);
615
616 if ((rescale < 0) && (length > 0)) {
617 if (!(flags & SBRDEC_LOW_POWER)) {
618 for (i = 0; i < ov_len; i++) {
619 scaleValues(&pLowBandReal[i][lsb], length, rescale);
620 scaleValues(&pLowBandImag[i][lsb], length, rescale);
621 }
622 } else {
623 for (i = 0; i < ov_len; i++) {
624 scaleValues(&pLowBandReal[i][lsb], length, rescale);
625 }
626 }
627 }
628 }
629
630 if (!(flags & SBRDEC_USAC_HARMONICSBR)) {
631 int length = hSbrDec->qmfDomainInCh->fb.lsb;
632 if (flags & SBRDEC_SYNTAX_USAC) {
633 length = hSbrDec->qmfDomainInCh->fb.no_channels;
634 }
635
636 /* in case of legacy sbr saving of filter states here */
637 for (i = 0; i < LPC_ORDER + ov_len; i++) {
638 /*
639 Store the unmodified qmf Slots values (required for LPC filtering)
640 */
641 if (!(flags & SBRDEC_LOW_POWER)) {
642 FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
643 pLowBandReal[noCols - LPC_ORDER + i],
644 length * sizeof(FIXP_DBL));
645 FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i],
646 pLowBandImag[noCols - LPC_ORDER + i],
647 length * sizeof(FIXP_DBL));
648 } else
649 FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
650 pLowBandReal[noCols - LPC_ORDER + i],
651 length * sizeof(FIXP_DBL));
652 }
653 }
654
655 /*
656 Synthesis subband filtering.
657 */
658
659 if (!(flags & SBRDEC_PS_DECODED)) {
660 if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
661 int outScalefactor = 0;
662
663 if (h_ps_d != NULL) {
664 h_ps_d->procFrameBased = 1; /* we here do frame based processing */
665 }
666
667 sbrDecoder_drcApply(&hSbrDec->sbrDrcChannel, pLowBandReal,
668 (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag,
669 hSbrDec->qmfDomainOutCh->fb.no_col, &outScalefactor);
670
671 qmfChangeOutScalefactor(&hSbrDec->qmfDomainOutCh->fb, outScalefactor);
672
673 {
674 HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
675 int save_usb = hSbrDec->qmfDomainOutCh->fb.usb;
676
677 #if (QMF_MAX_SYNTHESIS_BANDS <= 64)
678 C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
679 #else
680 C_AALLOC_STACK_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
681 #endif
682 if (hSbrDec->qmfDomainOutCh->fb.usb < hFreq->ov_highSubband) {
683 /* we need to patch usb for this frame as overlap may contain higher
684 frequency range if headerchange occured; fb. usb is always limited
685 to maximum fb.no_channels; In case of wrongly decoded headers it
686 might be that ov_highSubband is higher than the number of synthesis
687 channels (fb.no_channels), which is forbidden, therefore we need to
688 limit ov_highSubband with fMin function to avoid not allowed usb in
689 synthesis filterbank. */
690 hSbrDec->qmfDomainOutCh->fb.usb =
691 fMin((UINT)hFreq->ov_highSubband,
692 (UINT)hSbrDec->qmfDomainOutCh->fb.no_channels);
693 }
694 {
695 qmfSynthesisFiltering(
696 &hSbrDec->qmfDomainOutCh->fb, pLowBandReal,
697 (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag,
698 &hSbrDec->qmfDomainInCh->scaling,
699 hSbrDec->LppTrans.pSettings->overlap, timeOut, strideOut,
700 qmfTemp);
701 }
702 /* restore saved value */
703 hSbrDec->qmfDomainOutCh->fb.usb = save_usb;
704 hFreq->ov_highSubband = save_usb;
705 #if (QMF_MAX_SYNTHESIS_BANDS <= 64)
706 C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
707 #else
708 C_AALLOC_STACK_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
709 #endif
710 }
711 }
712
713 } else { /* (flags & SBRDEC_PS_DECODED) */
714 INT sdiff;
715 INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov;
716
717 HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb;
718 HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb;
719
720 /* adapt scaling */
721 sdiff = hSbrDec->qmfDomainInCh->scaling.lb_scale -
722 reserve; /* Scaling difference */
723 scaleFactorHighBand = sdiff - hSbrDec->qmfDomainInCh->scaling.hb_scale;
724 scaleFactorLowBand_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
725 scaleFactorLowBand_no_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.lb_scale;
726
727 /* Scale of low band overlapping QMF data */
728 scaleFactorLowBand_ov =
729 fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_ov));
730 /* Scale of low band current QMF data */
731 scaleFactorLowBand_no_ov = fMin(
732 DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_no_ov));
733 /* Scale of current high band */
734 scaleFactorHighBand =
735 fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorHighBand));
736
737 if (h_ps_d->procFrameBased == 1) /* If we have switched from frame to slot
738 based processing copy filter states */
739 { /* procFrameBased will be unset later */
740 /* copy filter states from left to right */
741 /* was ((640)-(64))*sizeof(FIXP_QSS)
742 flexible amount of synthesis bands needed for QMF based resampling
743 */
744 FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
745 QMF_MAX_SYNTHESIS_BANDS);
746 FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
747 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
748 sizeof(FIXP_QSS));
749 }
750
751 /* Feed delaylines when parametric stereo is switched on. */
752 PreparePsProcessing(h_ps_d, pLowBandReal, pLowBandImag,
753 scaleFactorLowBand_ov);
754
755 /* use the same synthese qmf values for left and right channel */
756 synQmfRight->no_col = synQmf->no_col;
757 synQmfRight->lsb = synQmf->lsb;
758 synQmfRight->usb = synQmf->usb;
759
760 int env = 0;
761
762 {
763 #if (QMF_MAX_SYNTHESIS_BANDS <= 64)
764 C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL,
765 2 * QMF_MAX_SYNTHESIS_BANDS);
766 #else
767 C_AALLOC_STACK_START(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
768 #endif
769
770 int maxShift = 0;
771
772 if (hSbrDec->sbrDrcChannel.enable != 0) {
773 if (hSbrDec->sbrDrcChannel.prevFact_exp > maxShift) {
774 maxShift = hSbrDec->sbrDrcChannel.prevFact_exp;
775 }
776 if (hSbrDec->sbrDrcChannel.currFact_exp > maxShift) {
777 maxShift = hSbrDec->sbrDrcChannel.currFact_exp;
778 }
779 if (hSbrDec->sbrDrcChannel.nextFact_exp > maxShift) {
780 maxShift = hSbrDec->sbrDrcChannel.nextFact_exp;
781 }
782 }
783
784 /* copy DRC data to right channel (with PS both channels use the same DRC
785 * gains) */
786 FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel,
787 sizeof(SBRDEC_DRC_CHANNEL));
788
789 for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */
790
791 INT outScalefactorR, outScalefactorL;
792
793 /* qmf timeslot of right channel */
794 FIXP_DBL *rQmfReal = pWorkBuffer;
795 FIXP_DBL *rQmfImag = pWorkBuffer + synQmf->no_channels;
796
797 {
798 if (i ==
799 h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]) {
800 initSlotBasedRotation(h_ps_d, env,
801 hHeaderData->freqBandData.highSubband);
802 env++;
803 }
804
805 ApplyPsSlot(
806 h_ps_d, /* parametric stereo decoder handle */
807 (pLowBandReal + i), /* one timeslot of left/mono channel */
808 (pLowBandImag + i), /* one timeslot of left/mono channel */
809 rQmfReal, /* one timeslot or right channel */
810 rQmfImag, /* one timeslot or right channel */
811 scaleFactorLowBand_no_ov,
812 (i < hSbrDec->LppTrans.pSettings->overlap)
813 ? scaleFactorLowBand_ov
814 : scaleFactorLowBand_no_ov,
815 scaleFactorHighBand, synQmf->lsb, synQmf->usb);
816
817 outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */
818 }
819
820 sbrDecoder_drcApplySlot(/* right channel */
821 &hSbrDecRight->sbrDrcChannel, rQmfReal,
822 rQmfImag, i, synQmfRight->no_col, maxShift);
823
824 outScalefactorR += maxShift;
825
826 sbrDecoder_drcApplySlot(/* left channel */
827 &hSbrDec->sbrDrcChannel, *(pLowBandReal + i),
828 *(pLowBandImag + i), i, synQmf->no_col,
829 maxShift);
830
831 outScalefactorL += maxShift;
832
833 if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
834 qmfSynthesisFilteringSlot(
835 synQmfRight, rQmfReal, /* QMF real buffer */
836 rQmfImag, /* QMF imag buffer */
837 outScalefactorL, outScalefactorL,
838 timeOutRight + (i * synQmf->no_channels * strideOut), strideOut,
839 pWorkBuffer);
840
841 qmfSynthesisFilteringSlot(
842 synQmf, *(pLowBandReal + i), /* QMF real buffer */
843 *(pLowBandImag + i), /* QMF imag buffer */
844 outScalefactorR, outScalefactorR,
845 timeOut + (i * synQmf->no_channels * strideOut), strideOut,
846 pWorkBuffer);
847 }
848 } /* no_col loop i */
849 #if (QMF_MAX_SYNTHESIS_BANDS <= 64)
850 C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
851 #else
852 C_AALLOC_STACK_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
853 #endif
854 }
855 }
856
857 sbrDecoder_drcUpdateChannel(&hSbrDec->sbrDrcChannel);
858
859 /*
860 Update overlap buffer
861 Even bands above usb are copied to avoid outdated spectral data in case
862 the stop frequency raises.
863 */
864
865 if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
866 {
867 FDK_QmfDomain_SaveOverlap(hSbrDec->qmfDomainInCh, 0);
868 FDK_ASSERT(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale == saveLbScale);
869 }
870 }
871
872 hSbrDec->savedStates = 0;
873
874 /* Save current frame status */
875 hPrevFrameData->frameErrorFlag = hHeaderData->frameErrorFlag;
876 hSbrDec->applySbrProc_old = applyProcessing;
877
878 } /* sbr_dec() */
879
880 /*!
881 \brief Creates sbr decoder structure
882 \return errorCode, 0 if successful
883 */
884 SBR_ERROR
createSbrDec(SBR_CHANNEL * hSbrChannel,HANDLE_SBR_HEADER_DATA hHeaderData,TRANSPOSER_SETTINGS * pSettings,const int downsampleFac,const UINT qmfFlags,const UINT flags,const int overlap,int chan,int codecFrameSize)885 createSbrDec(SBR_CHANNEL *hSbrChannel,
886 HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
887 TRANSPOSER_SETTINGS *pSettings,
888 const int downsampleFac, /*!< Downsampling factor */
889 const UINT qmfFlags, /*!< flags -> 1: HQ/LP selector, 2: CLDFB */
890 const UINT flags, const int overlap,
891 int chan, /*!< Channel for which to assign buffers etc. */
892 int codecFrameSize)
893
894 {
895 SBR_ERROR err = SBRDEC_OK;
896 int timeSlots =
897 hHeaderData->numberTimeSlots; /* Number of SBR slots per frame */
898 int noCols =
899 timeSlots * hHeaderData->timeStep; /* Number of QMF slots per frame */
900 HANDLE_SBR_DEC hs = &(hSbrChannel->SbrDec);
901
902 #if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
903 hs->highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES;
904
905 #endif
906 hs->scale_hbe = 15;
907 hs->scale_lb = 15;
908 hs->scale_ov = 15;
909
910 hs->prev_frame_lSbr = 0;
911 hs->prev_frame_hbeSbr = 0;
912
913 hs->codecFrameSize = codecFrameSize;
914
915 /*
916 create envelope calculator
917 */
918 err = createSbrEnvelopeCalc(&hs->SbrCalculateEnvelope, hHeaderData, chan,
919 flags);
920 if (err != SBRDEC_OK) {
921 return err;
922 }
923
924 initSbrPrevFrameData(&hSbrChannel->prevFrameData, timeSlots);
925
926 /*
927 create transposer
928 */
929 err = createLppTransposer(
930 &hs->LppTrans, pSettings, hHeaderData->freqBandData.lowSubband,
931 hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster,
932 hHeaderData->freqBandData.highSubband, timeSlots, noCols,
933 hHeaderData->freqBandData.freqBandTableNoise,
934 hHeaderData->freqBandData.nNfb, hHeaderData->sbrProcSmplRate, chan,
935 overlap);
936 if (err != SBRDEC_OK) {
937 return err;
938 }
939
940 if (flags & SBRDEC_USAC_HARMONICSBR) {
941 int noChannels, bSbr41 = flags & SBRDEC_QUAD_RATE ? 1 : 0;
942
943 noChannels =
944 QMF_SYNTH_CHANNELS /
945 ((bSbr41 + 1) * 2); /* 32 for (32:64 and 24:64) and 16 for 16:64 */
946
947 /* shared memory between hbeLightTimeDelayBuffer and hQmfHBESlotsReal if
948 * SBRDEC_HBE_ENABLE */
949 hSbrChannel->SbrDec.tmp_memory = (FIXP_DBL **)fdkCallocMatrix2D_aligned(
950 noCols, noChannels, sizeof(FIXP_DBL));
951 if (hSbrChannel->SbrDec.tmp_memory == NULL) {
952 return SBRDEC_MEM_ALLOC_FAILED;
953 }
954
955 hSbrChannel->SbrDec.hQmfHBESlotsReal = hSbrChannel->SbrDec.tmp_memory;
956 hSbrChannel->SbrDec.hQmfHBESlotsImag =
957 (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels,
958 sizeof(FIXP_DBL));
959 if (hSbrChannel->SbrDec.hQmfHBESlotsImag == NULL) {
960 return SBRDEC_MEM_ALLOC_FAILED;
961 }
962
963 /* buffers containing unmodified qmf data; required when switching from
964 * legacy SBR to HBE */
965 /* buffer can be used as LPCFilterstates buffer because legacy SBR needs
966 * exactly these values for LPC filtering */
967 hSbrChannel->SbrDec.codecQMFBufferReal =
968 (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels,
969 sizeof(FIXP_DBL));
970 if (hSbrChannel->SbrDec.codecQMFBufferReal == NULL) {
971 return SBRDEC_MEM_ALLOC_FAILED;
972 }
973
974 hSbrChannel->SbrDec.codecQMFBufferImag =
975 (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels,
976 sizeof(FIXP_DBL));
977 if (hSbrChannel->SbrDec.codecQMFBufferImag == NULL) {
978 return SBRDEC_MEM_ALLOC_FAILED;
979 }
980
981 err = QmfTransposerCreate(&hs->hHBE, codecFrameSize, 0, bSbr41);
982 if (err != SBRDEC_OK) {
983 return err;
984 }
985 }
986
987 return err;
988 }
989
990 /*!
991 \brief Delete sbr decoder structure
992 \return errorCode, 0 if successful
993 */
deleteSbrDec(SBR_CHANNEL * hSbrChannel)994 int deleteSbrDec(SBR_CHANNEL *hSbrChannel) {
995 HANDLE_SBR_DEC hs = &hSbrChannel->SbrDec;
996
997 deleteSbrEnvelopeCalc(&hs->SbrCalculateEnvelope);
998
999 if (hs->tmp_memory != NULL) {
1000 FDK_FREE_MEMORY_2D_ALIGNED(hs->tmp_memory);
1001 }
1002
1003 /* modify here */
1004 FDK_FREE_MEMORY_2D_ALIGNED(hs->hQmfHBESlotsImag);
1005
1006 if (hs->hHBE != NULL) QmfTransposerClose(hs->hHBE);
1007
1008 if (hs->codecQMFBufferReal != NULL) {
1009 FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferReal);
1010 }
1011
1012 if (hs->codecQMFBufferImag != NULL) {
1013 FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferImag);
1014 }
1015
1016 return 0;
1017 }
1018
1019 /*!
1020 \brief resets sbr decoder structure
1021 \return errorCode, 0 if successful
1022 */
1023 SBR_ERROR
resetSbrDec(HANDLE_SBR_DEC hSbrDec,HANDLE_SBR_HEADER_DATA hHeaderData,HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData,const int downsampleFac,const UINT flags,HANDLE_SBR_FRAME_DATA hFrameData)1024 resetSbrDec(HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData,
1025 HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int downsampleFac,
1026 const UINT flags, HANDLE_SBR_FRAME_DATA hFrameData) {
1027 SBR_ERROR sbrError = SBRDEC_OK;
1028 int i;
1029 FIXP_DBL *pLowBandReal[128];
1030 FIXP_DBL *pLowBandImag[128];
1031 int useLP = flags & SBRDEC_LOW_POWER;
1032
1033 int old_lsb = hSbrDec->qmfDomainInCh->fb.lsb;
1034 int old_usb = hSbrDec->qmfDomainInCh->fb.usb;
1035 int new_lsb = hHeaderData->freqBandData.lowSubband;
1036 /* int new_usb = hHeaderData->freqBandData.highSubband; */
1037 int l, startBand, stopBand, startSlot, size;
1038
1039 FIXP_DBL **OverlapBufferReal = hSbrDec->qmfDomainInCh->hQmfSlotsReal;
1040 FIXP_DBL **OverlapBufferImag = hSbrDec->qmfDomainInCh->hQmfSlotsImag;
1041
1042 /* in case the previous frame was not active in terms of SBR processing, the
1043 full band from 0 to no_channels was rescaled and not overwritten. Thats why
1044 the scaling factor lb_scale can be seen as assigned to all bands from 0 to
1045 no_channels in the previous frame. The same states for the current frame if
1046 the current frame is not active in terms of SBR processing
1047 */
1048 int applySbrProc = (hHeaderData->syncState == SBR_ACTIVE ||
1049 (hHeaderData->frameErrorFlag == 0 &&
1050 hHeaderData->syncState == SBR_HEADER));
1051 int applySbrProc_old = hSbrDec->applySbrProc_old;
1052
1053 if (!applySbrProc) {
1054 new_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels;
1055 }
1056 if (!applySbrProc_old) {
1057 old_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels;
1058 old_usb = old_lsb;
1059 }
1060
1061 resetSbrEnvelopeCalc(&hSbrDec->SbrCalculateEnvelope);
1062
1063 /* Change lsb and usb */
1064 /* Synthesis */
1065 FDK_ASSERT(hSbrDec->qmfDomainOutCh != NULL);
1066 hSbrDec->qmfDomainOutCh->fb.lsb =
1067 fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels,
1068 (INT)hHeaderData->freqBandData.lowSubband);
1069 hSbrDec->qmfDomainOutCh->fb.usb =
1070 fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels,
1071 (INT)hHeaderData->freqBandData.highSubband);
1072 /* Analysis */
1073 FDK_ASSERT(hSbrDec->qmfDomainInCh != NULL);
1074 hSbrDec->qmfDomainInCh->fb.lsb = hSbrDec->qmfDomainOutCh->fb.lsb;
1075 hSbrDec->qmfDomainInCh->fb.usb = hSbrDec->qmfDomainOutCh->fb.usb;
1076
1077 /*
1078 The following initialization of spectral data in the overlap buffer
1079 is required for dynamic x-over or a change of the start-freq for 2 reasons:
1080
1081 1. If the lowband gets _wider_, unadjusted data would remain
1082
1083 2. If the lowband becomes _smaller_, the highest bands of the old lowband
1084 must be cleared because the whitening would be affected
1085 */
1086 startBand = old_lsb;
1087 stopBand = new_lsb;
1088 startSlot = fMax(0, hHeaderData->timeStep * (hPrevFrameData->stopPos -
1089 hHeaderData->numberTimeSlots));
1090 size = fMax(0, stopBand - startBand);
1091
1092 /* in case of USAC we don't want to zero out the memory, as this can lead to
1093 holes in the spectrum; fix shall only be applied for USAC not for MPEG-4
1094 SBR, in this case setting zero remains */
1095 if (!(flags & SBRDEC_SYNTAX_USAC)) {
1096 /* keep already adjusted data in the x-over-area */
1097 if (!useLP) {
1098 for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) {
1099 FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL));
1100 FDKmemclear(&OverlapBufferImag[l][startBand], size * sizeof(FIXP_DBL));
1101 }
1102 } else {
1103 for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) {
1104 FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL));
1105 }
1106 }
1107
1108 /*
1109 reset LPC filter states
1110 */
1111 startBand = fixMin(old_lsb, new_lsb);
1112 stopBand = fixMax(old_lsb, new_lsb);
1113 size = fixMax(0, stopBand - startBand);
1114
1115 FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[0][startBand],
1116 size * sizeof(FIXP_DBL));
1117 FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[1][startBand],
1118 size * sizeof(FIXP_DBL));
1119 if (!useLP) {
1120 FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[0][startBand],
1121 size * sizeof(FIXP_DBL));
1122 FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[1][startBand],
1123 size * sizeof(FIXP_DBL));
1124 }
1125 }
1126
1127 if (startSlot != 0) {
1128 int source_exp, target_exp, delta_exp, target_lsb, target_usb, reserve;
1129 FIXP_DBL maxVal;
1130
1131 /*
1132 Rescale already processed spectral data between old and new x-over
1133 frequency. This must be done because of the separate scalefactors for
1134 lowband and highband.
1135 */
1136
1137 /* We have four relevant transitions to cover:
1138 1. old_usb is lower than new_lsb; old SBR area is completely below new SBR
1139 area.
1140 -> entire old area was highband and belongs to lowband now
1141 and has to be rescaled.
1142 2. old_lsb is higher than new_usb; new SBR area is completely below old SBR
1143 area.
1144 -> old area between new_lsb and old_lsb was lowband and belongs to
1145 highband now and has to be rescaled to match new highband scale.
1146 3. old_lsb is lower and old_usb is higher than new_lsb; old and new SBR
1147 areas overlap.
1148 -> old area between old_lsb and new_lsb was highband and belongs to
1149 lowband now and has to be rescaled to match new lowband scale.
1150 4. new_lsb is lower and new_usb_is higher than old_lsb; old and new SBR
1151 areas overlap.
1152 -> old area between new_lsb and old_usb was lowband and belongs to
1153 highband now and has to be rescaled to match new highband scale.
1154 */
1155
1156 if (new_lsb > old_lsb) {
1157 /* case 1 and 3 */
1158 source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale);
1159 target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale);
1160
1161 startBand = old_lsb;
1162
1163 if (new_lsb >= old_usb) {
1164 /* case 1 */
1165 stopBand = old_usb;
1166 } else {
1167 /* case 3 */
1168 stopBand = new_lsb;
1169 }
1170
1171 target_lsb = 0;
1172 target_usb = old_lsb;
1173 } else {
1174 /* case 2 and 4 */
1175 source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale);
1176 target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale);
1177
1178 startBand = new_lsb;
1179 stopBand = old_lsb;
1180
1181 target_lsb = old_lsb;
1182 target_usb = old_usb;
1183 }
1184
1185 maxVal =
1186 maxSubbandSample(OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag,
1187 startBand, stopBand, 0, startSlot);
1188
1189 reserve = ((LONG)maxVal != 0 ? CntLeadingZeros(maxVal) - 1 : 0);
1190 reserve = fixMin(
1191 reserve,
1192 DFRACT_BITS - 1 -
1193 EXP2SCALE(
1194 source_exp)); /* what is this line for, why do we need it? */
1195
1196 /* process only if x-over-area is not dominant after rescale;
1197 otherwise I'm not sure if all buffers are scaled correctly;
1198 */
1199 if (target_exp - (source_exp - reserve) >= 0) {
1200 rescaleSubbandSamples(OverlapBufferReal,
1201 (useLP) ? NULL : OverlapBufferImag, startBand,
1202 stopBand, 0, startSlot, reserve);
1203 source_exp -= reserve;
1204 }
1205
1206 delta_exp = target_exp - source_exp;
1207
1208 if (delta_exp < 0) { /* x-over-area is dominant */
1209 startBand = target_lsb;
1210 stopBand = target_usb;
1211 delta_exp = -delta_exp;
1212
1213 if (new_lsb > old_lsb) {
1214 /* The lowband has to be rescaled */
1215 hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = EXP2SCALE(source_exp);
1216 } else {
1217 /* The highband has to be rescaled */
1218 hSbrDec->qmfDomainInCh->scaling.ov_hb_scale = EXP2SCALE(source_exp);
1219 }
1220 }
1221
1222 FDK_ASSERT(startBand <= stopBand);
1223
1224 if (!useLP) {
1225 for (l = 0; l < startSlot; l++) {
1226 scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand,
1227 -delta_exp);
1228 scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand,
1229 -delta_exp);
1230 }
1231 } else
1232 for (l = 0; l < startSlot; l++) {
1233 scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand,
1234 -delta_exp);
1235 }
1236 } /* startSlot != 0 */
1237
1238 /*
1239 Initialize transposer and limiter
1240 */
1241 sbrError = resetLppTransposer(
1242 &hSbrDec->LppTrans, hHeaderData->freqBandData.lowSubband,
1243 hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster,
1244 hHeaderData->freqBandData.freqBandTableNoise,
1245 hHeaderData->freqBandData.nNfb, hHeaderData->freqBandData.highSubband,
1246 hHeaderData->sbrProcSmplRate);
1247 if (sbrError != SBRDEC_OK) return sbrError;
1248
1249 hSbrDec->savedStates = 0;
1250
1251 if ((flags & SBRDEC_USAC_HARMONICSBR) && applySbrProc) {
1252 sbrError = QmfTransposerReInit(hSbrDec->hHBE,
1253 hHeaderData->freqBandData.freqBandTable,
1254 hHeaderData->freqBandData.nSfb);
1255 if (sbrError != SBRDEC_OK) return sbrError;
1256
1257 /* copy saved states from previous frame to legacy SBR lpc filterstate
1258 * buffer */
1259 for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) {
1260 FDKmemcpy(
1261 hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
1262 hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols - LPC_ORDER -
1263 hSbrDec->LppTrans.pSettings->overlap + i],
1264 hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
1265 FDKmemcpy(
1266 hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i],
1267 hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols - LPC_ORDER -
1268 hSbrDec->LppTrans.pSettings->overlap + i],
1269 hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
1270 }
1271 hSbrDec->savedStates = 1;
1272
1273 {
1274 /* map QMF buffer to pointer array (Overlap + Frame)*/
1275 for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) {
1276 pLowBandReal[i] = hSbrDec->LppTrans.lpcFilterStatesRealHBE[i];
1277 pLowBandImag[i] = hSbrDec->LppTrans.lpcFilterStatesImagHBE[i];
1278 }
1279
1280 /* map QMF buffer to pointer array (Overlap + Frame)*/
1281 for (i = 0; i < hSbrDec->hHBE->noCols; i++) {
1282 pLowBandReal[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
1283 hSbrDec->codecQMFBufferReal[i];
1284 pLowBandImag[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
1285 hSbrDec->codecQMFBufferImag[i];
1286 }
1287
1288 if (flags & SBRDEC_QUAD_RATE) {
1289 if (hFrameData->sbrPatchingMode == 0) {
1290 int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE);
1291
1292 /* in case of harmonic SBR and no HBE_LP map additional buffer for
1293 one more frame to pointer arry */
1294 for (i = 0; i < hSbrDec->hHBE->noCols / 2; i++) {
1295 pLowBandReal[i + hSbrDec->hHBE->noCols +
1296 hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
1297 hSbrDec->hQmfHBESlotsReal[i];
1298 pLowBandImag[i + hSbrDec->hHBE->noCols +
1299 hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
1300 hSbrDec->hQmfHBESlotsImag[i];
1301 }
1302
1303 QmfTransposerApply(
1304 hSbrDec->hHBE,
1305 pLowBandReal + hSbrDec->LppTrans.pSettings->overlap +
1306 hSbrDec->hHBE->noCols / 2 + LPC_ORDER,
1307 pLowBandImag + hSbrDec->LppTrans.pSettings->overlap +
1308 hSbrDec->hHBE->noCols / 2 + LPC_ORDER,
1309 hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag,
1310 hSbrDec->LppTrans.lpcFilterStatesRealHBE,
1311 hSbrDec->LppTrans.lpcFilterStatesImagHBE,
1312 hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb,
1313 hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale,
1314 hHeaderData->timeStep, hFrameData->frameInfo.borders[0],
1315 hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF);
1316
1317 copyHarmonicSpectrum(
1318 xOverQmf, pLowBandReal, pLowBandImag, hSbrDec->hHBE->noCols,
1319 hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF);
1320 }
1321 } else {
1322 /* in case of harmonic SBR and no HBE_LP map additional buffer for
1323 one more frame to pointer arry */
1324 for (i = 0; i < hSbrDec->hHBE->noCols; i++) {
1325 pLowBandReal[i + hSbrDec->hHBE->noCols +
1326 hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
1327 hSbrDec->hQmfHBESlotsReal[i];
1328 pLowBandImag[i + hSbrDec->hHBE->noCols +
1329 hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
1330 hSbrDec->hQmfHBESlotsImag[i];
1331 }
1332
1333 if (hFrameData->sbrPatchingMode == 0) {
1334 QmfTransposerApply(
1335 hSbrDec->hHBE,
1336 pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER,
1337 pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER,
1338 hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag,
1339 hSbrDec->LppTrans.lpcFilterStatesRealHBE,
1340 hSbrDec->LppTrans.lpcFilterStatesImagHBE,
1341 0 /* not required for keeping states updated in this frame*/,
1342 hSbrDec->scale_lb, hSbrDec->scale_lb,
1343 &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep,
1344 hFrameData->frameInfo.borders[0],
1345 hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_NOOUT);
1346 }
1347
1348 QmfTransposerApply(
1349 hSbrDec->hHBE,
1350 pLowBandReal + hSbrDec->LppTrans.pSettings->overlap +
1351 hSbrDec->hHBE->noCols + LPC_ORDER,
1352 pLowBandImag + hSbrDec->LppTrans.pSettings->overlap +
1353 hSbrDec->hHBE->noCols + LPC_ORDER,
1354 hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag,
1355 hSbrDec->LppTrans.lpcFilterStatesRealHBE,
1356 hSbrDec->LppTrans.lpcFilterStatesImagHBE,
1357 hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb,
1358 hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale,
1359 hHeaderData->timeStep, hFrameData->frameInfo.borders[0],
1360 hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF);
1361 }
1362
1363 if (hFrameData->sbrPatchingMode == 0) {
1364 for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) {
1365 /*
1366 Store the unmodified qmf Slots values for upper part of spectrum
1367 (required for LPC filtering) required if next frame is a HBE frame
1368 */
1369 FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsReal[i],
1370 hSbrDec->LppTrans.lpcFilterStatesRealHBE[i + LPC_ORDER],
1371 (64) * sizeof(FIXP_DBL));
1372 FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsImag[i],
1373 hSbrDec->LppTrans.lpcFilterStatesImagHBE[i + LPC_ORDER],
1374 (64) * sizeof(FIXP_DBL));
1375 }
1376
1377 for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) {
1378 /*
1379 Store the unmodified qmf Slots values for upper part of spectrum
1380 (required for LPC filtering) required if next frame is a HBE frame
1381 */
1382 FDKmemcpy(
1383 hSbrDec->qmfDomainInCh->hQmfSlotsReal[i],
1384 hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols -
1385 hSbrDec->LppTrans.pSettings->overlap +
1386 i],
1387 new_lsb * sizeof(FIXP_DBL));
1388 FDKmemcpy(
1389 hSbrDec->qmfDomainInCh->hQmfSlotsImag[i],
1390 hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols -
1391 hSbrDec->LppTrans.pSettings->overlap +
1392 i],
1393 new_lsb * sizeof(FIXP_DBL));
1394 }
1395 }
1396 }
1397 }
1398
1399 {
1400 int adapt_lb = 0, diff = 0,
1401 new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
1402
1403 if ((hSbrDec->qmfDomainInCh->scaling.ov_lb_scale !=
1404 hSbrDec->qmfDomainInCh->scaling.lb_scale) &&
1405 startSlot != 0) {
1406 /* we need to adapt spectrum to have equal scale factor, always larger
1407 * than zero */
1408 diff = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale) -
1409 SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale);
1410
1411 if (diff > 0) {
1412 adapt_lb = 1;
1413 diff = -diff;
1414 new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
1415 }
1416
1417 stopBand = new_lsb;
1418 }
1419
1420 if (hFrameData->sbrPatchingMode == 1) {
1421 /* scale states from LegSBR filterstates buffer */
1422 for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) {
1423 scaleValues(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], new_lsb,
1424 diff);
1425 if (!useLP) {
1426 scaleValues(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], new_lsb,
1427 diff);
1428 }
1429 }
1430
1431 if (flags & SBRDEC_SYNTAX_USAC) {
1432 /* get missing states between old and new x_over from LegSBR
1433 * filterstates buffer */
1434 /* in case of legacy SBR we leave these values zeroed out */
1435 for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) {
1436 FDKmemcpy(&OverlapBufferReal[i][old_lsb],
1437 &hSbrDec->LppTrans
1438 .lpcFilterStatesRealLegSBR[LPC_ORDER + i][old_lsb],
1439 fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL));
1440 if (!useLP) {
1441 FDKmemcpy(&OverlapBufferImag[i][old_lsb],
1442 &hSbrDec->LppTrans
1443 .lpcFilterStatesImagLegSBR[LPC_ORDER + i][old_lsb],
1444 fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL));
1445 }
1446 }
1447 }
1448
1449 if (new_lsb > old_lsb) {
1450 stopBand = old_lsb;
1451 }
1452 }
1453 if ((adapt_lb == 1) && (stopBand > startBand)) {
1454 for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) {
1455 scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand,
1456 diff);
1457 if (!useLP) {
1458 scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand,
1459 diff);
1460 }
1461 }
1462 }
1463 hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = new_scale;
1464 }
1465
1466 sbrError = ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable,
1467 &hHeaderData->freqBandData.noLimiterBands,
1468 hHeaderData->freqBandData.freqBandTable[0],
1469 hHeaderData->freqBandData.nSfb[0],
1470 hSbrDec->LppTrans.pSettings->patchParam,
1471 hSbrDec->LppTrans.pSettings->noOfPatches,
1472 hHeaderData->bs_data.limiterBands,
1473 hFrameData->sbrPatchingMode,
1474 GetxOverBandQmfTransposer(hSbrDec->hHBE),
1475 Get41SbrQmfTransposer(hSbrDec->hHBE));
1476
1477 hSbrDec->SbrCalculateEnvelope.sbrPatchingMode = hFrameData->sbrPatchingMode;
1478
1479 return sbrError;
1480 }
1481