summaryrefslogtreecommitdiff
path: root/audio_codec/wfd_aac_decoder/bitstream.c (plain)
blob: d92b2c85f807670c339338277a526d3157112499
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: bitstream.c,v 1.1.2.1.6.1 2005/10/19 00:18:49 gwright 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
46#include "bitstream.h"
47
48/**************************************************************************************
49 * Function: SetBitstreamPointer
50 *
51 * Description: initialize bitstream reader
52 *
53 * Inputs: pointer to BitStreamInfo struct
54 * number of bytes in bitstream
55 * pointer to byte-aligned buffer of data to read from
56 *
57 * Outputs: initialized bitstream info struct
58 *
59 * Return: none
60 **************************************************************************************/
61void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf)
62{
63 /* init bitstream */
64 bsi->bytePtr = buf;
65 bsi->iCache = 0; /* 4-byte unsigned int */
66 bsi->cachedBits = 0; /* i.e. zero bits in cache */
67 bsi->nBytes = nBytes;
68}
69
70/**************************************************************************************
71 * Function: RefillBitstreamCache
72 *
73 * Description: read new data from bitstream buffer into 32-bit cache
74 *
75 * Inputs: pointer to initialized BitStreamInfo struct
76 *
77 * Outputs: updated bitstream info struct
78 *
79 * Return: none
80 *
81 * Notes: only call when iCache is completely drained (resets bitOffset to 0)
82 * always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer)
83 * stores data as big-endian in cache, regardless of machine endian-ness
84 **************************************************************************************/
85static void RefillBitstreamCache(BitStreamInfo *bsi)
86{
87 int nBytes = bsi->nBytes;
88
89 /* optimize for common case, independent of machine endian-ness */
90 if (nBytes >= 4) {
91 bsi->iCache = (*bsi->bytePtr++) << 24;
92 bsi->iCache |= (*bsi->bytePtr++) << 16;
93 bsi->iCache |= (*bsi->bytePtr++) << 8;
94 bsi->iCache |= (*bsi->bytePtr++);
95 bsi->cachedBits = 32;
96 bsi->nBytes -= 4;
97 } else {
98 bsi->iCache = 0;
99 while (nBytes--) {
100 bsi->iCache |= (*bsi->bytePtr++);
101 bsi->iCache <<= 8;
102 }
103 bsi->iCache <<= ((3 - bsi->nBytes) * 8);
104 bsi->cachedBits = 8 * bsi->nBytes;
105 bsi->nBytes = 0;
106 }
107}
108
109/**************************************************************************************
110 * Function: GetBits
111 *
112 * Description: get bits from bitstream, advance bitstream pointer
113 *
114 * Inputs: pointer to initialized BitStreamInfo struct
115 * number of bits to get from bitstream
116 *
117 * Outputs: updated bitstream info struct
118 *
119 * Return: the next nBits bits of data from bitstream buffer
120 *
121 * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
122 * for speed, does not indicate error if you overrun bit buffer
123 * if nBits == 0, returns 0
124 **************************************************************************************/
125unsigned int GetBits(BitStreamInfo *bsi, int nBits)
126{
127 unsigned int data, lowBits;
128
129 nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
130 data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
131 data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
132 bsi->iCache <<= nBits; /* left-justify cache */
133 bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */
134
135 /* if we cross an int boundary, refill the cache */
136 if (bsi->cachedBits < 0) {
137 lowBits = -bsi->cachedBits;
138 RefillBitstreamCache(bsi);
139 data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */
140
141 bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */
142 bsi->iCache <<= lowBits; /* left-justify cache */
143 }
144
145 return data;
146}
147
148/**************************************************************************************
149 * Function: GetBitsNoAdvance
150 *
151 * Description: get bits from bitstream, do not advance bitstream pointer
152 *
153 * Inputs: pointer to initialized BitStreamInfo struct
154 * number of bits to get from bitstream
155 *
156 * Outputs: none (state of BitStreamInfo struct left unchanged)
157 *
158 * Return: the next nBits bits of data from bitstream buffer
159 *
160 * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
161 * for speed, does not indicate error if you overrun bit buffer
162 * if nBits == 0, returns 0
163 **************************************************************************************/
164unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits)
165{
166 unsigned char *buf;
167 unsigned int data, iCache;
168 signed int lowBits;
169
170 nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
171 data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
172 data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
173 lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */
174
175 /* if we cross an int boundary, read next bytes in buffer */
176 if (lowBits > 0) {
177 iCache = 0;
178 buf = bsi->bytePtr;
179 while (lowBits > 0) {
180 iCache <<= 8;
181 if (buf < bsi->bytePtr + bsi->nBytes) {
182 iCache |= (unsigned int) * buf++;
183 }
184 lowBits -= 8;
185 }
186 lowBits = -lowBits;
187 data |= iCache >> lowBits;
188 }
189
190 return data;
191}
192
193/**************************************************************************************
194 * Function: AdvanceBitstream
195 *
196 * Description: move bitstream pointer ahead
197 *
198 * Inputs: pointer to initialized BitStreamInfo struct
199 * number of bits to advance bitstream
200 *
201 * Outputs: updated bitstream info struct
202 *
203 * Return: none
204 *
205 * Notes: generally used following GetBitsNoAdvance(bsi, maxBits)
206 **************************************************************************************/
207void AdvanceBitstream(BitStreamInfo *bsi, int nBits)
208{
209 nBits &= 0x1f;
210 if (nBits > bsi->cachedBits) {
211 nBits -= bsi->cachedBits;
212 RefillBitstreamCache(bsi);
213 }
214 bsi->iCache <<= nBits;
215 bsi->cachedBits -= nBits;
216}
217
218/**************************************************************************************
219 * Function: CalcBitsUsed
220 *
221 * Description: calculate how many bits have been read from bitstream
222 *
223 * Inputs: pointer to initialized BitStreamInfo struct
224 * pointer to start of bitstream buffer
225 * bit offset into first byte of startBuf (0-7)
226 *
227 * Outputs: none
228 *
229 * Return: number of bits read from bitstream, as offset from startBuf:startOffset
230 **************************************************************************************/
231int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset)
232{
233 int bitsUsed;
234
235 bitsUsed = (bsi->bytePtr - startBuf) * 8;
236 bitsUsed -= bsi->cachedBits;
237 bitsUsed -= startOffset;
238
239 return bitsUsed;
240}
241
242/**************************************************************************************
243 * Function: ByteAlignBitstream
244 *
245 * Description: bump bitstream pointer to start of next byte
246 *
247 * Inputs: pointer to initialized BitStreamInfo struct
248 *
249 * Outputs: byte-aligned bitstream BitStreamInfo struct
250 *
251 * Return: none
252 *
253 * Notes: if bitstream is already byte-aligned, do nothing
254 **************************************************************************************/
255void ByteAlignBitstream(BitStreamInfo *bsi)
256{
257 int offset;
258
259 offset = bsi->cachedBits & 0x07;
260 AdvanceBitstream(bsi, offset);
261}
262