blob: 06c509b728468f4e6ac61c894ae9f4a5b20bfd7e
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: bitstream.c,v 1.2 2005/09/27 20:31:11 jrecker Exp $ |
3 | * |
4 | * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. |
5 | * |
6 | * The contents of this file, and the files included with this file, |
7 | * are subject to the current version of the RealNetworks Public |
8 | * Source License (the "RPSL") available at |
9 | * http://www.helixcommunity.org/content/rpsl unless you have licensed |
10 | * the file under the current version of the RealNetworks Community |
11 | * Source License (the "RCSL") available at |
12 | * http://www.helixcommunity.org/content/rcsl, in which case the RCSL |
13 | * will apply. You may also obtain the license terms directly from |
14 | * RealNetworks. You may not use this file except in compliance with |
15 | * the RPSL or, if you have a valid RCSL with RealNetworks applicable |
16 | * to this file, the RCSL. Please see the applicable RPSL or RCSL for |
17 | * the rights, obligations and limitations governing use of the |
18 | * contents of the file. |
19 | * |
20 | * This file is part of the Helix DNA Technology. RealNetworks is the |
21 | * developer of the Original Code and owns the copyrights in the |
22 | * portions it created. |
23 | * |
24 | * This file, and the files included with this file, is distributed |
25 | * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY |
26 | * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS |
27 | * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES |
28 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET |
29 | * ENJOYMENT OR NON-INFRINGEMENT. |
30 | * |
31 | * Technology Compatibility Kit Test Suite(s) Location: |
32 | * http://www.helixcommunity.org/content/tck |
33 | * |
34 | * Contributor(s): |
35 | * |
36 | * ***** END LICENSE BLOCK ***** */ |
37 | |
38 | /************************************************************************************** |
39 | * Fixed-point HE-AAC decoder |
40 | * Jon Recker (jrecker@real.com) |
41 | * February 2005 |
42 | * |
43 | * bitstream.c - bitstream parsing functions |
44 | **************************************************************************************/ |
45 | //#include <core/dsp.h> |
46 | #include <stdio.h> |
47 | #include <stdlib.h> |
48 | |
49 | #include "bitstream.h" |
50 | #include "raac_decode.h" |
51 | #include <android/log.h> |
52 | |
53 | #define LOG_TAG "codec_raac" |
54 | #define raac_print(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) |
55 | |
56 | |
57 | static unsigned int iCache0 = 0; |
58 | static unsigned int iCache1 = 0; |
59 | static int cacheBit0 = 0; |
60 | static int cacheBit1 = 0; |
61 | static int bitsUsed = 0; |
62 | |
63 | extern cook_IObuf cook_input; |
64 | //extern cook_IObuf cook_output; |
65 | |
66 | void InitBitStream() |
67 | { |
68 | iCache0 = 0; |
69 | iCache1 = 0; |
70 | cacheBit0 = 0; |
71 | cacheBit1 = 0; |
72 | bitsUsed = 0; |
73 | } |
74 | |
75 | unsigned char GetByte() |
76 | { |
77 | unsigned int val = 0; //read_byte(); |
78 | if (cook_input.buf != NULL && cook_input.buf_len > 0) { |
79 | val = (unsigned int)cook_input.buf[0]; |
80 | memcpy(cook_input.buf, cook_input.buf + 1, cook_input.buf_len - 1); |
81 | cook_input.buf_len -= 1; |
82 | cook_input.cousume += 1; |
83 | cook_input.all_consume += 1; |
84 | } else { |
85 | raac_print("GetByte() failed, because cook_input.buf has not data\n"); |
86 | } |
87 | return val; |
88 | } |
89 | void RefillBitStream() |
90 | { |
91 | int nBits = 32 - cacheBit0; |
92 | while (nBits) { |
93 | iCache0 |= (GetByte() << (32 - cacheBit0 - 8)); |
94 | cacheBit0 += 8; |
95 | nBits -= 8; |
96 | } |
97 | } |
98 | |
99 | /************************************************************************************** |
100 | * Function: SetBitstreamPointer |
101 | * |
102 | * Description: initialize bitstream reader |
103 | * |
104 | * Inputs: pointer to BitStreamInfo struct |
105 | * number of bytes in bitstream |
106 | * pointer to byte-aligned buffer of data to read from |
107 | * |
108 | * Outputs: initialized bitstream info struct |
109 | * |
110 | * Return: none |
111 | **************************************************************************************/ |
112 | void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf) |
113 | { |
114 | if (AACDataSource == 1) { |
115 | /* init bitstream */ |
116 | bsi->bytePtr = buf; |
117 | bsi->iCache = 0; /* 4-byte unsigned int */ |
118 | bsi->cachedBits = 0; /* i.e. zero bits in cache */ |
119 | bsi->nBytes = nBytes; |
120 | } |
121 | } |
122 | |
123 | /************************************************************************************** |
124 | * Function: RefillBitstreamCache |
125 | * |
126 | * Description: read new data from bitstream buffer into 32-bit cache |
127 | * |
128 | * Inputs: pointer to initialized BitStreamInfo struct |
129 | * |
130 | * Outputs: updated bitstream info struct |
131 | * |
132 | * Return: none |
133 | * |
134 | * Notes: only call when iCache is completely drained (resets bitOffset to 0) |
135 | * always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer) |
136 | * stores data as big-endian in cache, regardless of machine endian-ness |
137 | **************************************************************************************/ |
138 | static void RefillBitstreamCache(BitStreamInfo *bsi) |
139 | { |
140 | int nBytes = bsi->nBytes; |
141 | |
142 | /* optimize for common case, independent of machine endian-ness */ |
143 | if (nBytes >= 4) { |
144 | bsi->iCache = (*bsi->bytePtr++) << 24; |
145 | bsi->iCache |= (*bsi->bytePtr++) << 16; |
146 | bsi->iCache |= (*bsi->bytePtr++) << 8; |
147 | bsi->iCache |= (*bsi->bytePtr++); |
148 | bsi->cachedBits = 32; |
149 | bsi->nBytes -= 4; |
150 | } else { |
151 | bsi->iCache = 0; |
152 | while (nBytes--) { |
153 | bsi->iCache |= (*bsi->bytePtr++); |
154 | bsi->iCache <<= 8; |
155 | } |
156 | bsi->iCache <<= ((3 - bsi->nBytes) * 8); |
157 | bsi->cachedBits = 8 * bsi->nBytes; |
158 | bsi->nBytes = 0; |
159 | } |
160 | } |
161 | |
162 | /************************************************************************************** |
163 | * Function: GetBits |
164 | * |
165 | * Description: get bits from bitstream, advance bitstream pointer |
166 | * |
167 | * Inputs: pointer to initialized BitStreamInfo struct |
168 | * number of bits to get from bitstream |
169 | * |
170 | * Outputs: updated bitstream info struct |
171 | * |
172 | * Return: the next nBits bits of data from bitstream buffer |
173 | * |
174 | * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f |
175 | * for speed, does not indicate error if you overrun bit buffer |
176 | * if nBits == 0, returns 0 |
177 | **************************************************************************************/ |
178 | unsigned int GetBits(BitStreamInfo *bsi, int nBits) |
179 | { |
180 | unsigned int data = 0; |
181 | unsigned int lowBits = 0; |
182 | |
183 | if (AACDataSource == 1) { |
184 | nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ |
185 | data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ |
186 | data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ |
187 | bsi->iCache <<= nBits; /* left-justify cache */ |
188 | bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */ |
189 | |
190 | /* if we cross an int boundary, refill the cache */ |
191 | if (bsi->cachedBits < 0) { |
192 | lowBits = -bsi->cachedBits; |
193 | RefillBitstreamCache(bsi); |
194 | data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */ |
195 | |
196 | bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */ |
197 | bsi->iCache <<= lowBits; /* left-justify cache */ |
198 | } |
199 | |
200 | return data; |
201 | } else { |
202 | if (!nBits) { |
203 | return 0; |
204 | } |
205 | nBits = (nBits > 32) ? 32 : nBits; |
206 | bitsUsed += nBits; |
207 | if (cacheBit1 > 0) { |
208 | if (nBits > cacheBit1) { |
209 | if (cacheBit1 == 0) { // if shift above 32, the instruction shift 0 |
210 | data = 0; |
211 | } else { |
212 | data = iCache1 >> (32 - cacheBit1); |
213 | } |
214 | nBits -= cacheBit1; |
215 | data <<= nBits; |
216 | iCache1 = 0; |
217 | cacheBit1 = 0; |
218 | } else { |
219 | data = iCache1 >> (32 - nBits); |
220 | cacheBit1 -= nBits; |
221 | iCache1 <<= nBits; |
222 | return data; |
223 | } |
224 | } |
225 | |
226 | if (nBits > cacheBit0) { |
227 | if (cacheBit0) { |
228 | data |= iCache0 >> (32 - cacheBit0); |
229 | } |
230 | nBits -= cacheBit0; |
231 | data <<= nBits; |
232 | iCache0 = 0; |
233 | iCache0 = GetByte(); |
234 | iCache0 <<= 8; |
235 | iCache0 |= GetByte(); |
236 | iCache0 <<= 8; |
237 | iCache0 |= GetByte(); |
238 | iCache0 <<= 8; |
239 | iCache0 |= GetByte(); |
240 | cacheBit0 = 32; |
241 | } |
242 | if (nBits) { |
243 | data |= iCache0 >> (32 - nBits); |
244 | } |
245 | iCache0 <<= nBits; |
246 | cacheBit0 -= nBits; |
247 | return data; |
248 | } |
249 | } |
250 | |
251 | /************************************************************************************** |
252 | * Function: GetBitsNoAdvance |
253 | * |
254 | * Description: get bits from bitstream, do not advance bitstream pointer |
255 | * |
256 | * Inputs: pointer to initialized BitStreamInfo struct |
257 | * number of bits to get from bitstream |
258 | * |
259 | * Outputs: none (state of BitStreamInfo struct left unchanged) |
260 | * |
261 | * Return: the next nBits bits of data from bitstream buffer |
262 | * |
263 | * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f |
264 | * for speed, does not indicate error if you overrun bit buffer |
265 | * if nBits == 0, returns 0 |
266 | **************************************************************************************/ |
267 | unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits) |
268 | { |
269 | unsigned char *buf = NULL; |
270 | unsigned int data = 0; |
271 | unsigned int iCache = 0; |
272 | signed int lowBits = 0; |
273 | |
274 | if (AACDataSource == 1) { |
275 | nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ |
276 | data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ |
277 | data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ |
278 | lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */ |
279 | |
280 | /* if we cross an int boundary, read next bytes in buffer */ |
281 | if (lowBits > 0) { |
282 | iCache = 0; |
283 | buf = bsi->bytePtr; |
284 | while (lowBits > 0) { |
285 | iCache <<= 8; |
286 | if (buf < bsi->bytePtr + bsi->nBytes) { |
287 | iCache |= (unsigned int) * buf++; |
288 | } |
289 | lowBits -= 8; |
290 | } |
291 | lowBits = -lowBits; |
292 | data |= iCache >> lowBits; |
293 | } |
294 | return data; |
295 | } else { |
296 | if (!nBits) { |
297 | return 0; |
298 | } |
299 | nBits = (nBits > 32) ? 32 : nBits; |
300 | |
301 | if (nBits > (cacheBit0 + cacheBit1)) { |
302 | data = ((iCache1 >> (32 - cacheBit1)) << cacheBit0); |
303 | |
304 | if (cacheBit0) { |
305 | data |= (iCache0 >> (32 - cacheBit0)); |
306 | } |
307 | |
308 | iCache1 = data << (32 - cacheBit0 - cacheBit1); |
309 | cacheBit1 = cacheBit0 + cacheBit1; |
310 | nBits -= cacheBit1; |
311 | data <<= nBits; |
312 | |
313 | iCache0 = GetByte(); |
314 | iCache0 <<= 8; |
315 | iCache0 |= GetByte(); |
316 | iCache0 <<= 8; |
317 | iCache0 |= GetByte(); |
318 | iCache0 <<= 8; |
319 | iCache0 |= GetByte(); |
320 | |
321 | cacheBit0 = 32; |
322 | } else if (nBits > cacheBit1) { |
323 | if (cacheBit1) { |
324 | data = iCache1 >> (32 - cacheBit1); |
325 | } |
326 | nBits -= cacheBit1; |
327 | data <<= nBits; |
328 | } else { |
329 | //if(nBits<cacheBit1) |
330 | data = iCache1 >> (32 - nBits); |
331 | //cacheBit1 -= nBits; |
332 | //iCache1 <<= nBits; |
333 | return data; |
334 | } |
335 | if (nBits) { |
336 | data |= (iCache0 >> (32 - nBits)); |
337 | } |
338 | |
339 | return data; |
340 | } |
341 | } |
342 | |
343 | /************************************************************************************** |
344 | * Function: AdvanceBitstream |
345 | * |
346 | * Description: move bitstream pointer ahead |
347 | * |
348 | * Inputs: pointer to initialized BitStreamInfo struct |
349 | * number of bits to advance bitstream |
350 | * |
351 | * Outputs: updated bitstream info struct |
352 | * |
353 | * Return: none |
354 | * |
355 | * Notes: generally used following GetBitsNoAdvance(bsi, maxBits) |
356 | **************************************************************************************/ |
357 | void AdvanceBitstream(BitStreamInfo *bsi, int nBits) |
358 | { |
359 | if (AACDataSource == 1) { |
360 | nBits &= 0x1f; |
361 | if (nBits > bsi->cachedBits) { |
362 | nBits -= bsi->cachedBits; |
363 | RefillBitstreamCache(bsi); |
364 | } |
365 | bsi->iCache <<= nBits; |
366 | bsi->cachedBits -= nBits; |
367 | } else { |
368 | if (!nBits) { |
369 | return; |
370 | } |
371 | nBits &= 0x1f; |
372 | bitsUsed += nBits; |
373 | if (cacheBit1 > 0) { |
374 | if (nBits > cacheBit1) { |
375 | nBits -= cacheBit1; |
376 | cacheBit1 = 0; |
377 | iCache1 = 0; |
378 | } else { |
379 | cacheBit1 -= nBits; |
380 | iCache1 <<= nBits; |
381 | return; |
382 | } |
383 | } |
384 | if (nBits > cacheBit0) { |
385 | nBits -= cacheBit0; |
386 | cacheBit0 = 0; |
387 | iCache0 = GetByte(); |
388 | iCache0 <<= 8; |
389 | iCache0 |= GetByte(); |
390 | iCache0 <<= 8; |
391 | iCache0 |= GetByte(); |
392 | iCache0 <<= 8; |
393 | iCache0 |= GetByte(); |
394 | cacheBit0 = 32; |
395 | } |
396 | cacheBit0 -= nBits; |
397 | iCache0 <<= nBits; |
398 | } |
399 | } |
400 | |
401 | /************************************************************************************** |
402 | * Function: CalcBitsUsed |
403 | * |
404 | * Description: calculate how many bits have been read from bitstream |
405 | * |
406 | * Inputs: pointer to initialized BitStreamInfo struct |
407 | * pointer to start of bitstream buffer |
408 | * bit offset into first byte of startBuf (0-7) |
409 | * |
410 | * Outputs: none |
411 | * |
412 | * Return: number of bits read from bitstream, as offset from startBuf:startOffset |
413 | **************************************************************************************/ |
414 | int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset) |
415 | { |
416 | int bitsUsed = 0; |
417 | if (AACDataSource == 1) { |
418 | bitsUsed = (bsi->bytePtr - startBuf) * 8; |
419 | bitsUsed -= bsi->cachedBits; |
420 | bitsUsed -= startOffset; |
421 | |
422 | return bitsUsed; |
423 | } else { |
424 | return bitsUsed; |
425 | } |
426 | } |
427 | |
428 | /************************************************************************************** |
429 | * Function: ByteAlignBitstream |
430 | * |
431 | * Description: bump bitstream pointer to start of next byte |
432 | * |
433 | * Inputs: pointer to initialized BitStreamInfo struct |
434 | * |
435 | * Outputs: byte-aligned bitstream BitStreamInfo struct |
436 | * |
437 | * Return: none |
438 | * |
439 | * Notes: if bitstream is already byte-aligned, do nothing |
440 | **************************************************************************************/ |
441 | void ByteAlignBitstream(BitStreamInfo *bsi) |
442 | { |
443 | int offset = 0; |
444 | |
445 | if (AACDataSource == 1) { |
446 | offset = bsi->cachedBits & 0x07; |
447 | AdvanceBitstream(bsi, offset); |
448 | } else { |
449 | GetBits(0, (cacheBit0 + cacheBit1) & 7); |
450 | } |
451 | } |
452 |