summaryrefslogtreecommitdiff
path: root/audio_codec/libraac/bitstream.c (plain)
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
57static unsigned int iCache0 = 0;
58static unsigned int iCache1 = 0;
59static int cacheBit0 = 0;
60static int cacheBit1 = 0;
61static int bitsUsed = 0;
62
63extern cook_IObuf cook_input;
64//extern cook_IObuf cook_output;
65
66void InitBitStream()
67{
68 iCache0 = 0;
69 iCache1 = 0;
70 cacheBit0 = 0;
71 cacheBit1 = 0;
72 bitsUsed = 0;
73}
74
75unsigned 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}
89void 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 **************************************************************************************/
112void 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 **************************************************************************************/
138static 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 **************************************************************************************/
178unsigned 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 **************************************************************************************/
267unsigned 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 **************************************************************************************/
357void 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 **************************************************************************************/
414int 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 **************************************************************************************/
441void 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