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 /*********************** MPEG surround encoder library *************************
96
97 Author(s):
98
99 Description: Encoder Library Interface
100 Bitstream Writer
101
102 *******************************************************************************/
103
104 /* Includes ******************************************************************/
105 #include "sacenc_bitstream.h"
106 #include "sacenc_const.h"
107
108 #include "genericStds.h"
109 #include "common_fix.h"
110
111 #include "FDK_matrixCalloc.h"
112 #include "sacenc_nlc_enc.h"
113
114 /* Defines *******************************************************************/
115 #define MAX_FREQ_RES_INDEX 8
116 #define MAX_SAMPLING_FREQUENCY_INDEX 13
117 #define SAMPLING_FREQUENCY_INDEX_ESCAPE 15
118
119 /* Data Types ****************************************************************/
120 typedef struct {
121 SCHAR cld_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS];
122 SCHAR icc_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS];
123 UCHAR quantCoarseCldPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
124 UCHAR quantCoarseIccPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
125
126 } PREV_OTTDATA;
127
128 typedef struct {
129 PREV_OTTDATA prevOttData;
130
131 } STATIC_SPATIALFRAME;
132
133 typedef struct BSF_INSTANCE {
134 SPATIALSPECIFICCONFIG spatialSpecificConfig;
135 SPATIALFRAME frame;
136 STATIC_SPATIALFRAME prevFrameData;
137
138 } BSF_INSTANCE;
139
140 /* Constants *****************************************************************/
141 static const INT SampleRateTable[MAX_SAMPLING_FREQUENCY_INDEX] = {
142 96000, 88200, 64000, 48000, 44100, 32000, 24000,
143 22050, 16000, 12000, 11025, 8000, 7350};
144
145 static const UCHAR FreqResBinTable_LD[MAX_FREQ_RES_INDEX] = {0, 23, 15, 12,
146 9, 7, 5, 4};
147 static const UCHAR FreqResStrideTable_LD[] = {1, 2, 5, 23};
148
149 /* Function / Class Declarations *********************************************/
150
151 /* Function / Class Definition ***********************************************/
DuplicateLosslessData(const INT startBox,const INT stopBox,const LOSSLESSDATA * const hLosslessDataFrom,const INT setFrom,LOSSLESSDATA * const hLosslessDataTo,const INT setTo)152 static FDK_SACENC_ERROR DuplicateLosslessData(
153 const INT startBox, const INT stopBox,
154 const LOSSLESSDATA *const hLosslessDataFrom, const INT setFrom,
155 LOSSLESSDATA *const hLosslessDataTo, const INT setTo) {
156 FDK_SACENC_ERROR error = SACENC_OK;
157
158 if ((NULL == hLosslessDataFrom) || (NULL == hLosslessDataTo)) {
159 error = SACENC_INVALID_HANDLE;
160 } else {
161 int i;
162
163 for (i = startBox; i < stopBox; i++) {
164 hLosslessDataTo->bsXXXDataMode[i][setTo] =
165 hLosslessDataFrom->bsXXXDataMode[i][setFrom];
166 hLosslessDataTo->bsDataPair[i][setTo] =
167 hLosslessDataFrom->bsDataPair[i][setFrom];
168 hLosslessDataTo->bsQuantCoarseXXX[i][setTo] =
169 hLosslessDataFrom->bsQuantCoarseXXX[i][setFrom];
170 hLosslessDataTo->bsFreqResStrideXXX[i][setTo] =
171 hLosslessDataFrom->bsFreqResStrideXXX[i][setFrom];
172 }
173 }
174 return error;
175 }
176
fdk_sacenc_duplicateParameterSet(const SPATIALFRAME * const hFrom,const INT setFrom,SPATIALFRAME * const hTo,const INT setTo)177 FDK_SACENC_ERROR fdk_sacenc_duplicateParameterSet(
178 const SPATIALFRAME *const hFrom, const INT setFrom, SPATIALFRAME *const hTo,
179 const INT setTo) {
180 FDK_SACENC_ERROR error = SACENC_OK;
181
182 if ((NULL == hFrom) || (NULL == hTo)) {
183 error = SACENC_INVALID_HANDLE;
184 } else {
185 int box;
186 /* Only Copy Parameter Set selective stuff */
187
188 /* OTT-Data */
189 for (box = 0; box < SACENC_MAX_NUM_BOXES; box++) {
190 FDKmemcpy(hTo->ottData.cld[box][setTo], hFrom->ottData.cld[box][setFrom],
191 sizeof(hFrom->ottData.cld[0][0]));
192 FDKmemcpy(hTo->ottData.icc[box][setTo], hFrom->ottData.icc[box][setFrom],
193 sizeof(hFrom->ottData.icc[0][0]));
194 }
195
196 /* LOSSLESSDATA */
197 DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->CLDLosslessData,
198 setFrom, &hTo->CLDLosslessData, setTo);
199 DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->ICCLosslessData,
200 setFrom, &hTo->ICCLosslessData, setTo);
201
202 } /* valid handle */
203
204 return error;
205 }
206
207 /* set frame defaults */
clearFrame(SPATIALFRAME * const pFrame)208 static void clearFrame(SPATIALFRAME *const pFrame) {
209 FDKmemclear(pFrame, sizeof(SPATIALFRAME));
210
211 pFrame->bsIndependencyFlag = 1;
212 pFrame->framingInfo.numParamSets = 1;
213 }
214
fine2coarse(SCHAR * const data,const DATA_TYPE dataType,const INT startBand,const INT numBands)215 static void fine2coarse(SCHAR *const data, const DATA_TYPE dataType,
216 const INT startBand, const INT numBands) {
217 int i;
218 if (dataType == t_CLD) {
219 for (i = startBand; i < startBand + numBands; i++) {
220 data[i] /= 2;
221 }
222 } else {
223 for (i = startBand; i < startBand + numBands; i++) {
224 data[i] >>= 1;
225 }
226 }
227 }
228
coarse2fine(SCHAR * const data,const DATA_TYPE dataType,const INT startBand,const INT numBands)229 static void coarse2fine(SCHAR *const data, const DATA_TYPE dataType,
230 const INT startBand, const INT numBands) {
231 int i;
232
233 for (i = startBand; i < startBand + numBands; i++) {
234 data[i] <<= 1;
235 }
236
237 if (dataType == t_CLD) {
238 for (i = startBand; i < startBand + numBands; i++) {
239 if (data[i] == -14) {
240 data[i] = -15;
241 } else if (data[i] == 14) {
242 data[i] = 15;
243 }
244 }
245 } /* (dataType == t_CLD) */
246 }
247
getBsFreqResStride(const INT index)248 static UCHAR getBsFreqResStride(const INT index) {
249 const UCHAR *pFreqResStrideTable = NULL;
250 int freqResStrideTableSize = 0;
251
252 pFreqResStrideTable = FreqResStrideTable_LD;
253 freqResStrideTableSize =
254 sizeof(FreqResStrideTable_LD) / sizeof(*FreqResStrideTable_LD);
255
256 return (((NULL != pFreqResStrideTable) && (index >= 0) &&
257 (index < freqResStrideTableSize))
258 ? pFreqResStrideTable[index]
259 : 1);
260 }
261
262 /* write data to bitstream */
ecData(HANDLE_FDK_BITSTREAM bitstream,SCHAR data[MAX_NUM_PARAMS][MAX_NUM_BINS],SCHAR oldData[MAX_NUM_BINS],UCHAR quantCoarseXXXprev[MAX_NUM_PARAMS],LOSSLESSDATA * const losslessData,const DATA_TYPE dataType,const INT paramIdx,const INT numParamSets,const INT independencyFlag,const INT startBand,const INT stopBand,const INT defaultValue)263 static void ecData(HANDLE_FDK_BITSTREAM bitstream,
264 SCHAR data[MAX_NUM_PARAMS][MAX_NUM_BINS],
265 SCHAR oldData[MAX_NUM_BINS],
266 UCHAR quantCoarseXXXprev[MAX_NUM_PARAMS],
267 LOSSLESSDATA *const losslessData, const DATA_TYPE dataType,
268 const INT paramIdx, const INT numParamSets,
269 const INT independencyFlag, const INT startBand,
270 const INT stopBand, const INT defaultValue) {
271 int ps, pb, strOffset, pbStride, dataBands, i;
272 int aStrides[MAX_NUM_BINS + 1] = {0};
273 SHORT cmpIdxData[2][MAX_NUM_BINS] = {{0}};
274 SHORT cmpOldData[MAX_NUM_BINS] = {0};
275
276 /* bsXXXDataMode */
277 if (independencyFlag || (losslessData->bsQuantCoarseXXX[paramIdx][0] !=
278 quantCoarseXXXprev[paramIdx])) {
279 losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE;
280 } else {
281 losslessData->bsXXXDataMode[paramIdx][0] = KEEP;
282 for (i = startBand; i < stopBand; i++) {
283 if (data[0][i] != oldData[i]) {
284 losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE;
285 break;
286 }
287 }
288 }
289
290 FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][0], 2);
291
292 for (ps = 1; ps < numParamSets; ps++) {
293 if (losslessData->bsQuantCoarseXXX[paramIdx][ps] !=
294 losslessData->bsQuantCoarseXXX[paramIdx][ps - 1]) {
295 losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE;
296 } else {
297 losslessData->bsXXXDataMode[paramIdx][ps] = KEEP;
298 for (i = startBand; i < stopBand; i++) {
299 if (data[ps][i] != data[ps - 1][i]) {
300 losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE;
301 break;
302 }
303 }
304 }
305
306 FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][ps], 2);
307 } /* for ps */
308
309 /* Create data pairs if possible */
310 for (ps = 0; ps < (numParamSets - 1); ps++) {
311 if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) {
312 /* Check if next parameter set is FINCOARSE */
313 if (losslessData->bsXXXDataMode[paramIdx][ps + 1] == FINECOARSE) {
314 /* We have to check if ps and ps+1 use the same bsXXXQuantMode */
315 /* and also have the same stride */
316 if ((losslessData->bsQuantCoarseXXX[paramIdx][ps + 1] ==
317 losslessData->bsQuantCoarseXXX[paramIdx][ps]) &&
318 (losslessData->bsFreqResStrideXXX[paramIdx][ps + 1] ==
319 losslessData->bsFreqResStrideXXX[paramIdx][ps])) {
320 losslessData->bsDataPair[paramIdx][ps] = 1;
321 losslessData->bsDataPair[paramIdx][ps + 1] = 1;
322
323 /* We have a data pair -> Jump to the ps after next ps*/
324 ps++;
325 continue;
326 }
327 }
328 /* dataMode of next ps is not FINECOARSE or does not use the same
329 * bsXXXQuantMode/stride */
330 /* -> no dataPair possible */
331 losslessData->bsDataPair[paramIdx][ps] = 0;
332
333 /* Initialize ps after next ps to Zero (only important for the last
334 * parameter set) */
335 losslessData->bsDataPair[paramIdx][ps + 1] = 0;
336 } else {
337 /* No FINECOARSE -> no data pair possible */
338 losslessData->bsDataPair[paramIdx][ps] = 0;
339
340 /* Initialize ps after next ps to Zero (only important for the last
341 * parameter set) */
342 losslessData->bsDataPair[paramIdx][ps + 1] = 0;
343 }
344 } /* for ps */
345
346 for (ps = 0; ps < numParamSets; ps++) {
347 if (losslessData->bsXXXDataMode[paramIdx][ps] == DEFAULT) {
348 /* Prepare old data */
349 for (i = startBand; i < stopBand; i++) {
350 oldData[i] = defaultValue;
351 }
352 quantCoarseXXXprev[paramIdx] = 0; /* Default data are always fine */
353 }
354
355 if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) {
356 FDKwriteBits(bitstream, losslessData->bsDataPair[paramIdx][ps], 1);
357 FDKwriteBits(bitstream, losslessData->bsQuantCoarseXXX[paramIdx][ps], 1);
358 FDKwriteBits(bitstream, losslessData->bsFreqResStrideXXX[paramIdx][ps],
359 2);
360
361 if (losslessData->bsQuantCoarseXXX[paramIdx][ps] !=
362 quantCoarseXXXprev[paramIdx]) {
363 if (quantCoarseXXXprev[paramIdx]) {
364 coarse2fine(oldData, dataType, startBand, stopBand - startBand);
365 } else {
366 fine2coarse(oldData, dataType, startBand, stopBand - startBand);
367 }
368 }
369
370 /* Handle strides */
371 pbStride =
372 getBsFreqResStride(losslessData->bsFreqResStrideXXX[paramIdx][ps]);
373 dataBands = (stopBand - startBand - 1) / pbStride + 1;
374
375 aStrides[0] = startBand;
376 for (pb = 1; pb <= dataBands; pb++) {
377 aStrides[pb] = aStrides[pb - 1] + pbStride;
378 }
379
380 strOffset = 0;
381 while (aStrides[dataBands] > stopBand) {
382 if (strOffset < dataBands) {
383 strOffset++;
384 }
385 for (i = strOffset; i <= dataBands; i++) {
386 aStrides[i]--;
387 }
388 } /* while */
389
390 for (pb = 0; pb < dataBands; pb++) {
391 cmpOldData[startBand + pb] = oldData[aStrides[pb]];
392 cmpIdxData[0][startBand + pb] = data[ps][aStrides[pb]];
393
394 if (losslessData->bsDataPair[paramIdx][ps]) {
395 cmpIdxData[1][startBand + pb] = data[ps + 1][aStrides[pb]];
396 }
397 } /* for pb*/
398
399 /* Finally encode */
400 if (losslessData->bsDataPair[paramIdx][ps]) {
401 fdk_sacenc_ecDataPairEnc(bitstream, cmpIdxData, cmpOldData, dataType, 0,
402 startBand, dataBands,
403 losslessData->bsQuantCoarseXXX[paramIdx][ps],
404 independencyFlag && (ps == 0));
405 } else {
406 fdk_sacenc_ecDataSingleEnc(bitstream, cmpIdxData, cmpOldData, dataType,
407 0, startBand, dataBands,
408 losslessData->bsQuantCoarseXXX[paramIdx][ps],
409 independencyFlag && (ps == 0));
410 }
411
412 /* Overwrite old data */
413 for (i = startBand; i < stopBand; i++) {
414 if (losslessData->bsDataPair[paramIdx][ps]) {
415 oldData[i] = data[ps + 1][i];
416 } else {
417 oldData[i] = data[ps][i];
418 }
419 }
420
421 quantCoarseXXXprev[paramIdx] =
422 losslessData->bsQuantCoarseXXX[paramIdx][ps];
423
424 /* Jump forward if we have encoded a data pair */
425 if (losslessData->bsDataPair[paramIdx][ps]) {
426 ps++;
427 }
428
429 } /* if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE ) */
430 } /* for ps */
431 }
432
433 /****************************************************************************/
434 /* Bitstream formatter interface functions */
435 /****************************************************************************/
getBsFreqResIndex(const INT numBands,INT * const pbsFreqResIndex)436 static FDK_SACENC_ERROR getBsFreqResIndex(const INT numBands,
437 INT *const pbsFreqResIndex) {
438 FDK_SACENC_ERROR error = SACENC_OK;
439
440 if (NULL == pbsFreqResIndex) {
441 error = SACENC_INVALID_HANDLE;
442 } else {
443 const UCHAR *pFreqResBinTable = FreqResBinTable_LD;
444 int i;
445 *pbsFreqResIndex = -1;
446
447 for (i = 0; i < MAX_FREQ_RES_INDEX; i++) {
448 if (numBands == pFreqResBinTable[i]) {
449 *pbsFreqResIndex = i;
450 break;
451 }
452 }
453 if (*pbsFreqResIndex < 0 || *pbsFreqResIndex >= MAX_FREQ_RES_INDEX) {
454 error = SACENC_INVALID_CONFIG;
455 }
456 }
457 return error;
458 }
459
getSamplingFrequencyIndex(const INT bsSamplingFrequency,INT * const pbsSamplingFrequencyIndex)460 static FDK_SACENC_ERROR getSamplingFrequencyIndex(
461 const INT bsSamplingFrequency, INT *const pbsSamplingFrequencyIndex) {
462 FDK_SACENC_ERROR error = SACENC_OK;
463
464 if (NULL == pbsSamplingFrequencyIndex) {
465 error = SACENC_INVALID_HANDLE;
466 } else {
467 int i;
468 *pbsSamplingFrequencyIndex = SAMPLING_FREQUENCY_INDEX_ESCAPE;
469
470 for (i = 0; i < MAX_SAMPLING_FREQUENCY_INDEX; i++) {
471 if (bsSamplingFrequency == SampleRateTable[i]) { /*spatial sampling rate*/
472 *pbsSamplingFrequencyIndex = i;
473 break;
474 }
475 }
476 }
477 return error;
478 }
479
480 /* destroy encoder instance */
fdk_sacenc_destroySpatialBitstreamEncoder(HANDLE_BSF_INSTANCE * selfPtr)481 FDK_SACENC_ERROR fdk_sacenc_destroySpatialBitstreamEncoder(
482 HANDLE_BSF_INSTANCE *selfPtr) {
483 FDK_SACENC_ERROR error = SACENC_OK;
484
485 if ((selfPtr == NULL) || (*selfPtr == NULL)) {
486 error = SACENC_INVALID_HANDLE;
487 } else {
488 if (*selfPtr != NULL) {
489 FDK_FREE_MEMORY_1D(*selfPtr);
490 }
491 }
492 return error;
493 }
494
495 /* create encoder instance */
fdk_sacenc_createSpatialBitstreamEncoder(HANDLE_BSF_INSTANCE * selfPtr)496 FDK_SACENC_ERROR fdk_sacenc_createSpatialBitstreamEncoder(
497 HANDLE_BSF_INSTANCE *selfPtr) {
498 FDK_SACENC_ERROR error = SACENC_OK;
499
500 if (NULL == selfPtr) {
501 error = SACENC_INVALID_HANDLE;
502 } else {
503 /* allocate encoder struct */
504 FDK_ALLOCATE_MEMORY_1D(*selfPtr, 1, BSF_INSTANCE);
505 }
506 return error;
507
508 bail:
509 fdk_sacenc_destroySpatialBitstreamEncoder(selfPtr);
510 return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
511 }
512
513 /* init encoder instance */
fdk_sacenc_initSpatialBitstreamEncoder(HANDLE_BSF_INSTANCE selfPtr)514 FDK_SACENC_ERROR fdk_sacenc_initSpatialBitstreamEncoder(
515 HANDLE_BSF_INSTANCE selfPtr) {
516 FDK_SACENC_ERROR error = SACENC_OK;
517
518 if (selfPtr == NULL) {
519 error = SACENC_INVALID_HANDLE;
520 } else {
521 /* init/clear */
522 clearFrame(&selfPtr->frame);
523
524 } /* valid handle */
525 return error;
526 }
527
528 /* get SpatialSpecificConfig struct */
fdk_sacenc_getSpatialSpecificConfig(HANDLE_BSF_INSTANCE selfPtr)529 SPATIALSPECIFICCONFIG *fdk_sacenc_getSpatialSpecificConfig(
530 HANDLE_BSF_INSTANCE selfPtr) {
531 return ((selfPtr == NULL) ? NULL : &(selfPtr->spatialSpecificConfig));
532 }
533
534 /* write SpatialSpecificConfig to stream */
fdk_sacenc_writeSpatialSpecificConfig(SPATIALSPECIFICCONFIG * const spatialSpecificConfig,UCHAR * const pOutputBuffer,const INT outputBufferSize,INT * const pnOutputBits)535 FDK_SACENC_ERROR fdk_sacenc_writeSpatialSpecificConfig(
536 SPATIALSPECIFICCONFIG *const spatialSpecificConfig,
537 UCHAR *const pOutputBuffer, const INT outputBufferSize,
538 INT *const pnOutputBits) {
539 FDK_SACENC_ERROR error = SACENC_OK;
540 INT bsSamplingFrequencyIndex = 0;
541 INT bsFreqRes = 0;
542
543 if ((spatialSpecificConfig == NULL) || (pOutputBuffer == NULL) ||
544 (pnOutputBits == NULL)) {
545 error = SACENC_INVALID_HANDLE;
546 } else {
547 FDK_BITSTREAM bitstream;
548
549 /* Find FreqRes */
550 if (SACENC_OK != (error = getBsFreqResIndex(spatialSpecificConfig->numBands,
551 &bsFreqRes)))
552 goto bail;
553
554 /* Find SamplingFrequencyIndex */
555 if (SACENC_OK != (error = getSamplingFrequencyIndex(
556 spatialSpecificConfig->bsSamplingFrequency,
557 &bsSamplingFrequencyIndex)))
558 goto bail;
559
560 /* bind extern buffer to bitstream handle */
561 FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
562
563 /****************************************************************************/
564 /* write to bitstream */
565
566 FDKwriteBits(&bitstream, bsSamplingFrequencyIndex, 4);
567
568 if (bsSamplingFrequencyIndex == 15) {
569 FDKwriteBits(&bitstream, spatialSpecificConfig->bsSamplingFrequency, 24);
570 }
571
572 FDKwriteBits(&bitstream, spatialSpecificConfig->bsFrameLength, 5);
573
574 FDKwriteBits(&bitstream, bsFreqRes, 3);
575 FDKwriteBits(&bitstream, spatialSpecificConfig->bsTreeConfig, 4);
576 FDKwriteBits(&bitstream, spatialSpecificConfig->bsQuantMode, 2);
577
578 FDKwriteBits(&bitstream, 0, 1); /* bsArbitraryDownmix */
579
580 FDKwriteBits(&bitstream, spatialSpecificConfig->bsFixedGainDMX, 3);
581
582 FDKwriteBits(&bitstream, TEMPSHAPE_OFF, 2);
583 FDKwriteBits(&bitstream, spatialSpecificConfig->bsDecorrConfig, 2);
584
585 FDKbyteAlign(&bitstream, 0); /* byte alignment */
586
587 /* return number of valid bits in bitstream */
588 if ((*pnOutputBits = FDKgetValidBits(&bitstream)) >
589 (outputBufferSize * 8)) {
590 error = SACENC_INVALID_CONFIG;
591 goto bail;
592 }
593
594 /* terminate buffer with alignment */
595 FDKbyteAlign(&bitstream, 0);
596
597 } /* valid handle */
598
599 bail:
600 return error;
601 }
602
603 /* get SpatialFrame struct */
fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr,const SPATIALFRAME_TYPE frameType)604 SPATIALFRAME *fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr,
605 const SPATIALFRAME_TYPE frameType) {
606 int idx = -1;
607
608 switch (frameType) {
609 case READ_SPATIALFRAME:
610 case WRITE_SPATIALFRAME:
611 idx = 0;
612 break;
613 default:
614 idx = -1; /* invalid configuration */
615 } /* switch frameType */
616
617 return (((selfPtr == NULL) || (idx == -1)) ? NULL : &selfPtr->frame);
618 }
619
writeFramingInfo(HANDLE_FDK_BITSTREAM hBitstream,const FRAMINGINFO * const pFramingInfo,const INT frameLength)620 static FDK_SACENC_ERROR writeFramingInfo(HANDLE_FDK_BITSTREAM hBitstream,
621 const FRAMINGINFO *const pFramingInfo,
622 const INT frameLength) {
623 FDK_SACENC_ERROR error = SACENC_OK;
624
625 if ((hBitstream == NULL) || (pFramingInfo == NULL)) {
626 error = SACENC_INVALID_HANDLE;
627 } else {
628 FDKwriteBits(hBitstream, pFramingInfo->bsFramingType, 1);
629 FDKwriteBits(hBitstream, pFramingInfo->numParamSets - 1, 1);
630
631 if (pFramingInfo->bsFramingType) {
632 int ps = 0;
633 int numParamSets = pFramingInfo->numParamSets;
634
635 {
636 for (ps = 0; ps < numParamSets; ps++) {
637 int bitsParamSlot = 0;
638 while ((1 << bitsParamSlot) < (frameLength + 1)) bitsParamSlot++;
639 if (bitsParamSlot > 0)
640 FDKwriteBits(hBitstream, pFramingInfo->bsParamSlots[ps],
641 bitsParamSlot);
642 }
643 }
644 } /* pFramingInfo->bsFramingType */
645 } /* valid handle */
646
647 return error;
648 }
649
writeSmgData(HANDLE_FDK_BITSTREAM hBitstream,const SMGDATA * const pSmgData,const INT numParamSets,const INT dataBands)650 static FDK_SACENC_ERROR writeSmgData(HANDLE_FDK_BITSTREAM hBitstream,
651 const SMGDATA *const pSmgData,
652 const INT numParamSets,
653 const INT dataBands) {
654 FDK_SACENC_ERROR error = SACENC_OK;
655
656 if ((hBitstream == NULL) || (pSmgData == NULL)) {
657 error = SACENC_INVALID_HANDLE;
658 } else {
659 int i, j;
660
661 for (i = 0; i < numParamSets; i++) {
662 FDKwriteBits(hBitstream, pSmgData->bsSmoothMode[i], 2);
663
664 if (pSmgData->bsSmoothMode[i] >= 2) {
665 FDKwriteBits(hBitstream, pSmgData->bsSmoothTime[i], 2);
666 }
667 if (pSmgData->bsSmoothMode[i] == 3) {
668 const int stride = getBsFreqResStride(pSmgData->bsFreqResStride[i]);
669 FDKwriteBits(hBitstream, pSmgData->bsFreqResStride[i], 2);
670 for (j = 0; j < dataBands; j += stride) {
671 FDKwriteBits(hBitstream, pSmgData->bsSmgData[i][j], 1);
672 }
673 }
674 } /* for i */
675 } /* valid handle */
676
677 return error;
678 }
679
writeOttData(HANDLE_FDK_BITSTREAM hBitstream,PREV_OTTDATA * const pPrevOttData,OTTDATA * const pOttData,const OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES],LOSSLESSDATA * const pCLDLosslessData,LOSSLESSDATA * const pICCLosslessData,const INT numOttBoxes,const INT numBands,const INT numParamSets,const INT bsIndependencyFlag)680 static FDK_SACENC_ERROR writeOttData(
681 HANDLE_FDK_BITSTREAM hBitstream, PREV_OTTDATA *const pPrevOttData,
682 OTTDATA *const pOttData, const OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES],
683 LOSSLESSDATA *const pCLDLosslessData, LOSSLESSDATA *const pICCLosslessData,
684 const INT numOttBoxes, const INT numBands, const INT numParamSets,
685 const INT bsIndependencyFlag) {
686 FDK_SACENC_ERROR error = SACENC_OK;
687
688 if ((hBitstream == NULL) || (pPrevOttData == NULL) || (pOttData == NULL) ||
689 (ottConfig == NULL) || (pCLDLosslessData == NULL) ||
690 (pICCLosslessData == NULL)) {
691 error = SACENC_INVALID_HANDLE;
692 } else {
693 int i;
694 for (i = 0; i < numOttBoxes; i++) {
695 ecData(hBitstream, pOttData->cld[i], pPrevOttData->cld_old[i],
696 pPrevOttData->quantCoarseCldPrev[i], pCLDLosslessData, t_CLD, i,
697 numParamSets, bsIndependencyFlag, 0, ottConfig[i].bsOttBands, 15);
698 }
699 {
700 for (i = 0; i < numOttBoxes; i++) {
701 {
702 ecData(hBitstream, pOttData->icc[i], pPrevOttData->icc_old[i],
703 pPrevOttData->quantCoarseIccPrev[i], pICCLosslessData, t_ICC,
704 i, numParamSets, bsIndependencyFlag, 0, numBands, 0);
705 }
706 } /* for i */
707 }
708 } /* valid handle */
709
710 return error;
711 }
712
713 /* write extension frame data to stream */
WriteSpatialExtensionFrame(HANDLE_FDK_BITSTREAM bitstream,HANDLE_BSF_INSTANCE self)714 static FDK_SACENC_ERROR WriteSpatialExtensionFrame(
715 HANDLE_FDK_BITSTREAM bitstream, HANDLE_BSF_INSTANCE self) {
716 FDK_SACENC_ERROR error = SACENC_OK;
717
718 if ((bitstream == NULL) || (self == NULL)) {
719 error = SACENC_INVALID_HANDLE;
720 } else {
721 FDKbyteAlign(bitstream, 0);
722 } /* valid handle */
723
724 return error;
725 }
726
727 /* write frame data to stream */
fdk_sacenc_writeSpatialFrame(UCHAR * const pOutputBuffer,const INT outputBufferSize,INT * const pnOutputBits,HANDLE_BSF_INSTANCE selfPtr)728 FDK_SACENC_ERROR fdk_sacenc_writeSpatialFrame(UCHAR *const pOutputBuffer,
729 const INT outputBufferSize,
730 INT *const pnOutputBits,
731 HANDLE_BSF_INSTANCE selfPtr) {
732 FDK_SACENC_ERROR error = SACENC_OK;
733
734 if ((pOutputBuffer == NULL) || (pnOutputBits == NULL) || (selfPtr == NULL)) {
735 error = SACENC_INVALID_HANDLE;
736 } else {
737 SPATIALFRAME *frame = NULL;
738 SPATIALSPECIFICCONFIG *config = NULL;
739 FDK_BITSTREAM bitstream;
740
741 int i, j, numParamSets, numOttBoxes;
742
743 if ((NULL ==
744 (frame = fdk_sacenc_getSpatialFrame(selfPtr, READ_SPATIALFRAME))) ||
745 (NULL == (config = &(selfPtr->spatialSpecificConfig)))) {
746 error = SACENC_INVALID_HANDLE;
747 goto bail;
748 }
749
750 numOttBoxes = selfPtr->spatialSpecificConfig.treeDescription.numOttBoxes;
751
752 numParamSets = frame->framingInfo.numParamSets;
753
754 if (frame->bUseBBCues) {
755 for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) {
756 /* If a transient was detected, force only the second ps broad band */
757 if (numParamSets == 1) {
758 frame->CLDLosslessData.bsFreqResStrideXXX[i][0] = 3;
759 frame->ICCLosslessData.bsFreqResStrideXXX[i][0] = 3;
760 } else {
761 for (j = 1; j < MAX_NUM_PARAMS; j++) {
762 frame->CLDLosslessData.bsFreqResStrideXXX[i][j] = 3;
763 frame->ICCLosslessData.bsFreqResStrideXXX[i][j] = 3;
764 }
765 }
766 }
767 } /* frame->bUseBBCues */
768
769 /* bind extern buffer to bitstream handle */
770 FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
771
772 if (SACENC_OK != (error = writeFramingInfo(
773 &bitstream, &(frame->framingInfo),
774 selfPtr->spatialSpecificConfig.bsFrameLength))) {
775 goto bail;
776 }
777
778 /* write bsIndependencyFlag */
779 FDKwriteBits(&bitstream, frame->bsIndependencyFlag, 1);
780
781 /* write spatial data to bitstream */
782 if (SACENC_OK !=
783 (error = writeOttData(&bitstream, &selfPtr->prevFrameData.prevOttData,
784 &frame->ottData, config->ottConfig,
785 &frame->CLDLosslessData, &frame->ICCLosslessData,
786 numOttBoxes, config->numBands, numParamSets,
787 frame->bsIndependencyFlag))) {
788 goto bail;
789 }
790 if (SACENC_OK != (error = writeSmgData(&bitstream, &frame->smgData,
791 numParamSets, config->numBands))) {
792 goto bail;
793 }
794
795 /* byte alignment */
796 FDKbyteAlign(&bitstream, 0);
797
798 /* Write SpatialExtensionFrame */
799 if (SACENC_OK !=
800 (error = WriteSpatialExtensionFrame(&bitstream, selfPtr))) {
801 goto bail;
802 }
803
804 if (NULL ==
805 (frame = fdk_sacenc_getSpatialFrame(selfPtr, WRITE_SPATIALFRAME))) {
806 error = SACENC_INVALID_HANDLE;
807 goto bail;
808 }
809
810 clearFrame(frame);
811
812 /* return number of valid bits in bitstream */
813 if ((*pnOutputBits = FDKgetValidBits(&bitstream)) >
814 (outputBufferSize * 8)) {
815 error = SACENC_INVALID_CONFIG;
816 goto bail;
817 }
818
819 /* terminate buffer with alignment */
820 FDKbyteAlign(&bitstream, 0);
821
822 } /* valid handle */
823
824 bail:
825 return error;
826 }
827