/src/aac/libSBRenc/src/ps_bitenc.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 - 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 | | |
107 | | static inline UCHAR FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream, |
108 | | UINT value, |
109 | 0 | const UINT numberOfBits) { |
110 | | /* hBitStream == NULL happens here intentionally */ |
111 | 0 | if (hBitStream != NULL) { |
112 | 0 | FDKwriteBits(hBitStream, value, numberOfBits); |
113 | 0 | } |
114 | 0 | return numberOfBits; |
115 | 0 | } |
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 | 0 | #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 | | |
235 | 0 | static INT getNoBands(const INT mode) { |
236 | 0 | INT noBands = 0; |
237 | |
|
238 | 0 | switch (mode) { |
239 | 0 | case 0: |
240 | 0 | case 3: /* coarse */ |
241 | 0 | noBands = PS_BANDS_COARSE; |
242 | 0 | break; |
243 | 0 | case 1: |
244 | 0 | case 4: /* mid */ |
245 | 0 | noBands = PS_BANDS_MID; |
246 | 0 | break; |
247 | 0 | case 2: |
248 | 0 | case 5: /* fine not supported */ |
249 | 0 | default: /* coarse as default */ |
250 | 0 | noBands = PS_BANDS_COARSE; |
251 | 0 | } |
252 | | |
253 | 0 | return noBands; |
254 | 0 | } |
255 | | |
256 | 0 | static INT getIIDRes(INT iidMode) { |
257 | 0 | if (iidMode < 3) |
258 | 0 | return PS_IID_RES_COARSE; |
259 | 0 | else |
260 | 0 | return PS_IID_RES_FINE; |
261 | 0 | } |
262 | | |
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 | 0 | const INT maxVal, INT *error) { |
267 | 0 | INT bitCnt = 0; |
268 | 0 | INT lastVal = 0; |
269 | 0 | INT band; |
270 | |
|
271 | 0 | for (band = 0; band < nBands; band++) { |
272 | 0 | INT delta = (val[band] - lastVal) + tableOffset; |
273 | 0 | lastVal = val[band]; |
274 | 0 | if ((delta > maxVal) || (delta < 0)) { |
275 | 0 | *error = 1; |
276 | 0 | delta = delta > 0 ? maxVal : 0; |
277 | 0 | } |
278 | 0 | bitCnt += |
279 | 0 | FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]); |
280 | 0 | } |
281 | |
|
282 | 0 | return bitCnt; |
283 | 0 | } |
284 | | |
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 | 0 | INT *error) { |
290 | 0 | INT bitCnt = 0; |
291 | 0 | INT band; |
292 | |
|
293 | 0 | for (band = 0; band < nBands; band++) { |
294 | 0 | INT delta = (val[band] - valLast[band]) + tableOffset; |
295 | 0 | if ((delta > maxVal) || (delta < 0)) { |
296 | 0 | *error = 1; |
297 | 0 | delta = delta > 0 ? maxVal : 0; |
298 | 0 | } |
299 | 0 | bitCnt += |
300 | 0 | FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]); |
301 | 0 | } |
302 | |
|
303 | 0 | return bitCnt; |
304 | 0 | } |
305 | | |
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 | 0 | INT *error) { |
310 | 0 | const UINT *codeTable; |
311 | 0 | const UINT *lengthTable; |
312 | 0 | INT bitCnt = 0; |
313 | |
|
314 | 0 | bitCnt = 0; |
315 | |
|
316 | 0 | switch (mode) { |
317 | 0 | case PS_DELTA_FREQ: |
318 | 0 | switch (res) { |
319 | 0 | case PS_IID_RES_COARSE: |
320 | 0 | codeTable = iidDeltaFreqCoarse_Code; |
321 | 0 | lengthTable = iidDeltaFreqCoarse_Length; |
322 | 0 | bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, |
323 | 0 | lengthTable, iidDeltaCoarse_Offset, |
324 | 0 | iidDeltaCoarse_MaxVal, error); |
325 | 0 | break; |
326 | 0 | case PS_IID_RES_FINE: |
327 | 0 | codeTable = iidDeltaFreqFine_Code; |
328 | 0 | lengthTable = iidDeltaFreqFine_Length; |
329 | 0 | bitCnt += |
330 | 0 | encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, lengthTable, |
331 | 0 | iidDeltaFine_Offset, iidDeltaFine_MaxVal, error); |
332 | 0 | break; |
333 | 0 | default: |
334 | 0 | *error = 1; |
335 | 0 | } |
336 | 0 | break; |
337 | | |
338 | 0 | case PS_DELTA_TIME: |
339 | 0 | switch (res) { |
340 | 0 | case PS_IID_RES_COARSE: |
341 | 0 | codeTable = iidDeltaTimeCoarse_Code; |
342 | 0 | lengthTable = iidDeltaTimeCoarse_Length; |
343 | 0 | bitCnt += encodeDeltaTime( |
344 | 0 | hBitBuf, iidVal, iidValLast, nBands, codeTable, lengthTable, |
345 | 0 | iidDeltaCoarse_Offset, iidDeltaCoarse_MaxVal, error); |
346 | 0 | break; |
347 | 0 | case PS_IID_RES_FINE: |
348 | 0 | codeTable = iidDeltaTimeFine_Code; |
349 | 0 | lengthTable = iidDeltaTimeFine_Length; |
350 | 0 | bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands, |
351 | 0 | codeTable, lengthTable, iidDeltaFine_Offset, |
352 | 0 | iidDeltaFine_MaxVal, error); |
353 | 0 | break; |
354 | 0 | default: |
355 | 0 | *error = 1; |
356 | 0 | } |
357 | 0 | break; |
358 | | |
359 | 0 | default: |
360 | 0 | *error = 1; |
361 | 0 | } |
362 | | |
363 | 0 | return bitCnt; |
364 | 0 | } |
365 | | |
366 | | INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal, |
367 | | const INT *iccValLast, const INT nBands, |
368 | 0 | const PS_DELTA mode, INT *error) { |
369 | 0 | const UINT *codeTable; |
370 | 0 | const UINT *lengthTable; |
371 | 0 | INT bitCnt = 0; |
372 | |
|
373 | 0 | switch (mode) { |
374 | 0 | case PS_DELTA_FREQ: |
375 | 0 | codeTable = iccDeltaFreq_Code; |
376 | 0 | lengthTable = iccDeltaFreq_Length; |
377 | 0 | bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable, lengthTable, |
378 | 0 | iccDelta_Offset, iccDelta_MaxVal, error); |
379 | 0 | break; |
380 | | |
381 | 0 | case PS_DELTA_TIME: |
382 | 0 | codeTable = iccDeltaTime_Code; |
383 | 0 | lengthTable = iccDeltaTime_Length; |
384 | |
|
385 | 0 | bitCnt += |
386 | 0 | encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable, |
387 | 0 | lengthTable, iccDelta_Offset, iccDelta_MaxVal, error); |
388 | 0 | break; |
389 | | |
390 | 0 | default: |
391 | 0 | *error = 1; |
392 | 0 | } |
393 | | |
394 | 0 | return bitCnt; |
395 | 0 | } |
396 | | |
397 | | INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal, |
398 | | const INT *ipdValLast, const INT nBands, |
399 | 0 | const PS_DELTA mode, INT *error) { |
400 | 0 | const UINT *codeTable; |
401 | 0 | const UINT *lengthTable; |
402 | 0 | INT bitCnt = 0; |
403 | |
|
404 | 0 | switch (mode) { |
405 | 0 | case PS_DELTA_FREQ: |
406 | 0 | codeTable = ipdDeltaFreq_Code; |
407 | 0 | lengthTable = ipdDeltaFreq_Length; |
408 | 0 | bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable, lengthTable, |
409 | 0 | ipdDelta_Offset, ipdDelta_MaxVal, error); |
410 | 0 | break; |
411 | | |
412 | 0 | case PS_DELTA_TIME: |
413 | 0 | codeTable = ipdDeltaTime_Code; |
414 | 0 | lengthTable = ipdDeltaTime_Length; |
415 | |
|
416 | 0 | bitCnt += |
417 | 0 | encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable, |
418 | 0 | lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error); |
419 | 0 | break; |
420 | | |
421 | 0 | default: |
422 | 0 | *error = 1; |
423 | 0 | } |
424 | | |
425 | 0 | return bitCnt; |
426 | 0 | } |
427 | | |
428 | | INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal, |
429 | | const INT *opdValLast, const INT nBands, |
430 | 0 | const PS_DELTA mode, INT *error) { |
431 | 0 | const UINT *codeTable; |
432 | 0 | const UINT *lengthTable; |
433 | 0 | INT bitCnt = 0; |
434 | |
|
435 | 0 | switch (mode) { |
436 | 0 | case PS_DELTA_FREQ: |
437 | 0 | codeTable = opdDeltaFreq_Code; |
438 | 0 | lengthTable = opdDeltaFreq_Length; |
439 | 0 | bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable, lengthTable, |
440 | 0 | opdDelta_Offset, opdDelta_MaxVal, error); |
441 | 0 | break; |
442 | | |
443 | 0 | case PS_DELTA_TIME: |
444 | 0 | codeTable = opdDeltaTime_Code; |
445 | 0 | lengthTable = opdDeltaTime_Length; |
446 | |
|
447 | 0 | bitCnt += |
448 | 0 | encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable, |
449 | 0 | lengthTable, opdDelta_Offset, opdDelta_MaxVal, error); |
450 | 0 | break; |
451 | | |
452 | 0 | default: |
453 | 0 | *error = 1; |
454 | 0 | } |
455 | | |
456 | 0 | return bitCnt; |
457 | 0 | } |
458 | | |
459 | 0 | static INT encodeIpdOpd(HANDLE_PS_OUT psOut, HANDLE_FDK_BITSTREAM hBitBuf) { |
460 | 0 | INT bitCnt = 0; |
461 | 0 | INT error = 0; |
462 | 0 | INT env; |
463 | |
|
464 | 0 | FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1); |
465 | |
|
466 | 0 | if (psOut->enableIpdOpd == 1) { |
467 | 0 | INT *ipdLast = psOut->ipdLast; |
468 | 0 | INT *opdLast = psOut->opdLast; |
469 | |
|
470 | 0 | for (env = 0; env < psOut->nEnvelopes; env++) { |
471 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIPD[env], 1); |
472 | 0 | bitCnt += FDKsbrEnc_EncodeIpd(hBitBuf, psOut->ipd[env], ipdLast, |
473 | 0 | getNoBands(psOut->iidMode), |
474 | 0 | psOut->deltaIPD[env], &error); |
475 | |
|
476 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaOPD[env], 1); |
477 | 0 | bitCnt += FDKsbrEnc_EncodeOpd(hBitBuf, psOut->opd[env], opdLast, |
478 | 0 | getNoBands(psOut->iidMode), |
479 | 0 | psOut->deltaOPD[env], &error); |
480 | 0 | } |
481 | | /* reserved bit */ |
482 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, 1); |
483 | 0 | } |
484 | |
|
485 | 0 | return bitCnt; |
486 | 0 | } |
487 | | |
488 | 0 | static INT getEnvIdx(const INT nEnvelopes, const INT frameClass) { |
489 | 0 | INT envIdx = 0; |
490 | |
|
491 | 0 | switch (nEnvelopes) { |
492 | 0 | case 0: |
493 | 0 | envIdx = 0; |
494 | 0 | break; |
495 | | |
496 | 0 | case 1: |
497 | 0 | if (frameClass == 0) |
498 | 0 | envIdx = 1; |
499 | 0 | else |
500 | 0 | envIdx = 0; |
501 | 0 | break; |
502 | | |
503 | 0 | case 2: |
504 | 0 | if (frameClass == 0) |
505 | 0 | envIdx = 2; |
506 | 0 | else |
507 | 0 | envIdx = 1; |
508 | 0 | break; |
509 | | |
510 | 0 | case 3: |
511 | 0 | envIdx = 2; |
512 | 0 | break; |
513 | | |
514 | 0 | case 4: |
515 | 0 | envIdx = 3; |
516 | 0 | break; |
517 | | |
518 | 0 | default: |
519 | | /* unsupported number of envelopes */ |
520 | 0 | envIdx = 0; |
521 | 0 | } |
522 | | |
523 | 0 | return envIdx; |
524 | 0 | } |
525 | | |
526 | | static INT encodePSExtension(const HANDLE_PS_OUT psOut, |
527 | 0 | HANDLE_FDK_BITSTREAM hBitBuf) { |
528 | 0 | INT bitCnt = 0; |
529 | |
|
530 | 0 | if (psOut->enableIpdOpd == 1) { |
531 | 0 | INT ipdOpdBits = 0; |
532 | 0 | INT extSize = (2 + encodeIpdOpd(psOut, NULL) + 7) >> 3; |
533 | |
|
534 | 0 | if (extSize < 15) { |
535 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, extSize, 4); |
536 | 0 | } else { |
537 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 15, 4); |
538 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize - 15), 8); |
539 | 0 | } |
540 | | |
541 | | /* write ipd opd data */ |
542 | 0 | ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2); |
543 | 0 | ipdOpdBits += encodeIpdOpd(psOut, hBitBuf); |
544 | | |
545 | | /* byte align the ipd opd data */ |
546 | 0 | if (ipdOpdBits % 8) |
547 | 0 | ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8 - (ipdOpdBits % 8))); |
548 | |
|
549 | 0 | bitCnt += ipdOpdBits; |
550 | 0 | } |
551 | |
|
552 | 0 | return (bitCnt); |
553 | 0 | } |
554 | | |
555 | | INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut, |
556 | 0 | HANDLE_FDK_BITSTREAM hBitBuf) { |
557 | 0 | INT psExtEnable = 0; |
558 | 0 | INT bitCnt = 0; |
559 | 0 | INT error = 0; |
560 | 0 | INT env; |
561 | |
|
562 | 0 | if (psOut != NULL) { |
563 | | /* PS HEADER */ |
564 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enablePSHeader, 1); |
565 | |
|
566 | 0 | if (psOut->enablePSHeader) { |
567 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIID, 1); |
568 | 0 | if (psOut->enableIID) { |
569 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iidMode, 3); |
570 | 0 | } |
571 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableICC, 1); |
572 | 0 | if (psOut->enableICC) { |
573 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iccMode, 3); |
574 | 0 | } |
575 | 0 | if (psOut->enableIpdOpd) { |
576 | 0 | psExtEnable = 1; |
577 | 0 | } |
578 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psExtEnable, 1); |
579 | 0 | } |
580 | | |
581 | | /* Frame class, number of envelopes */ |
582 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameClass, 1); |
583 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps( |
584 | 0 | hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2); |
585 | |
|
586 | 0 | if (psOut->frameClass == 1) { |
587 | 0 | for (env = 0; env < psOut->nEnvelopes; env++) { |
588 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameBorder[env], 5); |
589 | 0 | } |
590 | 0 | } |
591 | |
|
592 | 0 | if (psOut->enableIID == 1) { |
593 | 0 | INT *iidLast = psOut->iidLast; |
594 | 0 | for (env = 0; env < psOut->nEnvelopes; env++) { |
595 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIID[env], 1); |
596 | 0 | bitCnt += FDKsbrEnc_EncodeIid( |
597 | 0 | hBitBuf, psOut->iid[env], iidLast, getNoBands(psOut->iidMode), |
598 | 0 | (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode), psOut->deltaIID[env], |
599 | 0 | &error); |
600 | |
|
601 | 0 | iidLast = psOut->iid[env]; |
602 | 0 | } |
603 | 0 | } |
604 | |
|
605 | 0 | if (psOut->enableICC == 1) { |
606 | 0 | INT *iccLast = psOut->iccLast; |
607 | 0 | for (env = 0; env < psOut->nEnvelopes; env++) { |
608 | 0 | bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaICC[env], 1); |
609 | 0 | bitCnt += FDKsbrEnc_EncodeIcc(hBitBuf, psOut->icc[env], iccLast, |
610 | 0 | getNoBands(psOut->iccMode), |
611 | 0 | psOut->deltaICC[env], &error); |
612 | |
|
613 | 0 | iccLast = psOut->icc[env]; |
614 | 0 | } |
615 | 0 | } |
616 | |
|
617 | 0 | if (psExtEnable != 0) { |
618 | 0 | bitCnt += encodePSExtension(psOut, hBitBuf); |
619 | 0 | } |
620 | |
|
621 | 0 | } /* if(psOut != NULL) */ |
622 | |
|
623 | 0 | return bitCnt; |
624 | 0 | } |