• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** SBR encoder library ******************************
96 
97    Author(s):   N. Rettelbach
98 
99    Description: Parametric Stereo bitstream encoder
100 
101 *******************************************************************************/
102 
103 #include "ps_bitenc.h"
104 
105 #include "ps_main.h"
106 
FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream,UINT value,const UINT numberOfBits)107 static inline UCHAR FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream,
108                                            UINT value,
109                                            const UINT numberOfBits) {
110   /* hBitStream == NULL happens here intentionally */
111   if (hBitStream != NULL) {
112     FDKwriteBits(hBitStream, value, numberOfBits);
113   }
114   return numberOfBits;
115 }
116 
117 #define SI_SBR_EXTENSION_SIZE_BITS 4
118 #define SI_SBR_EXTENSION_ESC_COUNT_BITS 8
119 #define SI_SBR_EXTENSION_ID_BITS 2
120 #define EXTENSION_ID_PS_CODING 2
121 #define PS_EXT_ID_V0 0
122 
123 static const INT iidDeltaCoarse_Offset = 14;
124 static const INT iidDeltaCoarse_MaxVal = 28;
125 static const INT iidDeltaFine_Offset = 30;
126 static const INT iidDeltaFine_MaxVal = 60;
127 
128 /* PS Stereo Huffmantable: iidDeltaFreqCoarse */
129 static const UINT iidDeltaFreqCoarse_Length[] = {
130     17, 17, 17, 17, 16, 15, 13, 10, 9,  7,  6,  5,  4,  3, 1,
131     3,  4,  5,  6,  6,  8,  11, 13, 14, 14, 15, 17, 18, 18};
132 static const UINT iidDeltaFreqCoarse_Code[] = {
133     0x0001fffb, 0x0001fffc, 0x0001fffd, 0x0001fffa, 0x0000fffc, 0x00007ffc,
134     0x00001ffd, 0x000003fe, 0x000001fe, 0x0000007e, 0x0000003c, 0x0000001d,
135     0x0000000d, 0x00000005, 0000000000, 0x00000004, 0x0000000c, 0x0000001c,
136     0x0000003d, 0x0000003e, 0x000000fe, 0x000007fe, 0x00001ffc, 0x00003ffc,
137     0x00003ffd, 0x00007ffd, 0x0001fffe, 0x0003fffe, 0x0003ffff};
138 
139 /* PS Stereo Huffmantable: iidDeltaFreqFine */
140 static const UINT iidDeltaFreqFine_Length[] = {
141     18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15,
142     14, 14, 13, 12, 12, 11, 10, 10, 8,  7,  6,  5,  4,  3,  1,  3,
143     4,  5,  6,  7,  8,  9,  10, 11, 11, 12, 13, 14, 14, 15, 16, 16,
144     17, 17, 18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
145 static const UINT iidDeltaFreqFine_Code[] = {
146     0x0001feb4, 0x0001feb5, 0x0001fd76, 0x0001fd77, 0x0001fd74, 0x0001fd75,
147     0x0001fe8a, 0x0001fe8b, 0x0001fe88, 0x0000fe80, 0x0001feb6, 0x0000fe82,
148     0x0000feb8, 0x00007f42, 0x00007fae, 0x00003faf, 0x00001fd1, 0x00001fe9,
149     0x00000fe9, 0x000007ea, 0x000007fb, 0x000003fb, 0x000001fb, 0x000001ff,
150     0x0000007c, 0x0000003c, 0x0000001c, 0x0000000c, 0000000000, 0x00000001,
151     0x00000001, 0x00000002, 0x00000001, 0x0000000d, 0x0000001d, 0x0000003d,
152     0x0000007d, 0x000000fc, 0x000001fc, 0x000003fc, 0x000003f4, 0x000007eb,
153     0x00000fea, 0x00001fea, 0x00001fd6, 0x00003fd0, 0x00007faf, 0x00007f43,
154     0x0000feb9, 0x0000fe83, 0x0001feb7, 0x0000fe81, 0x0001fe89, 0x0001fe8e,
155     0x0001fe8f, 0x0001fe8c, 0x0001fe8d, 0x0001feb2, 0x0001feb3, 0x0001feb0,
156     0x0001feb1};
157 
158 /* PS Stereo Huffmantable: iidDeltaTimeCoarse */
159 static const UINT iidDeltaTimeCoarse_Length[] = {
160     19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8,  6,  4,  2, 1,
161     3,  5,  7,  9,  11, 13, 14, 17, 19, 20, 20, 20, 20, 20};
162 static const UINT iidDeltaTimeCoarse_Code[] = {
163     0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9, 0x000ffffa,
164     0x0001fffd, 0x00007ffe, 0x00000ffe, 0x000003fe, 0x000000fe, 0x0000003e,
165     0x0000000e, 0x00000002, 0000000000, 0x00000006, 0x0000001e, 0x0000007e,
166     0x000001fe, 0x000007fe, 0x00001ffe, 0x00003ffe, 0x0001fffc, 0x0007fff8,
167     0x000ffffb, 0x000ffffc, 0x000ffffd, 0x000ffffe, 0x000fffff};
168 
169 /* PS Stereo Huffmantable: iidDeltaTimeFine */
170 static const UINT iidDeltaTimeFine_Length[] = {
171     16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14,
172     14, 13, 13, 13, 12, 12, 11, 10, 9,  9,  7,  6,  5,  3,  1,  2,
173     5,  6,  7,  8,  9,  10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
174     15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
175 static const UINT iidDeltaTimeFine_Code[] = {
176     0x00004ed4, 0x00004ed5, 0x00004ece, 0x00004ecf, 0x00004ecc, 0x00004ed6,
177     0x00004ed8, 0x00004f46, 0x00004f60, 0x00002718, 0x00002719, 0x00002764,
178     0x00002765, 0x0000276d, 0x000027b1, 0x000013b7, 0x000013d6, 0x000009c7,
179     0x000009e9, 0x000009ed, 0x000004ee, 0x000004f7, 0x00000278, 0x00000139,
180     0x0000009a, 0x0000009f, 0x00000020, 0x00000011, 0x0000000a, 0x00000003,
181     0x00000001, 0000000000, 0x0000000b, 0x00000012, 0x00000021, 0x0000004c,
182     0x0000009b, 0x0000013a, 0x00000279, 0x00000270, 0x000004ef, 0x000004e2,
183     0x000009ea, 0x000009d8, 0x000013d7, 0x000013d0, 0x000027b2, 0x000027a2,
184     0x0000271a, 0x0000271b, 0x00004f66, 0x00004f67, 0x00004f61, 0x00004f47,
185     0x00004ed9, 0x00004ed7, 0x00004ecd, 0x00004ed2, 0x00004ed3, 0x00004ed0,
186     0x00004ed1};
187 
188 static const INT iccDelta_Offset = 7;
189 static const INT iccDelta_MaxVal = 14;
190 /* PS Stereo Huffmantable: iccDeltaFreq */
191 static const UINT iccDeltaFreq_Length[] = {14, 14, 12, 10, 7, 5,  3, 1,
192                                            2,  4,  6,  8,  9, 11, 13};
193 static const UINT iccDeltaFreq_Code[] = {
194     0x00003fff, 0x00003ffe, 0x00000ffe, 0x000003fe, 0x0000007e,
195     0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e,
196     0x0000003e, 0x000000fe, 0x000001fe, 0x000007fe, 0x00001ffe};
197 
198 /* PS Stereo Huffmantable: iccDeltaTime */
199 static const UINT iccDeltaTime_Length[] = {14, 13, 11, 9, 7,  5,  3, 1,
200                                            2,  4,  6,  8, 10, 12, 14};
201 static const UINT iccDeltaTime_Code[] = {
202     0x00003ffe, 0x00001ffe, 0x000007fe, 0x000001fe, 0x0000007e,
203     0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e,
204     0x0000003e, 0x000000fe, 0x000003fe, 0x00000ffe, 0x00003fff};
205 
206 static const INT ipdDelta_Offset = 0;
207 static const INT ipdDelta_MaxVal = 7;
208 /* PS Stereo Huffmantable: ipdDeltaFreq */
209 static const UINT ipdDeltaFreq_Length[] = {1, 3, 4, 4, 4, 4, 4, 4};
210 static const UINT ipdDeltaFreq_Code[] = {0x00000001, 0000000000, 0x00000006,
211                                          0x00000004, 0x00000002, 0x00000003,
212                                          0x00000005, 0x00000007};
213 
214 /* PS Stereo Huffmantable: ipdDeltaTime */
215 static const UINT ipdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3};
216 static const UINT ipdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000002,
217                                          0x00000003, 0x00000002, 0000000000,
218                                          0x00000003, 0x00000003};
219 
220 static const INT opdDelta_Offset = 0;
221 static const INT opdDelta_MaxVal = 7;
222 /* PS Stereo Huffmantable: opdDeltaFreq */
223 static const UINT opdDeltaFreq_Length[] = {1, 3, 4, 4, 5, 5, 4, 3};
224 static const UINT opdDeltaFreq_Code[] = {
225     0x00000001, 0x00000001, 0x00000006, 0x00000004,
226     0x0000000f, 0x0000000e, 0x00000005, 0000000000,
227 };
228 
229 /* PS Stereo Huffmantable: opdDeltaTime */
230 static const UINT opdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3};
231 static const UINT opdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000001,
232                                          0x00000007, 0x00000006, 0000000000,
233                                          0x00000002, 0x00000003};
234 
getNoBands(const INT mode)235 static INT getNoBands(const INT mode) {
236   INT noBands = 0;
237 
238   switch (mode) {
239     case 0:
240     case 3: /* coarse */
241       noBands = PS_BANDS_COARSE;
242       break;
243     case 1:
244     case 4: /* mid */
245       noBands = PS_BANDS_MID;
246       break;
247     case 2:
248     case 5:  /* fine not supported */
249     default: /* coarse as default */
250       noBands = PS_BANDS_COARSE;
251   }
252 
253   return noBands;
254 }
255 
getIIDRes(INT iidMode)256 static INT getIIDRes(INT iidMode) {
257   if (iidMode < 3)
258     return PS_IID_RES_COARSE;
259   else
260     return PS_IID_RES_FINE;
261 }
262 
encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf,const INT * val,const INT nBands,const UINT * codeTable,const UINT * lengthTable,const INT tableOffset,const INT maxVal,INT * error)263 static INT encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val,
264                            const INT nBands, const UINT *codeTable,
265                            const UINT *lengthTable, const INT tableOffset,
266                            const INT maxVal, INT *error) {
267   INT bitCnt = 0;
268   INT lastVal = 0;
269   INT band;
270 
271   for (band = 0; band < nBands; band++) {
272     INT delta = (val[band] - lastVal) + tableOffset;
273     lastVal = val[band];
274     if ((delta > maxVal) || (delta < 0)) {
275       *error = 1;
276       delta = delta > 0 ? maxVal : 0;
277     }
278     bitCnt +=
279         FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
280   }
281 
282   return bitCnt;
283 }
284 
encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf,const INT * val,const INT * valLast,const INT nBands,const UINT * codeTable,const UINT * lengthTable,const INT tableOffset,const INT maxVal,INT * error)285 static INT encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val,
286                            const INT *valLast, const INT nBands,
287                            const UINT *codeTable, const UINT *lengthTable,
288                            const INT tableOffset, const INT maxVal,
289                            INT *error) {
290   INT bitCnt = 0;
291   INT band;
292 
293   for (band = 0; band < nBands; band++) {
294     INT delta = (val[band] - valLast[band]) + tableOffset;
295     if ((delta > maxVal) || (delta < 0)) {
296       *error = 1;
297       delta = delta > 0 ? maxVal : 0;
298     }
299     bitCnt +=
300         FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
301   }
302 
303   return bitCnt;
304 }
305 
FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf,const INT * iidVal,const INT * iidValLast,const INT nBands,const PS_IID_RESOLUTION res,const PS_DELTA mode,INT * error)306 INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iidVal,
307                         const INT *iidValLast, const INT nBands,
308                         const PS_IID_RESOLUTION res, const PS_DELTA mode,
309                         INT *error) {
310   const UINT *codeTable;
311   const UINT *lengthTable;
312   INT bitCnt = 0;
313 
314   bitCnt = 0;
315 
316   switch (mode) {
317     case PS_DELTA_FREQ:
318       switch (res) {
319         case PS_IID_RES_COARSE:
320           codeTable = iidDeltaFreqCoarse_Code;
321           lengthTable = iidDeltaFreqCoarse_Length;
322           bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
323                                     lengthTable, iidDeltaCoarse_Offset,
324                                     iidDeltaCoarse_MaxVal, error);
325           break;
326         case PS_IID_RES_FINE:
327           codeTable = iidDeltaFreqFine_Code;
328           lengthTable = iidDeltaFreqFine_Length;
329           bitCnt +=
330               encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, lengthTable,
331                               iidDeltaFine_Offset, iidDeltaFine_MaxVal, error);
332           break;
333         default:
334           *error = 1;
335       }
336       break;
337 
338     case PS_DELTA_TIME:
339       switch (res) {
340         case PS_IID_RES_COARSE:
341           codeTable = iidDeltaTimeCoarse_Code;
342           lengthTable = iidDeltaTimeCoarse_Length;
343           bitCnt += encodeDeltaTime(
344               hBitBuf, iidVal, iidValLast, nBands, codeTable, lengthTable,
345               iidDeltaCoarse_Offset, iidDeltaCoarse_MaxVal, error);
346           break;
347         case PS_IID_RES_FINE:
348           codeTable = iidDeltaTimeFine_Code;
349           lengthTable = iidDeltaTimeFine_Length;
350           bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands,
351                                     codeTable, lengthTable, iidDeltaFine_Offset,
352                                     iidDeltaFine_MaxVal, error);
353           break;
354         default:
355           *error = 1;
356       }
357       break;
358 
359     default:
360       *error = 1;
361   }
362 
363   return bitCnt;
364 }
365 
FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf,const INT * iccVal,const INT * iccValLast,const INT nBands,const PS_DELTA mode,INT * error)366 INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal,
367                         const INT *iccValLast, const INT nBands,
368                         const PS_DELTA mode, INT *error) {
369   const UINT *codeTable;
370   const UINT *lengthTable;
371   INT bitCnt = 0;
372 
373   switch (mode) {
374     case PS_DELTA_FREQ:
375       codeTable = iccDeltaFreq_Code;
376       lengthTable = iccDeltaFreq_Length;
377       bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable, lengthTable,
378                                 iccDelta_Offset, iccDelta_MaxVal, error);
379       break;
380 
381     case PS_DELTA_TIME:
382       codeTable = iccDeltaTime_Code;
383       lengthTable = iccDeltaTime_Length;
384 
385       bitCnt +=
386           encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable,
387                           lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
388       break;
389 
390     default:
391       *error = 1;
392   }
393 
394   return bitCnt;
395 }
396 
FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf,const INT * ipdVal,const INT * ipdValLast,const INT nBands,const PS_DELTA mode,INT * error)397 INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal,
398                         const INT *ipdValLast, const INT nBands,
399                         const PS_DELTA mode, INT *error) {
400   const UINT *codeTable;
401   const UINT *lengthTable;
402   INT bitCnt = 0;
403 
404   switch (mode) {
405     case PS_DELTA_FREQ:
406       codeTable = ipdDeltaFreq_Code;
407       lengthTable = ipdDeltaFreq_Length;
408       bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable, lengthTable,
409                                 ipdDelta_Offset, ipdDelta_MaxVal, error);
410       break;
411 
412     case PS_DELTA_TIME:
413       codeTable = ipdDeltaTime_Code;
414       lengthTable = ipdDeltaTime_Length;
415 
416       bitCnt +=
417           encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable,
418                           lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
419       break;
420 
421     default:
422       *error = 1;
423   }
424 
425   return bitCnt;
426 }
427 
FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf,const INT * opdVal,const INT * opdValLast,const INT nBands,const PS_DELTA mode,INT * error)428 INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal,
429                         const INT *opdValLast, const INT nBands,
430                         const PS_DELTA mode, INT *error) {
431   const UINT *codeTable;
432   const UINT *lengthTable;
433   INT bitCnt = 0;
434 
435   switch (mode) {
436     case PS_DELTA_FREQ:
437       codeTable = opdDeltaFreq_Code;
438       lengthTable = opdDeltaFreq_Length;
439       bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable, lengthTable,
440                                 opdDelta_Offset, opdDelta_MaxVal, error);
441       break;
442 
443     case PS_DELTA_TIME:
444       codeTable = opdDeltaTime_Code;
445       lengthTable = opdDeltaTime_Length;
446 
447       bitCnt +=
448           encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable,
449                           lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
450       break;
451 
452     default:
453       *error = 1;
454   }
455 
456   return bitCnt;
457 }
458 
encodeIpdOpd(HANDLE_PS_OUT psOut,HANDLE_FDK_BITSTREAM hBitBuf)459 static INT encodeIpdOpd(HANDLE_PS_OUT psOut, HANDLE_FDK_BITSTREAM hBitBuf) {
460   INT bitCnt = 0;
461   INT error = 0;
462   INT env;
463 
464   FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1);
465 
466   if (psOut->enableIpdOpd == 1) {
467     INT *ipdLast = psOut->ipdLast;
468     INT *opdLast = psOut->opdLast;
469 
470     for (env = 0; env < psOut->nEnvelopes; env++) {
471       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIPD[env], 1);
472       bitCnt += FDKsbrEnc_EncodeIpd(hBitBuf, psOut->ipd[env], ipdLast,
473                                     getNoBands(psOut->iidMode),
474                                     psOut->deltaIPD[env], &error);
475 
476       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaOPD[env], 1);
477       bitCnt += FDKsbrEnc_EncodeOpd(hBitBuf, psOut->opd[env], opdLast,
478                                     getNoBands(psOut->iidMode),
479                                     psOut->deltaOPD[env], &error);
480     }
481     /* reserved bit */
482     bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, 1);
483   }
484 
485   return bitCnt;
486 }
487 
getEnvIdx(const INT nEnvelopes,const INT frameClass)488 static INT getEnvIdx(const INT nEnvelopes, const INT frameClass) {
489   INT envIdx = 0;
490 
491   switch (nEnvelopes) {
492     case 0:
493       envIdx = 0;
494       break;
495 
496     case 1:
497       if (frameClass == 0)
498         envIdx = 1;
499       else
500         envIdx = 0;
501       break;
502 
503     case 2:
504       if (frameClass == 0)
505         envIdx = 2;
506       else
507         envIdx = 1;
508       break;
509 
510     case 3:
511       envIdx = 2;
512       break;
513 
514     case 4:
515       envIdx = 3;
516       break;
517 
518     default:
519       /* unsupported number of envelopes */
520       envIdx = 0;
521   }
522 
523   return envIdx;
524 }
525 
encodePSExtension(const HANDLE_PS_OUT psOut,HANDLE_FDK_BITSTREAM hBitBuf)526 static INT encodePSExtension(const HANDLE_PS_OUT psOut,
527                              HANDLE_FDK_BITSTREAM hBitBuf) {
528   INT bitCnt = 0;
529 
530   if (psOut->enableIpdOpd == 1) {
531     INT ipdOpdBits = 0;
532     INT extSize = (2 + encodeIpdOpd(psOut, NULL) + 7) >> 3;
533 
534     if (extSize < 15) {
535       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, extSize, 4);
536     } else {
537       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 15, 4);
538       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize - 15), 8);
539     }
540 
541     /* write ipd opd data */
542     ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2);
543     ipdOpdBits += encodeIpdOpd(psOut, hBitBuf);
544 
545     /* byte align the ipd opd data  */
546     if (ipdOpdBits % 8)
547       ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8 - (ipdOpdBits % 8)));
548 
549     bitCnt += ipdOpdBits;
550   }
551 
552   return (bitCnt);
553 }
554 
FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,HANDLE_FDK_BITSTREAM hBitBuf)555 INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
556                                HANDLE_FDK_BITSTREAM hBitBuf) {
557   INT psExtEnable = 0;
558   INT bitCnt = 0;
559   INT error = 0;
560   INT env;
561 
562   if (psOut != NULL) {
563     /* PS HEADER */
564     bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enablePSHeader, 1);
565 
566     if (psOut->enablePSHeader) {
567       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIID, 1);
568       if (psOut->enableIID) {
569         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iidMode, 3);
570       }
571       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableICC, 1);
572       if (psOut->enableICC) {
573         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iccMode, 3);
574       }
575       if (psOut->enableIpdOpd) {
576         psExtEnable = 1;
577       }
578       bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psExtEnable, 1);
579     }
580 
581     /* Frame class, number of envelopes */
582     bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameClass, 1);
583     bitCnt += FDKsbrEnc_WriteBits_ps(
584         hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2);
585 
586     if (psOut->frameClass == 1) {
587       for (env = 0; env < psOut->nEnvelopes; env++) {
588         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameBorder[env], 5);
589       }
590     }
591 
592     if (psOut->enableIID == 1) {
593       INT *iidLast = psOut->iidLast;
594       for (env = 0; env < psOut->nEnvelopes; env++) {
595         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIID[env], 1);
596         bitCnt += FDKsbrEnc_EncodeIid(
597             hBitBuf, psOut->iid[env], iidLast, getNoBands(psOut->iidMode),
598             (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode), psOut->deltaIID[env],
599             &error);
600 
601         iidLast = psOut->iid[env];
602       }
603     }
604 
605     if (psOut->enableICC == 1) {
606       INT *iccLast = psOut->iccLast;
607       for (env = 0; env < psOut->nEnvelopes; env++) {
608         bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaICC[env], 1);
609         bitCnt += FDKsbrEnc_EncodeIcc(hBitBuf, psOut->icc[env], iccLast,
610                                       getNoBands(psOut->iccMode),
611                                       psOut->deltaICC[env], &error);
612 
613         iccLast = psOut->icc[env];
614       }
615     }
616 
617     if (psExtEnable != 0) {
618       bitCnt += encodePSExtension(psOut, hBitBuf);
619     }
620 
621   } /* if(psOut != NULL) */
622 
623   return bitCnt;
624 }
625