/src/aac/libSBRdec/src/sbrdecoder.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 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /**************************** SBR decoder library ****************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | /*! |
104 | | \file |
105 | | \brief SBR decoder frontend |
106 | | This module provides a frontend to the SBR decoder. The function openSBR() is |
107 | | called for initialization. The function sbrDecoder_Apply() is called for each |
108 | | frame. sbr_Apply() will call the required functions to decode the raw SBR data |
109 | | (provided by env_extr.cpp), to decode the envelope data and noise floor levels |
110 | | [decodeSbrData()], and to finally apply SBR to the current frame [sbr_dec()]. |
111 | | |
112 | | \sa sbrDecoder_Apply(), \ref documentationOverview |
113 | | */ |
114 | | |
115 | | /*! |
116 | | \page documentationOverview Overview of important information resources and |
117 | | source code documentation |
118 | | |
119 | | As part of this documentation you can find more extensive descriptions about |
120 | | key concepts and algorithms at the following locations: |
121 | | |
122 | | <h2>Programming</h2> |
123 | | |
124 | | \li Buffer management: sbrDecoder_Apply() and sbr_dec() |
125 | | \li Internal scale factors to maximize SNR on fixed point processors: |
126 | | #QMF_SCALE_FACTOR \li Special mantissa-exponent format: Created in |
127 | | requantizeEnvelopeData() and used in calculateSbrEnvelope() |
128 | | |
129 | | <h2>Algorithmic details</h2> |
130 | | \li About the SBR data format: \ref SBR_HEADER_ELEMENT and \ref |
131 | | SBR_STANDARD_ELEMENT \li Details about the bitstream decoder: env_extr.cpp \li |
132 | | Details about the QMF filterbank and the provided polyphase implementation: |
133 | | qmf_dec.cpp \li Details about the transposer: lpp_tran.cpp \li Details about |
134 | | the envelope adjuster: env_calc.cpp |
135 | | |
136 | | */ |
137 | | |
138 | | #include "sbrdecoder.h" |
139 | | |
140 | | #include "FDK_bitstream.h" |
141 | | |
142 | | #include "sbrdec_freq_sca.h" |
143 | | #include "env_extr.h" |
144 | | #include "sbr_dec.h" |
145 | | #include "env_dec.h" |
146 | | #include "FDK_crc.h" |
147 | | #include "sbr_ram.h" |
148 | | #include "sbr_rom.h" |
149 | | #include "lpp_tran.h" |
150 | | #include "transcendent.h" |
151 | | |
152 | | #include "sbrdec_drc.h" |
153 | | |
154 | | #include "psbitdec.h" |
155 | | |
156 | | /* Decoder library info */ |
157 | | #define SBRDECODER_LIB_VL0 3 |
158 | | #define SBRDECODER_LIB_VL1 1 |
159 | | #define SBRDECODER_LIB_VL2 0 |
160 | 0 | #define SBRDECODER_LIB_TITLE "SBR Decoder" |
161 | | #ifdef SUPPRESS_BUILD_DATE_INFO |
162 | | #define SBRDECODER_LIB_BUILD_DATE "" |
163 | | #define SBRDECODER_LIB_BUILD_TIME "" |
164 | | #else |
165 | 0 | #define SBRDECODER_LIB_BUILD_DATE __DATE__ |
166 | 0 | #define SBRDECODER_LIB_BUILD_TIME __TIME__ |
167 | | #endif |
168 | | |
169 | 0 | static void setFrameErrorFlag(SBR_DECODER_ELEMENT *pSbrElement, UCHAR value) { |
170 | 0 | if (pSbrElement != NULL) { |
171 | 0 | switch (value) { |
172 | 0 | case FRAME_ERROR_ALLSLOTS: |
173 | 0 | FDKmemset(pSbrElement->frameErrorFlag, FRAME_ERROR, |
174 | 0 | sizeof(pSbrElement->frameErrorFlag)); |
175 | 0 | break; |
176 | 0 | default: |
177 | 0 | pSbrElement->frameErrorFlag[pSbrElement->useFrameSlot] = value; |
178 | 0 | } |
179 | 0 | } |
180 | 0 | } |
181 | | |
182 | 0 | static UCHAR getHeaderSlot(UCHAR currentSlot, UCHAR hdrSlotUsage[(1) + 1]) { |
183 | 0 | UINT occupied = 0; |
184 | 0 | int s; |
185 | 0 | UCHAR slot = hdrSlotUsage[currentSlot]; |
186 | |
|
187 | 0 | FDK_ASSERT((1) + 1 < 32); |
188 | | |
189 | 0 | for (s = 0; s < (1) + 1; s++) { |
190 | 0 | if ((hdrSlotUsage[s] == slot) && (s != slot)) { |
191 | 0 | occupied = 1; |
192 | 0 | break; |
193 | 0 | } |
194 | 0 | } |
195 | |
|
196 | 0 | if (occupied) { |
197 | 0 | occupied = 0; |
198 | |
|
199 | 0 | for (s = 0; s < (1) + 1; s++) { |
200 | 0 | occupied |= 1 << hdrSlotUsage[s]; |
201 | 0 | } |
202 | 0 | for (s = 0; s < (1) + 1; s++) { |
203 | 0 | if (!(occupied & 0x1)) { |
204 | 0 | slot = s; |
205 | 0 | break; |
206 | 0 | } |
207 | 0 | occupied >>= 1; |
208 | 0 | } |
209 | 0 | } |
210 | |
|
211 | 0 | return slot; |
212 | 0 | } |
213 | | |
214 | | static void copySbrHeader(HANDLE_SBR_HEADER_DATA hDst, |
215 | 0 | const HANDLE_SBR_HEADER_DATA hSrc) { |
216 | | /* copy the whole header memory (including pointers) */ |
217 | 0 | FDKmemcpy(hDst, hSrc, sizeof(SBR_HEADER_DATA)); |
218 | | |
219 | | /* update pointers */ |
220 | 0 | hDst->freqBandData.freqBandTable[0] = hDst->freqBandData.freqBandTableLo; |
221 | 0 | hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi; |
222 | 0 | } |
223 | | |
224 | | static int compareSbrHeader(const HANDLE_SBR_HEADER_DATA hHdr1, |
225 | 0 | const HANDLE_SBR_HEADER_DATA hHdr2) { |
226 | 0 | int result = 0; |
227 | | |
228 | | /* compare basic data */ |
229 | 0 | result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0; |
230 | 0 | result |= (hHdr1->status != hHdr2->status) ? 1 : 0; |
231 | 0 | result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0; |
232 | 0 | result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0; |
233 | 0 | result |= |
234 | 0 | (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0; |
235 | 0 | result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0; |
236 | 0 | result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0; |
237 | | |
238 | | /* compare bitstream data */ |
239 | 0 | result |= |
240 | 0 | FDKmemcmp(&hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS)); |
241 | 0 | result |= |
242 | 0 | FDKmemcmp(&hHdr1->bs_dflt, &hHdr2->bs_dflt, sizeof(SBR_HEADER_DATA_BS)); |
243 | 0 | result |= FDKmemcmp(&hHdr1->bs_info, &hHdr2->bs_info, |
244 | 0 | sizeof(SBR_HEADER_DATA_BS_INFO)); |
245 | | |
246 | | /* compare frequency band data */ |
247 | 0 | result |= FDKmemcmp(&hHdr1->freqBandData, &hHdr2->freqBandData, |
248 | 0 | (8 + MAX_NUM_LIMITERS + 1) * sizeof(UCHAR)); |
249 | 0 | result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableLo, |
250 | 0 | hHdr2->freqBandData.freqBandTableLo, |
251 | 0 | (MAX_FREQ_COEFFS / 2 + 1) * sizeof(UCHAR)); |
252 | 0 | result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableHi, |
253 | 0 | hHdr2->freqBandData.freqBandTableHi, |
254 | 0 | (MAX_FREQ_COEFFS + 1) * sizeof(UCHAR)); |
255 | 0 | result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableNoise, |
256 | 0 | hHdr2->freqBandData.freqBandTableNoise, |
257 | 0 | (MAX_NOISE_COEFFS + 1) * sizeof(UCHAR)); |
258 | 0 | result |= |
259 | 0 | FDKmemcmp(hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, |
260 | 0 | (MAX_FREQ_COEFFS + 1) * sizeof(UCHAR)); |
261 | |
|
262 | 0 | return result; |
263 | 0 | } |
264 | | |
265 | | /*! |
266 | | \brief Reset SBR decoder. |
267 | | |
268 | | Reset should only be called if SBR has been sucessfully detected by |
269 | | an appropriate checkForPayload() function. |
270 | | |
271 | | \return Error code. |
272 | | */ |
273 | | static SBR_ERROR sbrDecoder_ResetElement(HANDLE_SBRDECODER self, |
274 | | int sampleRateIn, int sampleRateOut, |
275 | | int samplesPerFrame, |
276 | | const MP4_ELEMENT_ID elementID, |
277 | | const int elementIndex, |
278 | 0 | const int overlap) { |
279 | 0 | SBR_ERROR sbrError = SBRDEC_OK; |
280 | 0 | HANDLE_SBR_HEADER_DATA hSbrHeader; |
281 | 0 | UINT qmfFlags = 0; |
282 | |
|
283 | 0 | int i, synDownsampleFac; |
284 | | |
285 | | /* USAC: assuming theoretical case 8 kHz output sample rate with 4:1 SBR */ |
286 | 0 | const int sbr_min_sample_rate_in = IS_USAC(self->coreCodec) ? 2000 : 6400; |
287 | | |
288 | | /* Check in/out samplerates */ |
289 | 0 | if (sampleRateIn < sbr_min_sample_rate_in || sampleRateIn > (96000)) { |
290 | 0 | sbrError = SBRDEC_UNSUPPORTED_CONFIG; |
291 | 0 | goto bail; |
292 | 0 | } |
293 | | |
294 | 0 | if (sampleRateOut > (96000)) { |
295 | 0 | sbrError = SBRDEC_UNSUPPORTED_CONFIG; |
296 | 0 | goto bail; |
297 | 0 | } |
298 | | |
299 | | /* Set QMF mode flags */ |
300 | 0 | if (self->flags & SBRDEC_LOW_POWER) qmfFlags |= QMF_FLAG_LP; |
301 | |
|
302 | 0 | if (self->coreCodec == AOT_ER_AAC_ELD) { |
303 | 0 | if (self->flags & SBRDEC_LD_MPS_QMF) { |
304 | 0 | qmfFlags |= QMF_FLAG_MPSLDFB; |
305 | 0 | } else { |
306 | 0 | qmfFlags |= QMF_FLAG_CLDFB; |
307 | 0 | } |
308 | 0 | } |
309 | | |
310 | | /* Set downsampling factor for synthesis filter bank */ |
311 | 0 | if (sampleRateOut == 0) { |
312 | | /* no single rate mode */ |
313 | 0 | sampleRateOut = |
314 | 0 | sampleRateIn |
315 | 0 | << 1; /* In case of implicit signalling, assume dual rate SBR */ |
316 | 0 | } |
317 | |
|
318 | 0 | if (sampleRateIn == sampleRateOut) { |
319 | 0 | synDownsampleFac = 2; |
320 | 0 | self->flags |= SBRDEC_DOWNSAMPLE; |
321 | 0 | } else { |
322 | 0 | synDownsampleFac = 1; |
323 | 0 | self->flags &= ~SBRDEC_DOWNSAMPLE; |
324 | 0 | } |
325 | |
|
326 | 0 | self->synDownsampleFac = synDownsampleFac; |
327 | 0 | self->sampleRateOut = sampleRateOut; |
328 | |
|
329 | 0 | { |
330 | 0 | for (i = 0; i < (1) + 1; i++) { |
331 | 0 | int setDflt; |
332 | 0 | hSbrHeader = &(self->sbrHeader[elementIndex][i]); |
333 | 0 | setDflt = ((hSbrHeader->syncState == SBR_NOT_INITIALIZED) || |
334 | 0 | (self->flags & SBRDEC_FORCE_RESET)) |
335 | 0 | ? 1 |
336 | 0 | : 0; |
337 | | |
338 | | /* init a default header such that we can at least do upsampling later */ |
339 | 0 | sbrError = initHeaderData(hSbrHeader, sampleRateIn, sampleRateOut, |
340 | 0 | self->downscaleFactor, samplesPerFrame, |
341 | 0 | self->flags, setDflt); |
342 | | |
343 | | /* Set synchState to UPSAMPLING in case it already is initialized */ |
344 | 0 | hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING |
345 | 0 | ? UPSAMPLING |
346 | 0 | : hSbrHeader->syncState; |
347 | 0 | } |
348 | 0 | } |
349 | |
|
350 | 0 | if (sbrError != SBRDEC_OK) { |
351 | 0 | goto bail; |
352 | 0 | } |
353 | | |
354 | 0 | if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) { |
355 | 0 | self->pQmfDomain->globalConf.flags_requested |= qmfFlags; |
356 | 0 | self->pQmfDomain->globalConf.nBandsAnalysis_requested = |
357 | 0 | self->sbrHeader[elementIndex][0].numberOfAnalysisBands; |
358 | 0 | self->pQmfDomain->globalConf.nBandsSynthesis_requested = |
359 | 0 | (synDownsampleFac == 1) ? 64 : 32; /* may be overwritten by MPS */ |
360 | 0 | self->pQmfDomain->globalConf.nBandsSynthesis_requested /= |
361 | 0 | self->downscaleFactor; |
362 | 0 | self->pQmfDomain->globalConf.nQmfTimeSlots_requested = |
363 | 0 | self->sbrHeader[elementIndex][0].numberTimeSlots * |
364 | 0 | self->sbrHeader[elementIndex][0].timeStep; |
365 | 0 | self->pQmfDomain->globalConf.nQmfOvTimeSlots_requested = overlap; |
366 | 0 | self->pQmfDomain->globalConf.nQmfProcBands_requested = 64; /* always 64 */ |
367 | 0 | self->pQmfDomain->globalConf.nQmfProcChannels_requested = |
368 | 0 | 1; /* may be overwritten by MPS */ |
369 | 0 | } |
370 | | |
371 | | /* Init SBR channels going to be assigned to a SBR element */ |
372 | 0 | { |
373 | 0 | int ch; |
374 | 0 | for (ch = 0; ch < self->pSbrElement[elementIndex]->nChannels; ch++) { |
375 | 0 | int headerIndex = |
376 | 0 | getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, |
377 | 0 | self->pSbrElement[elementIndex]->useHeaderSlot); |
378 | | |
379 | | /* and create sbrDec */ |
380 | 0 | sbrError = |
381 | 0 | createSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch], |
382 | 0 | &self->sbrHeader[elementIndex][headerIndex], |
383 | 0 | &self->pSbrElement[elementIndex]->transposerSettings, |
384 | 0 | synDownsampleFac, qmfFlags, self->flags, overlap, ch, |
385 | 0 | self->codecFrameSize); |
386 | |
|
387 | 0 | if (sbrError != SBRDEC_OK) { |
388 | 0 | goto bail; |
389 | 0 | } |
390 | 0 | } |
391 | 0 | } |
392 | | |
393 | | // FDKmemclear(sbr_OverlapBuffer, sizeof(sbr_OverlapBuffer)); |
394 | | |
395 | 0 | if (self->numSbrElements == 1) { |
396 | 0 | switch (self->coreCodec) { |
397 | 0 | case AOT_AAC_LC: |
398 | 0 | case AOT_SBR: |
399 | 0 | case AOT_PS: |
400 | 0 | case AOT_ER_AAC_SCAL: |
401 | 0 | case AOT_DRM_AAC: |
402 | 0 | case AOT_DRM_SURROUND: |
403 | 0 | if (CreatePsDec(&self->hParametricStereoDec, samplesPerFrame)) { |
404 | 0 | sbrError = SBRDEC_CREATE_ERROR; |
405 | 0 | goto bail; |
406 | 0 | } |
407 | 0 | break; |
408 | 0 | default: |
409 | 0 | break; |
410 | 0 | } |
411 | 0 | } |
412 | | |
413 | | /* Init frame delay slot handling */ |
414 | 0 | self->pSbrElement[elementIndex]->useFrameSlot = 0; |
415 | 0 | for (i = 0; i < ((1) + 1); i++) { |
416 | 0 | self->pSbrElement[elementIndex]->useHeaderSlot[i] = i; |
417 | 0 | } |
418 | |
|
419 | 0 | bail: |
420 | |
|
421 | 0 | return sbrError; |
422 | 0 | } |
423 | | |
424 | | /*! |
425 | | \brief Assign QMF domain provided QMF channels to SBR channels. |
426 | | |
427 | | \return void |
428 | | */ |
429 | 0 | static void sbrDecoder_AssignQmfChannels2SbrChannels(HANDLE_SBRDECODER self) { |
430 | 0 | int ch, el, absCh_offset = 0; |
431 | 0 | for (el = 0; el < self->numSbrElements; el++) { |
432 | 0 | if (self->pSbrElement[el] != NULL) { |
433 | 0 | for (ch = 0; ch < self->pSbrElement[el]->nChannels; ch++) { |
434 | 0 | FDK_ASSERT(((absCh_offset + ch) < ((8) + (1))) && |
435 | 0 | ((absCh_offset + ch) < ((8) + (1)))); |
436 | 0 | self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainInCh = |
437 | 0 | &self->pQmfDomain->QmfDomainIn[absCh_offset + ch]; |
438 | 0 | self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainOutCh = |
439 | 0 | &self->pQmfDomain->QmfDomainOut[absCh_offset + ch]; |
440 | 0 | } |
441 | 0 | absCh_offset += self->pSbrElement[el]->nChannels; |
442 | 0 | } |
443 | 0 | } |
444 | 0 | } |
445 | | |
446 | | SBR_ERROR sbrDecoder_Open(HANDLE_SBRDECODER *pSelf, |
447 | 23 | HANDLE_FDK_QMF_DOMAIN pQmfDomain) { |
448 | 23 | HANDLE_SBRDECODER self = NULL; |
449 | 23 | SBR_ERROR sbrError = SBRDEC_OK; |
450 | 23 | int elIdx; |
451 | | |
452 | 23 | if ((pSelf == NULL) || (pQmfDomain == NULL)) { |
453 | 0 | return SBRDEC_INVALID_ARGUMENT; |
454 | 0 | } |
455 | | |
456 | | /* Get memory for this instance */ |
457 | 23 | self = GetRam_SbrDecoder(); |
458 | 23 | if (self == NULL) { |
459 | 0 | sbrError = SBRDEC_MEM_ALLOC_FAILED; |
460 | 0 | goto bail; |
461 | 0 | } |
462 | | |
463 | 23 | self->pQmfDomain = pQmfDomain; |
464 | | |
465 | | /* |
466 | | Already zero because of calloc |
467 | | self->numSbrElements = 0; |
468 | | self->numSbrChannels = 0; |
469 | | self->codecFrameSize = 0; |
470 | | */ |
471 | | |
472 | 23 | self->numDelayFrames = (1); /* set to the max value by default */ |
473 | | |
474 | | /* Initialize header sync state */ |
475 | 207 | for (elIdx = 0; elIdx < (8); elIdx += 1) { |
476 | 184 | int i; |
477 | 552 | for (i = 0; i < (1) + 1; i += 1) { |
478 | 368 | self->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED; |
479 | 368 | } |
480 | 184 | } |
481 | | |
482 | 23 | *pSelf = self; |
483 | | |
484 | 23 | bail: |
485 | 23 | return sbrError; |
486 | 23 | } |
487 | | |
488 | | /** |
489 | | * \brief determine if the given core codec AOT can be processed or not. |
490 | | * \param coreCodec core codec audio object type. |
491 | | * \return 1 if SBR can be processed, 0 if SBR cannot be processed/applied. |
492 | | */ |
493 | 0 | static int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec) { |
494 | 0 | switch (coreCodec) { |
495 | 0 | case AOT_AAC_LC: |
496 | 0 | case AOT_SBR: |
497 | 0 | case AOT_PS: |
498 | 0 | case AOT_ER_AAC_SCAL: |
499 | 0 | case AOT_ER_AAC_ELD: |
500 | 0 | case AOT_DRM_AAC: |
501 | 0 | case AOT_DRM_SURROUND: |
502 | 0 | case AOT_USAC: |
503 | 0 | return 1; |
504 | 0 | default: |
505 | 0 | return 0; |
506 | 0 | } |
507 | 0 | } |
508 | | |
509 | | static void sbrDecoder_DestroyElement(HANDLE_SBRDECODER self, |
510 | 184 | const int elementIndex) { |
511 | 184 | if (self->pSbrElement[elementIndex] != NULL) { |
512 | 0 | int ch; |
513 | |
|
514 | 0 | for (ch = 0; ch < SBRDEC_MAX_CH_PER_ELEMENT; ch++) { |
515 | 0 | if (self->pSbrElement[elementIndex]->pSbrChannel[ch] != NULL) { |
516 | 0 | deleteSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch]); |
517 | 0 | FreeRam_SbrDecChannel( |
518 | 0 | &self->pSbrElement[elementIndex]->pSbrChannel[ch]); |
519 | 0 | self->numSbrChannels -= 1; |
520 | 0 | } |
521 | 0 | } |
522 | 0 | FreeRam_SbrDecElement(&self->pSbrElement[elementIndex]); |
523 | 0 | self->numSbrElements -= 1; |
524 | 0 | } |
525 | 184 | } |
526 | | |
527 | | SBR_ERROR sbrDecoder_InitElement( |
528 | | HANDLE_SBRDECODER self, const int sampleRateIn, const int sampleRateOut, |
529 | | const int samplesPerFrame, const AUDIO_OBJECT_TYPE coreCodec, |
530 | | const MP4_ELEMENT_ID elementID, const int elementIndex, |
531 | | const UCHAR harmonicSBR, const UCHAR stereoConfigIndex, |
532 | 0 | const UCHAR configMode, UCHAR *configChanged, const INT downscaleFactor) { |
533 | 0 | SBR_ERROR sbrError = SBRDEC_OK; |
534 | 0 | int chCnt = 0; |
535 | 0 | int nSbrElementsStart; |
536 | 0 | int nSbrChannelsStart; |
537 | 0 | if (self == NULL) { |
538 | 0 | return SBRDEC_INVALID_ARGUMENT; |
539 | 0 | } |
540 | | |
541 | 0 | nSbrElementsStart = self->numSbrElements; |
542 | 0 | nSbrChannelsStart = self->numSbrChannels; |
543 | | |
544 | | /* Check core codec AOT */ |
545 | 0 | if (!sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) { |
546 | 0 | sbrError = SBRDEC_UNSUPPORTED_CONFIG; |
547 | 0 | goto bail; |
548 | 0 | } |
549 | | |
550 | 0 | if (elementID != ID_SCE && elementID != ID_CPE && elementID != ID_LFE) { |
551 | 0 | sbrError = SBRDEC_UNSUPPORTED_CONFIG; |
552 | 0 | goto bail; |
553 | 0 | } |
554 | | |
555 | 0 | if (self->sampleRateIn == sampleRateIn && |
556 | 0 | self->codecFrameSize == samplesPerFrame && self->coreCodec == coreCodec && |
557 | 0 | self->pSbrElement[elementIndex] != NULL && |
558 | 0 | self->pSbrElement[elementIndex]->elementID == elementID && |
559 | 0 | !(self->flags & SBRDEC_FORCE_RESET) && |
560 | 0 | ((sampleRateOut == 0) ? 1 : (self->sampleRateOut == sampleRateOut)) && |
561 | 0 | ((harmonicSBR == 2) ? 1 |
562 | 0 | : (self->harmonicSBR == |
563 | 0 | harmonicSBR)) /* The value 2 signalizes that |
564 | | harmonicSBR shall be ignored in |
565 | | the config change detection */ |
566 | 0 | ) { |
567 | | /* Nothing to do */ |
568 | 0 | return SBRDEC_OK; |
569 | 0 | } else { |
570 | 0 | if (configMode & AC_CM_DET_CFG_CHANGE) { |
571 | 0 | *configChanged = 1; |
572 | 0 | } |
573 | 0 | } |
574 | | |
575 | | /* reaching this point the SBR-decoder gets (re-)configured */ |
576 | | |
577 | | /* The flags field is used for all elements! */ |
578 | 0 | self->flags &= |
579 | 0 | (SBRDEC_FORCE_RESET | SBRDEC_FLUSH); /* Keep the global flags. They will |
580 | | be reset after decoding. */ |
581 | 0 | self->flags |= (downscaleFactor > 1) ? SBRDEC_ELD_DOWNSCALE : 0; |
582 | 0 | self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0; |
583 | 0 | self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0; |
584 | 0 | self->flags |= |
585 | 0 | (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM : 0; |
586 | 0 | self->flags |= (coreCodec == AOT_DRM_SURROUND) |
587 | 0 | ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM |
588 | 0 | : 0; |
589 | 0 | self->flags |= (coreCodec == AOT_USAC) ? SBRDEC_SYNTAX_USAC : 0; |
590 | | /* Robustness: Take integer division rounding into consideration. E.g. 22050 |
591 | | * Hz with 4:1 SBR => 5512 Hz core sampling rate. */ |
592 | 0 | self->flags |= (sampleRateIn == sampleRateOut / 4) ? SBRDEC_QUAD_RATE : 0; |
593 | 0 | self->flags |= (harmonicSBR == 1) ? SBRDEC_USAC_HARMONICSBR : 0; |
594 | |
|
595 | 0 | if (configMode & AC_CM_DET_CFG_CHANGE) { |
596 | 0 | return SBRDEC_OK; |
597 | 0 | } |
598 | | |
599 | 0 | self->sampleRateIn = sampleRateIn; |
600 | 0 | self->codecFrameSize = samplesPerFrame; |
601 | 0 | self->coreCodec = coreCodec; |
602 | 0 | self->harmonicSBR = harmonicSBR; |
603 | 0 | self->downscaleFactor = downscaleFactor; |
604 | | |
605 | | /* Init SBR elements */ |
606 | 0 | { |
607 | 0 | int elChannels, ch; |
608 | |
|
609 | 0 | if (self->pSbrElement[elementIndex] == NULL) { |
610 | 0 | self->pSbrElement[elementIndex] = GetRam_SbrDecElement(elementIndex); |
611 | 0 | if (self->pSbrElement[elementIndex] == NULL) { |
612 | 0 | sbrError = SBRDEC_MEM_ALLOC_FAILED; |
613 | 0 | goto bail; |
614 | 0 | } |
615 | 0 | self->numSbrElements++; |
616 | 0 | } else { |
617 | 0 | self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels; |
618 | 0 | } |
619 | | |
620 | | /* Determine amount of channels for this element */ |
621 | 0 | switch (elementID) { |
622 | 0 | case ID_NONE: |
623 | 0 | case ID_CPE: |
624 | 0 | elChannels = 2; |
625 | 0 | break; |
626 | 0 | case ID_LFE: |
627 | 0 | case ID_SCE: |
628 | 0 | elChannels = 1; |
629 | 0 | break; |
630 | 0 | default: |
631 | 0 | elChannels = 0; |
632 | 0 | break; |
633 | 0 | } |
634 | | |
635 | | /* Handle case of Parametric Stereo */ |
636 | 0 | if (elementIndex == 0 && elementID == ID_SCE) { |
637 | 0 | switch (coreCodec) { |
638 | 0 | case AOT_AAC_LC: |
639 | 0 | case AOT_SBR: |
640 | 0 | case AOT_PS: |
641 | 0 | case AOT_ER_AAC_SCAL: |
642 | 0 | case AOT_DRM_AAC: |
643 | 0 | case AOT_DRM_SURROUND: |
644 | 0 | elChannels = 2; |
645 | 0 | break; |
646 | 0 | default: |
647 | 0 | break; |
648 | 0 | } |
649 | 0 | } |
650 | | |
651 | | /* Sanity check to avoid memory leaks */ |
652 | 0 | if (elChannels < self->pSbrElement[elementIndex]->nChannels || |
653 | 0 | (self->numSbrChannels + elChannels) > (8) + (1)) { |
654 | 0 | self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels; |
655 | 0 | sbrError = SBRDEC_PARSE_ERROR; |
656 | 0 | goto bail; |
657 | 0 | } |
658 | | |
659 | | /* Save element ID for sanity checks and to have a fallback for concealment. |
660 | | */ |
661 | 0 | self->pSbrElement[elementIndex]->elementID = elementID; |
662 | 0 | self->pSbrElement[elementIndex]->nChannels = elChannels; |
663 | |
|
664 | 0 | for (ch = 0; ch < elChannels; ch++) { |
665 | 0 | if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) { |
666 | 0 | self->pSbrElement[elementIndex]->pSbrChannel[ch] = |
667 | 0 | GetRam_SbrDecChannel(chCnt); |
668 | 0 | if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) { |
669 | 0 | sbrError = SBRDEC_MEM_ALLOC_FAILED; |
670 | 0 | goto bail; |
671 | 0 | } |
672 | 0 | } |
673 | 0 | self->numSbrChannels++; |
674 | |
|
675 | 0 | sbrDecoder_drcInitChannel(&self->pSbrElement[elementIndex] |
676 | 0 | ->pSbrChannel[ch] |
677 | 0 | ->SbrDec.sbrDrcChannel); |
678 | |
|
679 | 0 | chCnt++; |
680 | 0 | } |
681 | 0 | } |
682 | | |
683 | 0 | if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) { |
684 | 0 | self->pQmfDomain->globalConf.nInputChannels_requested = |
685 | 0 | self->numSbrChannels; |
686 | 0 | self->pQmfDomain->globalConf.nOutputChannels_requested = |
687 | 0 | fMax((INT)self->numSbrChannels, |
688 | 0 | (INT)self->pQmfDomain->globalConf.nOutputChannels_requested); |
689 | 0 | } |
690 | | |
691 | | /* Make sure each SBR channel has one QMF channel assigned even if |
692 | | * numSbrChannels or element set-up has changed. */ |
693 | 0 | sbrDecoder_AssignQmfChannels2SbrChannels(self); |
694 | | |
695 | | /* clear error flags for all delay slots */ |
696 | 0 | FDKmemclear(self->pSbrElement[elementIndex]->frameErrorFlag, |
697 | 0 | ((1) + 1) * sizeof(UCHAR)); |
698 | |
|
699 | 0 | { |
700 | 0 | int overlap; |
701 | |
|
702 | 0 | if (coreCodec == AOT_ER_AAC_ELD) { |
703 | 0 | overlap = 0; |
704 | 0 | } else if (self->flags & SBRDEC_QUAD_RATE) { |
705 | 0 | overlap = (3 * 4); |
706 | 0 | } else { |
707 | 0 | overlap = (3 * 2); |
708 | 0 | } |
709 | | /* Initialize this instance */ |
710 | 0 | sbrError = sbrDecoder_ResetElement(self, sampleRateIn, sampleRateOut, |
711 | 0 | samplesPerFrame, elementID, elementIndex, |
712 | 0 | overlap); |
713 | 0 | } |
714 | |
|
715 | 0 | bail: |
716 | 0 | if (sbrError != SBRDEC_OK) { |
717 | 0 | if ((nSbrElementsStart < self->numSbrElements) || |
718 | 0 | (nSbrChannelsStart < self->numSbrChannels)) { |
719 | | /* Free the memory allocated for this element */ |
720 | 0 | sbrDecoder_DestroyElement(self, elementIndex); |
721 | 0 | } else if ((elementIndex < (8)) && |
722 | 0 | (self->pSbrElement[elementIndex] != |
723 | 0 | NULL)) { /* Set error flag to trigger concealment */ |
724 | 0 | setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); |
725 | 0 | } |
726 | 0 | } |
727 | |
|
728 | 0 | return sbrError; |
729 | 0 | } |
730 | | |
731 | | /** |
732 | | * \brief Free config dependent SBR memory. |
733 | | * \param self SBR decoder instance handle |
734 | | */ |
735 | 0 | SBR_ERROR sbrDecoder_FreeMem(HANDLE_SBRDECODER *self) { |
736 | 0 | int i; |
737 | 0 | int elIdx; |
738 | |
|
739 | 0 | if (self != NULL && *self != NULL) { |
740 | 0 | for (i = 0; i < (8); i++) { |
741 | 0 | sbrDecoder_DestroyElement(*self, i); |
742 | 0 | } |
743 | |
|
744 | 0 | for (elIdx = 0; elIdx < (8); elIdx += 1) { |
745 | 0 | for (i = 0; i < (1) + 1; i += 1) { |
746 | 0 | (*self)->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED; |
747 | 0 | } |
748 | 0 | } |
749 | 0 | } |
750 | |
|
751 | 0 | return SBRDEC_OK; |
752 | 0 | } |
753 | | |
754 | | /** |
755 | | * \brief Apply decoded SBR header for one element. |
756 | | * \param self SBR decoder instance handle |
757 | | * \param hSbrHeader SBR header handle to be processed. |
758 | | * \param hSbrChannel pointer array to the SBR element channels corresponding to |
759 | | * the SBR header. |
760 | | * \param headerStatus header status value returned from SBR header parser. |
761 | | * \param numElementChannels amount of channels for the SBR element whos header |
762 | | * is to be processed. |
763 | | */ |
764 | | static SBR_ERROR sbrDecoder_HeaderUpdate(HANDLE_SBRDECODER self, |
765 | | HANDLE_SBR_HEADER_DATA hSbrHeader, |
766 | | SBR_HEADER_STATUS headerStatus, |
767 | | HANDLE_SBR_CHANNEL hSbrChannel[], |
768 | 0 | const int numElementChannels) { |
769 | 0 | SBR_ERROR errorStatus = SBRDEC_OK; |
770 | | |
771 | | /* |
772 | | change of control data, reset decoder |
773 | | */ |
774 | 0 | errorStatus = resetFreqBandTables(hSbrHeader, self->flags); |
775 | |
|
776 | 0 | if (errorStatus == SBRDEC_OK) { |
777 | 0 | if (hSbrHeader->syncState == UPSAMPLING && headerStatus != HEADER_RESET) { |
778 | | #if (SBRDEC_MAX_HB_FADE_FRAMES > 0) |
779 | | int ch; |
780 | | for (ch = 0; ch < numElementChannels; ch += 1) { |
781 | | hSbrChannel[ch]->SbrDec.highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES; |
782 | | } |
783 | | |
784 | | #endif |
785 | | /* As the default header would limit the frequency range, |
786 | | lowSubband and highSubband must be patched. */ |
787 | 0 | hSbrHeader->freqBandData.lowSubband = hSbrHeader->numberOfAnalysisBands; |
788 | 0 | hSbrHeader->freqBandData.highSubband = hSbrHeader->numberOfAnalysisBands; |
789 | 0 | } |
790 | | |
791 | | /* Trigger a reset before processing this slot */ |
792 | 0 | hSbrHeader->status |= SBRDEC_HDR_STAT_RESET; |
793 | 0 | } |
794 | |
|
795 | 0 | return errorStatus; |
796 | 0 | } |
797 | | |
798 | | INT sbrDecoder_Header(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, |
799 | | const INT sampleRateIn, const INT sampleRateOut, |
800 | | const INT samplesPerFrame, |
801 | | const AUDIO_OBJECT_TYPE coreCodec, |
802 | | const MP4_ELEMENT_ID elementID, const INT elementIndex, |
803 | | const UCHAR harmonicSBR, const UCHAR stereoConfigIndex, |
804 | | const UCHAR configMode, UCHAR *configChanged, |
805 | 0 | const INT downscaleFactor) { |
806 | 0 | SBR_HEADER_STATUS headerStatus; |
807 | 0 | HANDLE_SBR_HEADER_DATA hSbrHeader; |
808 | 0 | SBR_ERROR sbrError = SBRDEC_OK; |
809 | 0 | int headerIndex; |
810 | 0 | UINT flagsSaved = |
811 | 0 | 0; /* flags should not be changed in AC_CM_DET_CFG_CHANGE - mode after |
812 | | parsing */ |
813 | |
|
814 | 0 | if (self == NULL || elementIndex >= (8)) { |
815 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
816 | 0 | } |
817 | | |
818 | 0 | if (!sbrDecoder_isCoreCodecValid(coreCodec)) { |
819 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
820 | 0 | } |
821 | | |
822 | 0 | if (configMode & AC_CM_DET_CFG_CHANGE) { |
823 | 0 | flagsSaved = self->flags; /* store */ |
824 | 0 | } |
825 | |
|
826 | 0 | sbrError = sbrDecoder_InitElement( |
827 | 0 | self, sampleRateIn, sampleRateOut, samplesPerFrame, coreCodec, elementID, |
828 | 0 | elementIndex, harmonicSBR, stereoConfigIndex, configMode, configChanged, |
829 | 0 | downscaleFactor); |
830 | |
|
831 | 0 | if ((sbrError != SBRDEC_OK) || (elementID == ID_LFE)) { |
832 | 0 | goto bail; |
833 | 0 | } |
834 | | |
835 | 0 | if (configMode & AC_CM_DET_CFG_CHANGE) { |
836 | 0 | hSbrHeader = NULL; |
837 | 0 | } else { |
838 | 0 | headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, |
839 | 0 | self->pSbrElement[elementIndex]->useHeaderSlot); |
840 | |
|
841 | 0 | hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]); |
842 | 0 | } |
843 | |
|
844 | 0 | headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 0, configMode); |
845 | |
|
846 | 0 | if (coreCodec == AOT_USAC) { |
847 | 0 | if (configMode & AC_CM_DET_CFG_CHANGE) { |
848 | 0 | self->flags = flagsSaved; /* restore */ |
849 | 0 | } |
850 | 0 | return sbrError; |
851 | 0 | } |
852 | | |
853 | 0 | if (configMode & AC_CM_ALLOC_MEM) { |
854 | 0 | SBR_DECODER_ELEMENT *pSbrElement; |
855 | |
|
856 | 0 | pSbrElement = self->pSbrElement[elementIndex]; |
857 | | |
858 | | /* Sanity check */ |
859 | 0 | if (pSbrElement != NULL) { |
860 | 0 | if ((elementID == ID_CPE && pSbrElement->nChannels != 2) || |
861 | 0 | (elementID != ID_CPE && pSbrElement->nChannels != 1)) { |
862 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
863 | 0 | } |
864 | 0 | if (headerStatus == HEADER_RESET) { |
865 | 0 | sbrError = sbrDecoder_HeaderUpdate(self, hSbrHeader, headerStatus, |
866 | 0 | pSbrElement->pSbrChannel, |
867 | 0 | pSbrElement->nChannels); |
868 | |
|
869 | 0 | if (sbrError == SBRDEC_OK) { |
870 | 0 | hSbrHeader->syncState = SBR_HEADER; |
871 | 0 | hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; |
872 | 0 | } else { |
873 | 0 | hSbrHeader->syncState = SBR_NOT_INITIALIZED; |
874 | 0 | hSbrHeader->status = HEADER_ERROR; |
875 | 0 | } |
876 | 0 | } |
877 | 0 | } |
878 | 0 | } |
879 | 0 | bail: |
880 | 0 | if (configMode & AC_CM_DET_CFG_CHANGE) { |
881 | 0 | self->flags = flagsSaved; /* restore */ |
882 | 0 | } |
883 | 0 | return sbrError; |
884 | 0 | } |
885 | | |
886 | | SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param, |
887 | 23 | const INT value) { |
888 | 23 | SBR_ERROR errorStatus = SBRDEC_OK; |
889 | | |
890 | | /* configure the subsystems */ |
891 | 23 | switch (param) { |
892 | 23 | case SBR_SYSTEM_BITSTREAM_DELAY: |
893 | 23 | if (value < 0 || value > (1)) { |
894 | 0 | errorStatus = SBRDEC_SET_PARAM_FAIL; |
895 | 0 | break; |
896 | 0 | } |
897 | 23 | if (self == NULL) { |
898 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
899 | 23 | } else { |
900 | 23 | self->numDelayFrames = (UCHAR)value; |
901 | 23 | } |
902 | 23 | break; |
903 | 0 | case SBR_QMF_MODE: |
904 | 0 | if (self == NULL) { |
905 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
906 | 0 | } else { |
907 | 0 | if (value == 1) { |
908 | 0 | self->flags |= SBRDEC_LOW_POWER; |
909 | 0 | } else { |
910 | 0 | self->flags &= ~SBRDEC_LOW_POWER; |
911 | 0 | } |
912 | 0 | } |
913 | 0 | break; |
914 | 0 | case SBR_LD_QMF_TIME_ALIGN: |
915 | 0 | if (self == NULL) { |
916 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
917 | 0 | } else { |
918 | 0 | if (value == 1) { |
919 | 0 | self->flags |= SBRDEC_LD_MPS_QMF; |
920 | 0 | } else { |
921 | 0 | self->flags &= ~SBRDEC_LD_MPS_QMF; |
922 | 0 | } |
923 | 0 | } |
924 | 0 | break; |
925 | 0 | case SBR_FLUSH_DATA: |
926 | 0 | if (value != 0) { |
927 | 0 | if (self == NULL) { |
928 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
929 | 0 | } else { |
930 | 0 | self->flags |= SBRDEC_FLUSH; |
931 | 0 | } |
932 | 0 | } |
933 | 0 | break; |
934 | 0 | case SBR_CLEAR_HISTORY: |
935 | 0 | if (value != 0) { |
936 | 0 | if (self == NULL) { |
937 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
938 | 0 | } else { |
939 | 0 | self->flags |= SBRDEC_FORCE_RESET; |
940 | 0 | } |
941 | 0 | } |
942 | 0 | break; |
943 | 0 | case SBR_BS_INTERRUPTION: { |
944 | 0 | int elementIndex; |
945 | |
|
946 | 0 | if (self == NULL) { |
947 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
948 | 0 | break; |
949 | 0 | } |
950 | | |
951 | | /* Loop over SBR elements */ |
952 | 0 | for (elementIndex = 0; elementIndex < self->numSbrElements; |
953 | 0 | elementIndex++) { |
954 | 0 | if (self->pSbrElement[elementIndex] != NULL) { |
955 | 0 | HANDLE_SBR_HEADER_DATA hSbrHeader; |
956 | 0 | int headerIndex = |
957 | 0 | getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, |
958 | 0 | self->pSbrElement[elementIndex]->useHeaderSlot); |
959 | |
|
960 | 0 | hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]); |
961 | | |
962 | | /* Set sync state UPSAMPLING for the corresponding slot. |
963 | | This switches off bitstream parsing until a new header arrives. */ |
964 | 0 | if (hSbrHeader->syncState != SBR_NOT_INITIALIZED) { |
965 | 0 | hSbrHeader->syncState = UPSAMPLING; |
966 | 0 | hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; |
967 | 0 | } |
968 | 0 | } |
969 | 0 | } |
970 | 0 | } break; |
971 | | |
972 | 0 | case SBR_SKIP_QMF: |
973 | 0 | if (self == NULL) { |
974 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
975 | 0 | } else { |
976 | 0 | if (value == 1) { |
977 | 0 | self->flags |= SBRDEC_SKIP_QMF_ANA; |
978 | 0 | } else { |
979 | 0 | self->flags &= ~SBRDEC_SKIP_QMF_ANA; |
980 | 0 | } |
981 | 0 | if (value == 2) { |
982 | 0 | self->flags |= SBRDEC_SKIP_QMF_SYN; |
983 | 0 | } else { |
984 | 0 | self->flags &= ~SBRDEC_SKIP_QMF_SYN; |
985 | 0 | } |
986 | 0 | } |
987 | 0 | break; |
988 | 0 | default: |
989 | 0 | errorStatus = SBRDEC_SET_PARAM_FAIL; |
990 | 0 | break; |
991 | 23 | } /* switch(param) */ |
992 | | |
993 | 23 | return (errorStatus); |
994 | 23 | } |
995 | | |
996 | | static SBRDEC_DRC_CHANNEL *sbrDecoder_drcGetChannel( |
997 | 0 | const HANDLE_SBRDECODER self, const INT channel) { |
998 | 0 | SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; |
999 | 0 | int elementIndex, elChanIdx = 0, numCh = 0; |
1000 | |
|
1001 | 0 | for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel); |
1002 | 0 | elementIndex++) { |
1003 | 0 | SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex]; |
1004 | 0 | int c, elChannels; |
1005 | |
|
1006 | 0 | elChanIdx = 0; |
1007 | 0 | if (pSbrElement == NULL) break; |
1008 | | |
1009 | | /* Determine amount of channels for this element */ |
1010 | 0 | switch (pSbrElement->elementID) { |
1011 | 0 | case ID_CPE: |
1012 | 0 | elChannels = 2; |
1013 | 0 | break; |
1014 | 0 | case ID_LFE: |
1015 | 0 | case ID_SCE: |
1016 | 0 | elChannels = 1; |
1017 | 0 | break; |
1018 | 0 | case ID_NONE: |
1019 | 0 | default: |
1020 | 0 | elChannels = 0; |
1021 | 0 | break; |
1022 | 0 | } |
1023 | | |
1024 | | /* Limit with actual allocated element channels */ |
1025 | 0 | elChannels = fMin(elChannels, pSbrElement->nChannels); |
1026 | |
|
1027 | 0 | for (c = 0; (c < elChannels) && (numCh <= channel); c++) { |
1028 | 0 | if (pSbrElement->pSbrChannel[elChanIdx] != NULL) { |
1029 | 0 | numCh++; |
1030 | 0 | elChanIdx++; |
1031 | 0 | } |
1032 | 0 | } |
1033 | 0 | } |
1034 | 0 | elementIndex -= 1; |
1035 | 0 | elChanIdx -= 1; |
1036 | |
|
1037 | 0 | if (elChanIdx < 0 || elementIndex < 0) { |
1038 | 0 | return NULL; |
1039 | 0 | } |
1040 | | |
1041 | 0 | if (self->pSbrElement[elementIndex] != NULL) { |
1042 | 0 | if (self->pSbrElement[elementIndex]->pSbrChannel[elChanIdx] != NULL) { |
1043 | 0 | pSbrDrcChannelData = &self->pSbrElement[elementIndex] |
1044 | 0 | ->pSbrChannel[elChanIdx] |
1045 | 0 | ->SbrDec.sbrDrcChannel; |
1046 | 0 | } |
1047 | 0 | } |
1048 | |
|
1049 | 0 | return (pSbrDrcChannelData); |
1050 | 0 | } |
1051 | | |
1052 | | SBR_ERROR sbrDecoder_drcFeedChannel(HANDLE_SBRDECODER self, INT ch, |
1053 | | UINT numBands, FIXP_DBL *pNextFact_mag, |
1054 | | INT nextFact_exp, |
1055 | | SHORT drcInterpolationScheme, |
1056 | 0 | UCHAR winSequence, USHORT *pBandTop) { |
1057 | 0 | SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; |
1058 | 0 | int band, isValidData = 0; |
1059 | |
|
1060 | 0 | if (self == NULL) { |
1061 | 0 | return SBRDEC_NOT_INITIALIZED; |
1062 | 0 | } |
1063 | 0 | if (ch > (8) || pNextFact_mag == NULL) { |
1064 | 0 | return SBRDEC_SET_PARAM_FAIL; |
1065 | 0 | } |
1066 | | |
1067 | | /* Search for gain values different to 1.0f */ |
1068 | 0 | for (band = 0; band < (int)numBands; band += 1) { |
1069 | 0 | if (!((pNextFact_mag[band] == FL2FXCONST_DBL(0.5)) && |
1070 | 0 | (nextFact_exp == 1)) && |
1071 | 0 | !((pNextFact_mag[band] == (FIXP_DBL)MAXVAL_DBL) && |
1072 | 0 | (nextFact_exp == 0))) { |
1073 | 0 | isValidData = 1; |
1074 | 0 | break; |
1075 | 0 | } |
1076 | 0 | } |
1077 | | |
1078 | | /* Find the right SBR channel */ |
1079 | 0 | pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch); |
1080 | |
|
1081 | 0 | if (pSbrDrcChannelData != NULL) { |
1082 | 0 | if (pSbrDrcChannelData->enable || |
1083 | 0 | isValidData) { /* Activate processing only with real and valid data */ |
1084 | 0 | int i; |
1085 | |
|
1086 | 0 | pSbrDrcChannelData->enable = 1; |
1087 | 0 | pSbrDrcChannelData->numBandsNext = numBands; |
1088 | |
|
1089 | 0 | pSbrDrcChannelData->winSequenceNext = winSequence; |
1090 | 0 | pSbrDrcChannelData->drcInterpolationSchemeNext = drcInterpolationScheme; |
1091 | 0 | pSbrDrcChannelData->nextFact_exp = nextFact_exp; |
1092 | |
|
1093 | 0 | for (i = 0; i < (int)numBands; i++) { |
1094 | 0 | pSbrDrcChannelData->bandTopNext[i] = pBandTop[i]; |
1095 | 0 | pSbrDrcChannelData->nextFact_mag[i] = pNextFact_mag[i]; |
1096 | 0 | } |
1097 | 0 | } |
1098 | 0 | } |
1099 | |
|
1100 | 0 | return SBRDEC_OK; |
1101 | 0 | } |
1102 | | |
1103 | 0 | void sbrDecoder_drcDisable(HANDLE_SBRDECODER self, INT ch) { |
1104 | 0 | SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; |
1105 | |
|
1106 | 0 | if ((self == NULL) || (ch > (8)) || (self->numSbrElements == 0) || |
1107 | 0 | (self->numSbrChannels == 0)) { |
1108 | 0 | return; |
1109 | 0 | } |
1110 | | |
1111 | | /* Find the right SBR channel */ |
1112 | 0 | pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch); |
1113 | |
|
1114 | 0 | if (pSbrDrcChannelData != NULL) { |
1115 | 0 | sbrDecoder_drcInitChannel(pSbrDrcChannelData); |
1116 | 0 | } |
1117 | 0 | } |
1118 | | |
1119 | | SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, |
1120 | | UCHAR *pDrmBsBuffer, USHORT drmBsBufferSize, |
1121 | | int *count, int bsPayLen, int crcFlag, |
1122 | | MP4_ELEMENT_ID prevElement, int elementIndex, |
1123 | 0 | UINT acFlags, UINT acElFlags[]) { |
1124 | 0 | SBR_DECODER_ELEMENT *hSbrElement = NULL; |
1125 | 0 | HANDLE_SBR_HEADER_DATA hSbrHeader = NULL; |
1126 | 0 | HANDLE_SBR_CHANNEL *pSbrChannel; |
1127 | |
|
1128 | 0 | SBR_FRAME_DATA *hFrameDataLeft = NULL; |
1129 | 0 | SBR_FRAME_DATA *hFrameDataRight = NULL; |
1130 | 0 | SBR_FRAME_DATA frameDataLeftCopy; |
1131 | 0 | SBR_FRAME_DATA frameDataRightCopy; |
1132 | |
|
1133 | 0 | SBR_ERROR errorStatus = SBRDEC_OK; |
1134 | 0 | SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; |
1135 | |
|
1136 | 0 | INT startPos = FDKgetValidBits(hBs); |
1137 | 0 | FDK_CRCINFO crcInfo; |
1138 | 0 | INT crcReg = 0; |
1139 | 0 | USHORT sbrCrc = 0; |
1140 | 0 | UINT crcPoly; |
1141 | 0 | UINT crcStartValue = 0; |
1142 | 0 | UINT crcLen; |
1143 | |
|
1144 | 0 | HANDLE_FDK_BITSTREAM hBsOriginal = hBs; |
1145 | 0 | FDK_BITSTREAM bsBwd; |
1146 | |
|
1147 | 0 | const int fGlobalIndependencyFlag = acFlags & AC_INDEP; |
1148 | 0 | const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC; |
1149 | 0 | const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES; |
1150 | 0 | int stereo; |
1151 | 0 | int fDoDecodeSbrData = 1; |
1152 | 0 | int alignBits = 0; |
1153 | |
|
1154 | 0 | int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0; |
1155 | |
|
1156 | 0 | if (*count <= 0) { |
1157 | 0 | setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); |
1158 | 0 | return SBRDEC_OK; |
1159 | 0 | } |
1160 | | |
1161 | | /* SBR sanity checks */ |
1162 | 0 | if (self == NULL) { |
1163 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
1164 | 0 | goto bail; |
1165 | 0 | } |
1166 | | |
1167 | | /* Reverse bits of DRM SBR payload */ |
1168 | 0 | if ((self->flags & SBRDEC_SYNTAX_DRM) && *count > 0) { |
1169 | 0 | int dataBytes, dataBits; |
1170 | |
|
1171 | 0 | FDK_ASSERT(drmBsBufferSize >= (512)); |
1172 | 0 | dataBits = *count; |
1173 | |
|
1174 | 0 | if (dataBits > ((512) * 8)) { |
1175 | | /* do not flip more data than needed */ |
1176 | 0 | dataBits = (512) * 8; |
1177 | 0 | } |
1178 | |
|
1179 | 0 | dataBytes = (dataBits + 7) >> 3; |
1180 | |
|
1181 | 0 | int j; |
1182 | |
|
1183 | 0 | if ((j = (int)FDKgetValidBits(hBs)) != 8) { |
1184 | 0 | FDKpushBiDirectional(hBs, (j - 8)); |
1185 | 0 | } |
1186 | |
|
1187 | 0 | j = 0; |
1188 | 0 | for (; dataBytes > 0; dataBytes--) { |
1189 | 0 | int i; |
1190 | 0 | UCHAR tmpByte; |
1191 | 0 | UCHAR buffer = 0x00; |
1192 | |
|
1193 | 0 | tmpByte = (UCHAR)FDKreadBits(hBs, 8); |
1194 | 0 | for (i = 0; i < 4; i++) { |
1195 | 0 | int shift = 2 * i + 1; |
1196 | 0 | buffer |= (tmpByte & (0x08 >> i)) << shift; |
1197 | 0 | buffer |= (tmpByte & (0x10 << i)) >> shift; |
1198 | 0 | } |
1199 | 0 | pDrmBsBuffer[j++] = buffer; |
1200 | 0 | FDKpushBack(hBs, 16); |
1201 | 0 | } |
1202 | |
|
1203 | 0 | FDKinitBitStream(&bsBwd, pDrmBsBuffer, (512), dataBits, BS_READER); |
1204 | | |
1205 | | /* Use reversed data */ |
1206 | 0 | hBs = &bsBwd; |
1207 | 0 | bsPayLen = *count; |
1208 | 0 | } |
1209 | | |
1210 | | /* Remember start position of SBR element */ |
1211 | 0 | startPos = FDKgetValidBits(hBs); |
1212 | | |
1213 | | /* SBR sanity checks */ |
1214 | 0 | if (self->pSbrElement[elementIndex] == NULL) { |
1215 | 0 | errorStatus = SBRDEC_NOT_INITIALIZED; |
1216 | 0 | goto bail; |
1217 | 0 | } |
1218 | 0 | hSbrElement = self->pSbrElement[elementIndex]; |
1219 | |
|
1220 | 0 | lastSlot = (hSbrElement->useFrameSlot > 0) ? hSbrElement->useFrameSlot - 1 |
1221 | 0 | : self->numDelayFrames; |
1222 | 0 | lastHdrSlot = hSbrElement->useHeaderSlot[lastSlot]; |
1223 | 0 | thisHdrSlot = getHeaderSlot( |
1224 | 0 | hSbrElement->useFrameSlot, |
1225 | 0 | hSbrElement->useHeaderSlot); /* Get a free header slot not used by |
1226 | | frames not processed yet. */ |
1227 | | |
1228 | | /* Assign the free slot to store a new header if there is one. */ |
1229 | 0 | hSbrHeader = &self->sbrHeader[elementIndex][thisHdrSlot]; |
1230 | |
|
1231 | 0 | pSbrChannel = hSbrElement->pSbrChannel; |
1232 | 0 | stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; |
1233 | |
|
1234 | 0 | hFrameDataLeft = &self->pSbrElement[elementIndex] |
1235 | 0 | ->pSbrChannel[0] |
1236 | 0 | ->frameData[hSbrElement->useFrameSlot]; |
1237 | 0 | if (stereo) { |
1238 | 0 | hFrameDataRight = &self->pSbrElement[elementIndex] |
1239 | 0 | ->pSbrChannel[1] |
1240 | 0 | ->frameData[hSbrElement->useFrameSlot]; |
1241 | 0 | } |
1242 | | |
1243 | | /* store frameData; new parsed frameData possibly corrupted */ |
1244 | 0 | FDKmemcpy(&frameDataLeftCopy, hFrameDataLeft, sizeof(SBR_FRAME_DATA)); |
1245 | 0 | if (stereo) { |
1246 | 0 | FDKmemcpy(&frameDataRightCopy, hFrameDataRight, sizeof(SBR_FRAME_DATA)); |
1247 | 0 | } |
1248 | | |
1249 | | /* reset PS flag; will be set after PS was found */ |
1250 | 0 | self->flags &= ~SBRDEC_PS_DECODED; |
1251 | |
|
1252 | 0 | if (hSbrHeader->status & SBRDEC_HDR_STAT_UPDATE) { |
1253 | | /* Got a new header from extern (e.g. from an ASC) */ |
1254 | 0 | headerStatus = HEADER_OK; |
1255 | 0 | hSbrHeader->status &= ~SBRDEC_HDR_STAT_UPDATE; |
1256 | 0 | } else if (thisHdrSlot != lastHdrSlot) { |
1257 | | /* Copy the last header into this slot otherwise the |
1258 | | header compare will trigger more HEADER_RESETs than needed. */ |
1259 | 0 | copySbrHeader(hSbrHeader, &self->sbrHeader[elementIndex][lastHdrSlot]); |
1260 | 0 | } |
1261 | | |
1262 | | /* |
1263 | | Check if bit stream data is valid and matches the element context |
1264 | | */ |
1265 | 0 | if (((prevElement != ID_SCE) && (prevElement != ID_CPE)) || |
1266 | 0 | prevElement != hSbrElement->elementID) { |
1267 | | /* In case of LFE we also land here, since there is no LFE SBR element (do |
1268 | | * upsampling only) */ |
1269 | 0 | fDoDecodeSbrData = 0; |
1270 | 0 | } |
1271 | |
|
1272 | 0 | if (fDoDecodeSbrData) { |
1273 | 0 | if ((INT)FDKgetValidBits(hBs) <= 0) { |
1274 | 0 | fDoDecodeSbrData = 0; |
1275 | 0 | } |
1276 | 0 | } |
1277 | | |
1278 | | /* |
1279 | | SBR CRC-check |
1280 | | */ |
1281 | 0 | if (fDoDecodeSbrData) { |
1282 | 0 | if (crcFlag) { |
1283 | 0 | switch (self->coreCodec) { |
1284 | 0 | case AOT_DRM_AAC: |
1285 | 0 | case AOT_DRM_SURROUND: |
1286 | 0 | crcPoly = 0x001d; |
1287 | 0 | crcLen = 8; |
1288 | 0 | crcStartValue = 0x000000ff; |
1289 | 0 | break; |
1290 | 0 | default: |
1291 | 0 | crcPoly = 0x0633; |
1292 | 0 | crcLen = 10; |
1293 | 0 | crcStartValue = 0x00000000; |
1294 | 0 | break; |
1295 | 0 | } |
1296 | 0 | sbrCrc = (USHORT)FDKreadBits(hBs, crcLen); |
1297 | | /* Setup CRC decoder */ |
1298 | 0 | FDKcrcInit(&crcInfo, crcPoly, crcStartValue, crcLen); |
1299 | | /* Start CRC region */ |
1300 | 0 | crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); |
1301 | 0 | } |
1302 | 0 | } /* if (fDoDecodeSbrData) */ |
1303 | | |
1304 | | /* |
1305 | | Read in the header data and issue a reset if change occured |
1306 | | */ |
1307 | 0 | if (fDoDecodeSbrData) { |
1308 | 0 | int sbrHeaderPresent; |
1309 | |
|
1310 | 0 | if (self->flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) { |
1311 | 0 | SBR_HEADER_DATA_BS_INFO newSbrInfo; |
1312 | 0 | int sbrInfoPresent; |
1313 | |
|
1314 | 0 | if (bs_interTes) { |
1315 | 0 | self->flags |= SBRDEC_USAC_ITES; |
1316 | 0 | } else { |
1317 | 0 | self->flags &= ~SBRDEC_USAC_ITES; |
1318 | 0 | } |
1319 | |
|
1320 | 0 | if (fGlobalIndependencyFlag) { |
1321 | 0 | self->flags |= SBRDEC_USAC_INDEP; |
1322 | 0 | sbrInfoPresent = 1; |
1323 | 0 | sbrHeaderPresent = 1; |
1324 | 0 | } else { |
1325 | 0 | self->flags &= ~SBRDEC_USAC_INDEP; |
1326 | 0 | sbrInfoPresent = FDKreadBit(hBs); |
1327 | 0 | if (sbrInfoPresent) { |
1328 | 0 | sbrHeaderPresent = FDKreadBit(hBs); |
1329 | 0 | } else { |
1330 | 0 | sbrHeaderPresent = 0; |
1331 | 0 | } |
1332 | 0 | } |
1333 | |
|
1334 | 0 | if (sbrInfoPresent) { |
1335 | 0 | newSbrInfo.ampResolution = FDKreadBit(hBs); |
1336 | 0 | newSbrInfo.xover_band = FDKreadBits(hBs, 4); |
1337 | 0 | newSbrInfo.sbr_preprocessing = FDKreadBit(hBs); |
1338 | 0 | if (bs_pvc) { |
1339 | 0 | newSbrInfo.pvc_mode = FDKreadBits(hBs, 2); |
1340 | | /* bs_pvc_mode: 0 -> no PVC, 1 -> PVC mode 1, 2 -> PVC mode 2, 3 -> |
1341 | | * reserved */ |
1342 | 0 | if (newSbrInfo.pvc_mode > 2) { |
1343 | 0 | headerStatus = HEADER_ERROR; |
1344 | 0 | } |
1345 | 0 | if (stereo && newSbrInfo.pvc_mode > 0) { |
1346 | | /* bs_pvc is always transmitted but pvc_mode is set to zero in case |
1347 | | * of stereo SBR. The config might be wrong but we cannot tell for |
1348 | | * sure. */ |
1349 | 0 | newSbrInfo.pvc_mode = 0; |
1350 | 0 | } |
1351 | 0 | } else { |
1352 | 0 | newSbrInfo.pvc_mode = 0; |
1353 | 0 | } |
1354 | 0 | if (headerStatus != HEADER_ERROR) { |
1355 | 0 | if (FDKmemcmp(&hSbrHeader->bs_info, &newSbrInfo, |
1356 | 0 | sizeof(SBR_HEADER_DATA_BS_INFO))) { |
1357 | | /* in case of ampResolution and preprocessing change no full reset |
1358 | | * required */ |
1359 | | /* HEADER reset would trigger HBE transposer reset which breaks |
1360 | | * eSbr_3_Eaa.mp4 */ |
1361 | 0 | if ((hSbrHeader->bs_info.pvc_mode != newSbrInfo.pvc_mode) || |
1362 | 0 | (hSbrHeader->bs_info.xover_band != newSbrInfo.xover_band)) { |
1363 | 0 | headerStatus = HEADER_RESET; |
1364 | 0 | } else { |
1365 | 0 | headerStatus = HEADER_OK; |
1366 | 0 | } |
1367 | |
|
1368 | 0 | hSbrHeader->bs_info = newSbrInfo; |
1369 | 0 | } else { |
1370 | 0 | headerStatus = HEADER_OK; |
1371 | 0 | } |
1372 | 0 | } |
1373 | 0 | } |
1374 | 0 | if (headerStatus == HEADER_ERROR) { |
1375 | | /* Corrupt SBR info data, do not decode and switch to UPSAMPLING */ |
1376 | 0 | hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING |
1377 | 0 | ? UPSAMPLING |
1378 | 0 | : hSbrHeader->syncState; |
1379 | 0 | fDoDecodeSbrData = 0; |
1380 | 0 | sbrHeaderPresent = 0; |
1381 | 0 | } |
1382 | |
|
1383 | 0 | if (sbrHeaderPresent && fDoDecodeSbrData) { |
1384 | 0 | int useDfltHeader; |
1385 | |
|
1386 | 0 | useDfltHeader = FDKreadBit(hBs); |
1387 | |
|
1388 | 0 | if (useDfltHeader) { |
1389 | 0 | sbrHeaderPresent = 0; |
1390 | 0 | if (FDKmemcmp(&hSbrHeader->bs_data, &hSbrHeader->bs_dflt, |
1391 | 0 | sizeof(SBR_HEADER_DATA_BS)) || |
1392 | 0 | hSbrHeader->syncState != SBR_ACTIVE) { |
1393 | 0 | hSbrHeader->bs_data = hSbrHeader->bs_dflt; |
1394 | 0 | headerStatus = HEADER_RESET; |
1395 | 0 | } |
1396 | 0 | } |
1397 | 0 | } |
1398 | 0 | } else { |
1399 | 0 | sbrHeaderPresent = FDKreadBit(hBs); |
1400 | 0 | } |
1401 | |
|
1402 | 0 | if (sbrHeaderPresent) { |
1403 | 0 | headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 1, 0); |
1404 | 0 | } |
1405 | |
|
1406 | 0 | if (headerStatus == HEADER_RESET) { |
1407 | 0 | errorStatus = sbrDecoder_HeaderUpdate( |
1408 | 0 | self, hSbrHeader, headerStatus, pSbrChannel, hSbrElement->nChannels); |
1409 | |
|
1410 | 0 | if (errorStatus == SBRDEC_OK) { |
1411 | 0 | hSbrHeader->syncState = SBR_HEADER; |
1412 | 0 | } else { |
1413 | 0 | hSbrHeader->syncState = SBR_NOT_INITIALIZED; |
1414 | 0 | headerStatus = HEADER_ERROR; |
1415 | 0 | } |
1416 | 0 | } |
1417 | |
|
1418 | 0 | if (errorStatus != SBRDEC_OK) { |
1419 | 0 | fDoDecodeSbrData = 0; |
1420 | 0 | } |
1421 | 0 | } /* if (fDoDecodeSbrData) */ |
1422 | | |
1423 | | /* |
1424 | | Print debugging output only if state has changed |
1425 | | */ |
1426 | | |
1427 | | /* read frame data */ |
1428 | 0 | if ((hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) { |
1429 | 0 | int sbrFrameOk; |
1430 | | /* read the SBR element data */ |
1431 | 0 | if (!stereo && (self->hParametricStereoDec != NULL)) { |
1432 | | /* update slot index for PS bitstream parsing */ |
1433 | 0 | self->hParametricStereoDec->bsLastSlot = |
1434 | 0 | self->hParametricStereoDec->bsReadSlot; |
1435 | 0 | self->hParametricStereoDec->bsReadSlot = hSbrElement->useFrameSlot; |
1436 | 0 | } |
1437 | 0 | sbrFrameOk = sbrGetChannelElement( |
1438 | 0 | hSbrHeader, hFrameDataLeft, (stereo) ? hFrameDataRight : NULL, |
1439 | 0 | &pSbrChannel[0]->prevFrameData, |
1440 | 0 | pSbrChannel[0]->SbrDec.PvcStaticData.pvc_mode_last, hBs, |
1441 | 0 | (stereo) ? NULL : self->hParametricStereoDec, self->flags, |
1442 | 0 | self->pSbrElement[elementIndex]->transposerSettings.overlap); |
1443 | |
|
1444 | 0 | if (!sbrFrameOk) { |
1445 | 0 | fDoDecodeSbrData = 0; |
1446 | 0 | } else { |
1447 | 0 | INT valBits; |
1448 | |
|
1449 | 0 | if (bsPayLen > 0) { |
1450 | 0 | valBits = bsPayLen - ((INT)startPos - (INT)FDKgetValidBits(hBs)); |
1451 | 0 | } else { |
1452 | 0 | valBits = (INT)FDKgetValidBits(hBs); |
1453 | 0 | } |
1454 | | |
1455 | | /* sanity check of remaining bits */ |
1456 | 0 | if (valBits < 0) { |
1457 | 0 | fDoDecodeSbrData = 0; |
1458 | 0 | } else { |
1459 | 0 | switch (self->coreCodec) { |
1460 | 0 | case AOT_SBR: |
1461 | 0 | case AOT_PS: |
1462 | 0 | case AOT_AAC_LC: { |
1463 | | /* This sanity check is only meaningful with General Audio |
1464 | | * bitstreams */ |
1465 | 0 | alignBits = valBits & 0x7; |
1466 | |
|
1467 | 0 | if (valBits > alignBits) { |
1468 | 0 | fDoDecodeSbrData = 0; |
1469 | 0 | } |
1470 | 0 | } break; |
1471 | 0 | default: |
1472 | | /* No sanity check available */ |
1473 | 0 | break; |
1474 | 0 | } |
1475 | 0 | } |
1476 | 0 | } |
1477 | 0 | } else { |
1478 | | /* The returned bit count will not be the actual payload size since we did |
1479 | | not parse the frame data. Return an error so that the caller can react |
1480 | | respectively. */ |
1481 | 0 | errorStatus = SBRDEC_PARSE_ERROR; |
1482 | 0 | } |
1483 | | |
1484 | 0 | if (crcFlag && (hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) { |
1485 | 0 | FDKpushFor(hBs, alignBits); |
1486 | 0 | FDKcrcEndReg(&crcInfo, hBs, crcReg); /* End CRC region */ |
1487 | 0 | FDKpushBack(hBs, alignBits); |
1488 | | /* Check CRC */ |
1489 | 0 | if ((FDKcrcGetCRC(&crcInfo) ^ crcStartValue) != sbrCrc) { |
1490 | 0 | fDoDecodeSbrData = 0; |
1491 | 0 | if (headerStatus != HEADER_NOT_PRESENT) { |
1492 | 0 | headerStatus = HEADER_ERROR; |
1493 | 0 | hSbrHeader->syncState = SBR_NOT_INITIALIZED; |
1494 | 0 | } |
1495 | 0 | } |
1496 | 0 | } |
1497 | |
|
1498 | 0 | if (!fDoDecodeSbrData) { |
1499 | | /* Set error flag for this slot to trigger concealment */ |
1500 | 0 | setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); |
1501 | | /* restore old frameData for concealment */ |
1502 | 0 | FDKmemcpy(hFrameDataLeft, &frameDataLeftCopy, sizeof(SBR_FRAME_DATA)); |
1503 | 0 | if (stereo) { |
1504 | 0 | FDKmemcpy(hFrameDataRight, &frameDataRightCopy, sizeof(SBR_FRAME_DATA)); |
1505 | 0 | } |
1506 | 0 | errorStatus = SBRDEC_PARSE_ERROR; |
1507 | 0 | } else { |
1508 | | /* Everything seems to be ok so clear the error flag */ |
1509 | 0 | setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_OK); |
1510 | 0 | } |
1511 | |
|
1512 | 0 | if (!stereo) { |
1513 | | /* Turn coupling off explicitely to avoid access to absent right frame data |
1514 | | that might occur with corrupt bitstreams. */ |
1515 | 0 | hFrameDataLeft->coupling = COUPLING_OFF; |
1516 | 0 | } |
1517 | |
|
1518 | 0 | bail: |
1519 | |
|
1520 | 0 | if (self != NULL) { |
1521 | 0 | if (self->flags & SBRDEC_SYNTAX_DRM) { |
1522 | 0 | hBs = hBsOriginal; |
1523 | 0 | } |
1524 | |
|
1525 | 0 | if (errorStatus != SBRDEC_NOT_INITIALIZED) { |
1526 | 0 | int useOldHdr = |
1527 | 0 | ((headerStatus == HEADER_NOT_PRESENT) || |
1528 | 0 | (headerStatus == HEADER_ERROR) || |
1529 | 0 | (headerStatus == HEADER_RESET && errorStatus == SBRDEC_PARSE_ERROR)) |
1530 | 0 | ? 1 |
1531 | 0 | : 0; |
1532 | |
|
1533 | 0 | if (!useOldHdr && (thisHdrSlot != lastHdrSlot) && (hSbrHeader != NULL)) { |
1534 | 0 | useOldHdr |= |
1535 | 0 | (compareSbrHeader(hSbrHeader, |
1536 | 0 | &self->sbrHeader[elementIndex][lastHdrSlot]) == 0) |
1537 | 0 | ? 1 |
1538 | 0 | : 0; |
1539 | 0 | } |
1540 | |
|
1541 | 0 | if (hSbrElement != NULL) { |
1542 | 0 | if (useOldHdr != 0) { |
1543 | | /* Use the old header for this frame */ |
1544 | 0 | hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot; |
1545 | 0 | } else { |
1546 | | /* Use the new header for this frame */ |
1547 | 0 | hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = thisHdrSlot; |
1548 | 0 | } |
1549 | | |
1550 | | /* Move frame pointer to the next slot which is up to be decoded/applied |
1551 | | * next */ |
1552 | 0 | hSbrElement->useFrameSlot = |
1553 | 0 | (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1); |
1554 | 0 | } |
1555 | 0 | } |
1556 | 0 | } |
1557 | |
|
1558 | 0 | *count -= startPos - (INT)FDKgetValidBits(hBs); |
1559 | |
|
1560 | 0 | return errorStatus; |
1561 | 0 | } |
1562 | | |
1563 | | /** |
1564 | | * \brief Render one SBR element into time domain signal. |
1565 | | * \param self SBR decoder handle |
1566 | | * \param timeData pointer to output buffer |
1567 | | * \param channelMapping pointer to UCHAR array where next 2 channel offsets are |
1568 | | * stored. |
1569 | | * \param elementIndex enumerating index of the SBR element to render. |
1570 | | * \param numInChannels number of channels from core coder. |
1571 | | * \param numOutChannels pointer to a location to return number of output |
1572 | | * channels. |
1573 | | * \param psPossible flag indicating if PS is possible or not. |
1574 | | * \return SBRDEC_OK if successfull, else error code |
1575 | | */ |
1576 | | static SBR_ERROR sbrDecoder_DecodeElement( |
1577 | | HANDLE_SBRDECODER self, LONG *input, LONG *timeData, const int timeDataSize, |
1578 | | const FDK_channelMapDescr *const mapDescr, const int mapIdx, |
1579 | | int channelIndex, const int elementIndex, const int numInChannels, |
1580 | 0 | int *numOutChannels, const int psPossible) { |
1581 | 0 | SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex]; |
1582 | 0 | HANDLE_SBR_CHANNEL *pSbrChannel = |
1583 | 0 | self->pSbrElement[elementIndex]->pSbrChannel; |
1584 | 0 | HANDLE_SBR_HEADER_DATA hSbrHeader = |
1585 | 0 | &self->sbrHeader[elementIndex] |
1586 | 0 | [hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]]; |
1587 | 0 | HANDLE_PS_DEC h_ps_d = self->hParametricStereoDec; |
1588 | | |
1589 | | /* get memory for frame data from scratch */ |
1590 | 0 | SBR_FRAME_DATA *hFrameDataLeft = NULL; |
1591 | 0 | SBR_FRAME_DATA *hFrameDataRight = NULL; |
1592 | |
|
1593 | 0 | SBR_ERROR errorStatus = SBRDEC_OK; |
1594 | |
|
1595 | 0 | INT strideOut, offset0 = 255, offset0_block = 0, offset1 = 255, |
1596 | 0 | offset1_block = 0; |
1597 | 0 | INT codecFrameSize = self->codecFrameSize; |
1598 | |
|
1599 | 0 | int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; |
1600 | 0 | int numElementChannels = |
1601 | 0 | hSbrElement |
1602 | 0 | ->nChannels; /* Number of channels of the current SBR element */ |
1603 | |
|
1604 | 0 | hFrameDataLeft = |
1605 | 0 | &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; |
1606 | 0 | if (stereo) { |
1607 | 0 | hFrameDataRight = |
1608 | 0 | &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; |
1609 | 0 | } |
1610 | |
|
1611 | 0 | if (self->flags & SBRDEC_FLUSH) { |
1612 | 0 | if (self->numFlushedFrames > self->numDelayFrames) { |
1613 | 0 | int hdrIdx; |
1614 | | /* No valid SBR payload available, hence switch to upsampling (in all |
1615 | | * headers) */ |
1616 | 0 | for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) { |
1617 | 0 | if (self->sbrHeader[elementIndex][hdrIdx].syncState > UPSAMPLING) { |
1618 | 0 | self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; |
1619 | 0 | } |
1620 | 0 | } |
1621 | 0 | } else { |
1622 | | /* Move frame pointer to the next slot which is up to be decoded/applied |
1623 | | * next */ |
1624 | 0 | hSbrElement->useFrameSlot = |
1625 | 0 | (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1); |
1626 | | /* Update header and frame data pointer because they have already been set |
1627 | | */ |
1628 | 0 | hSbrHeader = |
1629 | 0 | &self->sbrHeader[elementIndex] |
1630 | 0 | [hSbrElement |
1631 | 0 | ->useHeaderSlot[hSbrElement->useFrameSlot]]; |
1632 | 0 | hFrameDataLeft = |
1633 | 0 | &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; |
1634 | 0 | if (stereo) { |
1635 | 0 | hFrameDataRight = |
1636 | 0 | &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; |
1637 | 0 | } |
1638 | 0 | } |
1639 | 0 | } |
1640 | | |
1641 | | /* Update the header error flag */ |
1642 | 0 | hSbrHeader->frameErrorFlag = |
1643 | 0 | hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot]; |
1644 | | |
1645 | | /* |
1646 | | Prepare filterbank for upsampling if no valid bit stream data is available. |
1647 | | */ |
1648 | 0 | if (hSbrHeader->syncState == SBR_NOT_INITIALIZED) { |
1649 | 0 | errorStatus = |
1650 | 0 | initHeaderData(hSbrHeader, self->sampleRateIn, self->sampleRateOut, |
1651 | 0 | self->downscaleFactor, codecFrameSize, self->flags, |
1652 | 0 | 1 /* SET_DEFAULT_HDR */ |
1653 | 0 | ); |
1654 | |
|
1655 | 0 | if (errorStatus != SBRDEC_OK) { |
1656 | 0 | return errorStatus; |
1657 | 0 | } |
1658 | | |
1659 | 0 | hSbrHeader->syncState = UPSAMPLING; |
1660 | |
|
1661 | 0 | errorStatus = sbrDecoder_HeaderUpdate(self, hSbrHeader, HEADER_NOT_PRESENT, |
1662 | 0 | pSbrChannel, hSbrElement->nChannels); |
1663 | |
|
1664 | 0 | if (errorStatus != SBRDEC_OK) { |
1665 | 0 | hSbrHeader->syncState = SBR_NOT_INITIALIZED; |
1666 | 0 | return errorStatus; |
1667 | 0 | } |
1668 | 0 | } |
1669 | | |
1670 | | /* reset */ |
1671 | 0 | if (hSbrHeader->status & SBRDEC_HDR_STAT_RESET) { |
1672 | 0 | int ch; |
1673 | 0 | int applySbrProc = (hSbrHeader->syncState == SBR_ACTIVE || |
1674 | 0 | (hSbrHeader->frameErrorFlag == 0 && |
1675 | 0 | hSbrHeader->syncState == SBR_HEADER)); |
1676 | 0 | for (ch = 0; ch < numElementChannels; ch++) { |
1677 | 0 | SBR_ERROR errorStatusTmp = SBRDEC_OK; |
1678 | |
|
1679 | 0 | errorStatusTmp = resetSbrDec( |
1680 | 0 | &pSbrChannel[ch]->SbrDec, hSbrHeader, &pSbrChannel[ch]->prevFrameData, |
1681 | 0 | self->synDownsampleFac, self->flags, pSbrChannel[ch]->frameData); |
1682 | |
|
1683 | 0 | if (errorStatusTmp != SBRDEC_OK) { |
1684 | 0 | hSbrHeader->syncState = UPSAMPLING; |
1685 | 0 | } |
1686 | 0 | } |
1687 | 0 | if (applySbrProc) { |
1688 | 0 | hSbrHeader->status &= ~SBRDEC_HDR_STAT_RESET; |
1689 | 0 | } |
1690 | 0 | } |
1691 | | |
1692 | | /* decoding */ |
1693 | 0 | if ((hSbrHeader->syncState == SBR_ACTIVE) || |
1694 | 0 | ((hSbrHeader->syncState == SBR_HEADER) && |
1695 | 0 | (hSbrHeader->frameErrorFlag == 0))) { |
1696 | 0 | errorStatus = SBRDEC_OK; |
1697 | |
|
1698 | 0 | decodeSbrData(hSbrHeader, hFrameDataLeft, &pSbrChannel[0]->prevFrameData, |
1699 | 0 | (stereo) ? hFrameDataRight : NULL, |
1700 | 0 | (stereo) ? &pSbrChannel[1]->prevFrameData : NULL); |
1701 | | |
1702 | | /* Now we have a full parameter set and can do parameter |
1703 | | based concealment instead of plain upsampling. */ |
1704 | 0 | hSbrHeader->syncState = SBR_ACTIVE; |
1705 | 0 | } |
1706 | |
|
1707 | 0 | if (timeDataSize < |
1708 | 0 | hSbrHeader->numberTimeSlots * hSbrHeader->timeStep * |
1709 | 0 | self->pQmfDomain->globalConf.nBandsSynthesis * |
1710 | 0 | (psPossible ? fMax(2, numInChannels) : numInChannels)) { |
1711 | 0 | return SBRDEC_OUTPUT_BUFFER_TOO_SMALL; |
1712 | 0 | } |
1713 | | |
1714 | 0 | { |
1715 | 0 | self->flags &= ~SBRDEC_PS_DECODED; |
1716 | 0 | C_ALLOC_SCRATCH_START(pPsScratch, struct PS_DEC_COEFFICIENTS, 1) |
1717 | | |
1718 | | /* decode PS data if available */ |
1719 | 0 | if (h_ps_d != NULL && psPossible && (hSbrHeader->syncState == SBR_ACTIVE)) { |
1720 | 0 | int applyPs = 1; |
1721 | | |
1722 | | /* define which frame delay line slot to process */ |
1723 | 0 | h_ps_d->processSlot = hSbrElement->useFrameSlot; |
1724 | |
|
1725 | 0 | applyPs = DecodePs(h_ps_d, hSbrHeader->frameErrorFlag, pPsScratch); |
1726 | 0 | self->flags |= (applyPs) ? SBRDEC_PS_DECODED : 0; |
1727 | 0 | } |
1728 | |
|
1729 | 0 | offset0 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex, mapIdx); |
1730 | 0 | offset0_block = offset0 * codecFrameSize; |
1731 | 0 | if (stereo || psPossible) { |
1732 | | /* the value of offset1 only matters if the condition is true, however if |
1733 | | it is not true channelIndex+1 may exceed the channel map resutling in an |
1734 | | error, though the value of offset1 is actually meaningless. This is |
1735 | | prevented here. */ |
1736 | 0 | offset1 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex + 1, mapIdx); |
1737 | 0 | offset1_block = offset1 * codecFrameSize; |
1738 | 0 | } |
1739 | | /* Set strides for reading and writing */ |
1740 | 0 | if (psPossible) |
1741 | 0 | strideOut = (numInChannels < 2) ? 2 : numInChannels; |
1742 | 0 | else |
1743 | 0 | strideOut = numInChannels; |
1744 | | |
1745 | | /* use same buffers for left and right channel and apply PS per timeslot */ |
1746 | | /* Process left channel */ |
1747 | 0 | sbr_dec(&pSbrChannel[0]->SbrDec, input + offset0_block, timeData + offset0, |
1748 | 0 | (self->flags & SBRDEC_PS_DECODED) ? &pSbrChannel[1]->SbrDec : NULL, |
1749 | 0 | timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft, |
1750 | 0 | &pSbrChannel[0]->prevFrameData, |
1751 | 0 | (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags, |
1752 | 0 | codecFrameSize, self->sbrInDataHeadroom); |
1753 | |
|
1754 | 0 | if (stereo) { |
1755 | | /* Process right channel */ |
1756 | 0 | sbr_dec(&pSbrChannel[1]->SbrDec, input + offset1_block, |
1757 | 0 | timeData + offset1, NULL, NULL, strideOut, hSbrHeader, |
1758 | 0 | hFrameDataRight, &pSbrChannel[1]->prevFrameData, |
1759 | 0 | (hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags, |
1760 | 0 | codecFrameSize, self->sbrInDataHeadroom); |
1761 | 0 | } |
1762 | |
|
1763 | 0 | C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1) |
1764 | 0 | } |
1765 | |
|
1766 | 0 | if (h_ps_d != NULL) { |
1767 | | /* save PS status for next run */ |
1768 | 0 | h_ps_d->psDecodedPrv = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0; |
1769 | 0 | } |
1770 | |
|
1771 | 0 | if (psPossible && !(self->flags & SBRDEC_SKIP_QMF_SYN)) { |
1772 | 0 | FDK_ASSERT(strideOut > 1); |
1773 | 0 | if (!(self->flags & SBRDEC_PS_DECODED)) { |
1774 | | /* A decoder which is able to decode PS has to produce a stereo output |
1775 | | * even if no PS data is available. */ |
1776 | | /* So copy left channel to right channel. */ |
1777 | 0 | int copyFrameSize = |
1778 | 0 | codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels; |
1779 | 0 | copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels; |
1780 | 0 | LONG *ptr; |
1781 | 0 | INT i; |
1782 | 0 | FDK_ASSERT(strideOut == 2); |
1783 | | |
1784 | 0 | ptr = timeData; |
1785 | 0 | for (i = copyFrameSize >> 1; i--;) { |
1786 | 0 | LONG tmp; /* This temporal variable is required because some compilers |
1787 | | can't do *ptr++ = *ptr++ correctly. */ |
1788 | 0 | tmp = *ptr++; |
1789 | 0 | *ptr++ = tmp; |
1790 | 0 | tmp = *ptr++; |
1791 | 0 | *ptr++ = tmp; |
1792 | 0 | } |
1793 | 0 | } |
1794 | 0 | *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */ |
1795 | 0 | } |
1796 | | |
1797 | 0 | return errorStatus; |
1798 | 0 | } |
1799 | | |
1800 | | SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData, |
1801 | | const int timeDataSize, int *numChannels, |
1802 | | int *sampleRate, |
1803 | | const FDK_channelMapDescr *const mapDescr, |
1804 | | const int mapIdx, const int coreDecodedOk, |
1805 | | UCHAR *psDecoded, const INT inDataHeadroom, |
1806 | 0 | INT *outDataHeadroom) { |
1807 | 0 | SBR_ERROR errorStatus = SBRDEC_OK; |
1808 | |
|
1809 | 0 | int psPossible; |
1810 | 0 | int sbrElementNum; |
1811 | 0 | int numCoreChannels; |
1812 | 0 | int numSbrChannels = 0; |
1813 | |
|
1814 | 0 | if ((self == NULL) || (timeData == NULL) || (numChannels == NULL) || |
1815 | 0 | (sampleRate == NULL) || (psDecoded == NULL) || |
1816 | 0 | !FDK_chMapDescr_isValid(mapDescr)) { |
1817 | 0 | return SBRDEC_INVALID_ARGUMENT; |
1818 | 0 | } |
1819 | | |
1820 | 0 | psPossible = *psDecoded; |
1821 | 0 | numCoreChannels = *numChannels; |
1822 | 0 | if (numCoreChannels <= 0) { |
1823 | 0 | return SBRDEC_INVALID_ARGUMENT; |
1824 | 0 | } |
1825 | | |
1826 | 0 | if (self->numSbrElements < 1) { |
1827 | | /* exit immediately to avoid access violations */ |
1828 | 0 | return SBRDEC_NOT_INITIALIZED; |
1829 | 0 | } |
1830 | | |
1831 | | /* Sanity check of allocated SBR elements. */ |
1832 | 0 | for (sbrElementNum = 0; sbrElementNum < self->numSbrElements; |
1833 | 0 | sbrElementNum++) { |
1834 | 0 | if (self->pSbrElement[sbrElementNum] == NULL) { |
1835 | 0 | return SBRDEC_NOT_INITIALIZED; |
1836 | 0 | } |
1837 | 0 | } |
1838 | | |
1839 | 0 | if (self->numSbrElements != 1 || self->pSbrElement[0]->elementID != ID_SCE) { |
1840 | 0 | psPossible = 0; |
1841 | 0 | } |
1842 | |
|
1843 | 0 | self->sbrInDataHeadroom = inDataHeadroom; |
1844 | 0 | *outDataHeadroom = (INT)(8); |
1845 | | |
1846 | | /* Make sure that even if no SBR data was found/parsed *psDecoded is returned |
1847 | | * 1 if psPossible was 0. */ |
1848 | 0 | if (psPossible == 0) { |
1849 | 0 | self->flags &= ~SBRDEC_PS_DECODED; |
1850 | 0 | } |
1851 | | |
1852 | | /* replaces channel based reset inside sbr_dec() */ |
1853 | 0 | if (((self->flags & SBRDEC_LOW_POWER) ? 1 : 0) != |
1854 | 0 | ((self->pQmfDomain->globalConf.flags & QMF_FLAG_LP) ? 1 : 0)) { |
1855 | 0 | if (self->flags & SBRDEC_LOW_POWER) { |
1856 | 0 | self->pQmfDomain->globalConf.flags |= QMF_FLAG_LP; |
1857 | 0 | self->pQmfDomain->globalConf.flags_requested |= QMF_FLAG_LP; |
1858 | 0 | } else { |
1859 | 0 | self->pQmfDomain->globalConf.flags &= ~QMF_FLAG_LP; |
1860 | 0 | self->pQmfDomain->globalConf.flags_requested &= ~QMF_FLAG_LP; |
1861 | 0 | } |
1862 | 0 | if (FDK_QmfDomain_InitFilterBank(self->pQmfDomain, QMF_FLAG_KEEP_STATES)) { |
1863 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
1864 | 0 | } |
1865 | 0 | } |
1866 | 0 | if (self->numSbrChannels > self->pQmfDomain->globalConf.nInputChannels) { |
1867 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
1868 | 0 | } |
1869 | | |
1870 | 0 | if (self->flags & SBRDEC_FLUSH) { |
1871 | | /* flushing is signalized, hence increment the flush frame counter */ |
1872 | 0 | self->numFlushedFrames++; |
1873 | 0 | } else { |
1874 | | /* no flushing is signalized, hence reset the flush frame counter */ |
1875 | 0 | self->numFlushedFrames = 0; |
1876 | 0 | } |
1877 | | |
1878 | | /* Loop over SBR elements */ |
1879 | 0 | for (sbrElementNum = 0; sbrElementNum < self->numSbrElements; |
1880 | 0 | sbrElementNum++) { |
1881 | 0 | int numElementChan; |
1882 | |
|
1883 | 0 | if (psPossible && |
1884 | 0 | self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) { |
1885 | | /* Disable PS and try decoding SBR mono. */ |
1886 | 0 | psPossible = 0; |
1887 | 0 | } |
1888 | |
|
1889 | 0 | numElementChan = |
1890 | 0 | (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1; |
1891 | | |
1892 | | /* If core signal is bad then force upsampling */ |
1893 | 0 | if (!coreDecodedOk) { |
1894 | 0 | setFrameErrorFlag(self->pSbrElement[sbrElementNum], FRAME_ERROR_ALLSLOTS); |
1895 | 0 | } |
1896 | |
|
1897 | 0 | errorStatus = sbrDecoder_DecodeElement( |
1898 | 0 | self, input, timeData, timeDataSize, mapDescr, mapIdx, numSbrChannels, |
1899 | 0 | sbrElementNum, |
1900 | 0 | numCoreChannels, /* is correct even for USC SCI==2 case */ |
1901 | 0 | &numElementChan, psPossible); |
1902 | |
|
1903 | 0 | if (errorStatus != SBRDEC_OK) { |
1904 | 0 | goto bail; |
1905 | 0 | } |
1906 | | |
1907 | 0 | numSbrChannels += numElementChan; |
1908 | |
|
1909 | 0 | if (numSbrChannels >= numCoreChannels) { |
1910 | 0 | break; |
1911 | 0 | } |
1912 | 0 | } |
1913 | | |
1914 | | /* Update numChannels and samplerate */ |
1915 | | /* Do not mess with output channels in case of USAC. numSbrChannels != |
1916 | | * numChannels for stereoConfigIndex == 2 */ |
1917 | 0 | if (!(self->flags & SBRDEC_SYNTAX_USAC)) { |
1918 | 0 | *numChannels = numSbrChannels; |
1919 | 0 | } |
1920 | 0 | *sampleRate = self->sampleRateOut; |
1921 | 0 | *psDecoded = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0; |
1922 | | |
1923 | | /* Clear reset and flush flag because everything seems to be done |
1924 | | * successfully. */ |
1925 | 0 | self->flags &= ~SBRDEC_FORCE_RESET; |
1926 | 0 | self->flags &= ~SBRDEC_FLUSH; |
1927 | |
|
1928 | 0 | bail: |
1929 | |
|
1930 | 0 | return errorStatus; |
1931 | 0 | } |
1932 | | |
1933 | 23 | SBR_ERROR sbrDecoder_Close(HANDLE_SBRDECODER *pSelf) { |
1934 | 23 | HANDLE_SBRDECODER self = *pSelf; |
1935 | 23 | int i; |
1936 | | |
1937 | 23 | if (self != NULL) { |
1938 | 23 | if (self->hParametricStereoDec != NULL) { |
1939 | 0 | DeletePsDec(&self->hParametricStereoDec); |
1940 | 0 | } |
1941 | | |
1942 | 207 | for (i = 0; i < (8); i++) { |
1943 | 184 | sbrDecoder_DestroyElement(self, i); |
1944 | 184 | } |
1945 | | |
1946 | 23 | FreeRam_SbrDecoder(pSelf); |
1947 | 23 | } |
1948 | | |
1949 | 23 | return SBRDEC_OK; |
1950 | 23 | } |
1951 | | |
1952 | 0 | INT sbrDecoder_GetLibInfo(LIB_INFO *info) { |
1953 | 0 | int i; |
1954 | |
|
1955 | 0 | if (info == NULL) { |
1956 | 0 | return -1; |
1957 | 0 | } |
1958 | | |
1959 | | /* search for next free tab */ |
1960 | 0 | for (i = 0; i < FDK_MODULE_LAST; i++) { |
1961 | 0 | if (info[i].module_id == FDK_NONE) break; |
1962 | 0 | } |
1963 | 0 | if (i == FDK_MODULE_LAST) return -1; |
1964 | 0 | info += i; |
1965 | |
|
1966 | 0 | info->module_id = FDK_SBRDEC; |
1967 | 0 | info->version = |
1968 | 0 | LIB_VERSION(SBRDECODER_LIB_VL0, SBRDECODER_LIB_VL1, SBRDECODER_LIB_VL2); |
1969 | 0 | LIB_VERSION_STRING(info); |
1970 | 0 | info->build_date = SBRDECODER_LIB_BUILD_DATE; |
1971 | 0 | info->build_time = SBRDECODER_LIB_BUILD_TIME; |
1972 | 0 | info->title = SBRDECODER_LIB_TITLE; |
1973 | | |
1974 | | /* Set flags */ |
1975 | 0 | info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_LP | CAPF_SBR_PS_MPEG | |
1976 | 0 | CAPF_SBR_DRM_BS | CAPF_SBR_CONCEALMENT | CAPF_SBR_DRC | |
1977 | 0 | CAPF_SBR_ELD_DOWNSCALE | CAPF_SBR_HBEHQ; |
1978 | | /* End of flags */ |
1979 | |
|
1980 | 0 | return 0; |
1981 | 0 | } |
1982 | | |
1983 | 0 | UINT sbrDecoder_GetDelay(const HANDLE_SBRDECODER self) { |
1984 | 0 | UINT outputDelay = 0; |
1985 | |
|
1986 | 0 | if (self != NULL) { |
1987 | 0 | UINT flags = self->flags; |
1988 | | |
1989 | | /* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */ |
1990 | | |
1991 | | /* Are we initialized? */ |
1992 | 0 | if ((self->numSbrChannels > 0) && (self->numSbrElements > 0)) { |
1993 | | /* Add QMF synthesis delay */ |
1994 | 0 | if ((flags & SBRDEC_ELD_GRID) && IS_LOWDELAY(self->coreCodec)) { |
1995 | | /* Low delay SBR: */ |
1996 | 0 | if (!(flags & SBRDEC_SKIP_QMF_SYN)) { |
1997 | 0 | outputDelay += |
1998 | 0 | (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */ |
1999 | 0 | if (flags & SBRDEC_LD_MPS_QMF) { |
2000 | 0 | outputDelay += 32; |
2001 | 0 | } |
2002 | 0 | } |
2003 | 0 | } else if (!IS_USAC(self->coreCodec)) { |
2004 | | /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...) |
2005 | | * branch: */ |
2006 | 0 | outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962; |
2007 | 0 | if (flags & SBRDEC_SKIP_QMF_SYN) { |
2008 | 0 | outputDelay -= 257; /* QMF synthesis */ |
2009 | 0 | } |
2010 | 0 | } |
2011 | 0 | } |
2012 | 0 | } |
2013 | |
|
2014 | 0 | return (outputDelay); |
2015 | 0 | } |