diff options
author | Dave Chapman <dave@dchapman.com> | 2005-10-26 12:35:58 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-10-26 12:35:58 +0000 |
commit | 273d2e81f72c7721447ab9c539877f6712faaecc (patch) | |
tree | 79c66b0b699ca65ac2cc2369cd5bbed764c35a4b /apps/codecs/libffmpegFLAC/bitstream.h | |
parent | 48be8e6a8b45fa16380af97829ba944430a78f17 (diff) | |
download | rockbox-273d2e81f72c7721447ab9c539877f6712faaecc.tar.gz rockbox-273d2e81f72c7721447ab9c539877f6712faaecc.zip |
New FLAC decoder from the ffmpeg project
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7656 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libffmpegFLAC/bitstream.h')
-rw-r--r-- | apps/codecs/libffmpegFLAC/bitstream.h | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/apps/codecs/libffmpegFLAC/bitstream.h b/apps/codecs/libffmpegFLAC/bitstream.h new file mode 100644 index 0000000000..62e98c07ea --- /dev/null +++ b/apps/codecs/libffmpegFLAC/bitstream.h | |||
@@ -0,0 +1,333 @@ | |||
1 | /** | ||
2 | * @file bitstream.h | ||
3 | * bitstream api header. | ||
4 | */ | ||
5 | |||
6 | #ifndef BITSTREAM_H | ||
7 | #define BITSTREAM_H | ||
8 | |||
9 | #include <inttypes.h> | ||
10 | |||
11 | #ifndef BUILD_STANDALONE | ||
12 | #include <config.h> | ||
13 | #include <system.h> | ||
14 | #else | ||
15 | #include <stdio.h> | ||
16 | #define IBSS_ATTR | ||
17 | #define ICONST_ATTR | ||
18 | |||
19 | #endif | ||
20 | |||
21 | /* Endian conversion routines for standalone compilation */ | ||
22 | #ifdef BUILD_STANDALONE | ||
23 | #ifdef BUILD_BIGENDIAN | ||
24 | #define betoh32(x) (x) | ||
25 | #define letoh32(x) swap32(x) | ||
26 | #else | ||
27 | #define letoh32(x) (x) | ||
28 | #define betoh32(x) swap32(x) | ||
29 | #endif | ||
30 | |||
31 | /* Taken from rockbox/firmware/export/system.h */ | ||
32 | |||
33 | static inline unsigned short swap16(unsigned short value) | ||
34 | /* | ||
35 | result[15..8] = value[ 7..0]; | ||
36 | result[ 7..0] = value[15..8]; | ||
37 | */ | ||
38 | { | ||
39 | return (value >> 8) | (value << 8); | ||
40 | } | ||
41 | |||
42 | static inline unsigned long swap32(unsigned long value) | ||
43 | /* | ||
44 | result[31..24] = value[ 7.. 0]; | ||
45 | result[23..16] = value[15.. 8]; | ||
46 | result[15.. 8] = value[23..16]; | ||
47 | result[ 7.. 0] = value[31..24]; | ||
48 | */ | ||
49 | { | ||
50 | unsigned long hi = swap16(value >> 16); | ||
51 | unsigned long lo = swap16(value & 0xffff); | ||
52 | return (lo << 16) | hi; | ||
53 | } | ||
54 | #endif | ||
55 | |||
56 | /* FLAC files are big-endian */ | ||
57 | #define ALT_BITSTREAM_READER_BE | ||
58 | |||
59 | #define NEG_SSR32(a,s) (((int32_t)(a))>>(32-(s))) | ||
60 | #define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) | ||
61 | |||
62 | /* bit input */ | ||
63 | /* buffer, buffer_end and size_in_bits must be present and used by every reader */ | ||
64 | typedef struct GetBitContext { | ||
65 | const uint8_t *buffer, *buffer_end; | ||
66 | int index; | ||
67 | int size_in_bits; | ||
68 | } GetBitContext; | ||
69 | |||
70 | #define VLC_TYPE int16_t | ||
71 | |||
72 | typedef struct VLC { | ||
73 | int bits; | ||
74 | VLC_TYPE (*table)[2]; ///< code, bits | ||
75 | int table_size, table_allocated; | ||
76 | } VLC; | ||
77 | |||
78 | typedef struct RL_VLC_ELEM { | ||
79 | int16_t level; | ||
80 | int8_t len; | ||
81 | uint8_t run; | ||
82 | } RL_VLC_ELEM; | ||
83 | |||
84 | #if defined(ARCH_SPARC) || defined(ARCH_ARMV4L) | ||
85 | #define UNALIGNED_STORES_ARE_BAD | ||
86 | #endif | ||
87 | |||
88 | /* used to avoid missaligned exceptions on some archs (alpha, ...) */ | ||
89 | #if defined(ARCH_X86) || defined(ARCH_X86_64) | ||
90 | # define unaligned32(a) (*(const uint32_t*)(a)) | ||
91 | #else | ||
92 | # ifdef __GNUC__ | ||
93 | static inline uint32_t unaligned32(const void *v) { | ||
94 | struct Unaligned { | ||
95 | uint32_t i; | ||
96 | } __attribute__((packed)); | ||
97 | |||
98 | return ((const struct Unaligned *) v)->i; | ||
99 | } | ||
100 | # elif defined(__DECC) | ||
101 | static inline uint32_t unaligned32(const void *v) { | ||
102 | return *(const __unaligned uint32_t *) v; | ||
103 | } | ||
104 | # else | ||
105 | static inline uint32_t unaligned32(const void *v) { | ||
106 | return *(const uint32_t *) v; | ||
107 | } | ||
108 | # endif | ||
109 | #endif //!ARCH_X86 | ||
110 | |||
111 | |||
112 | /* Bitstream reader API docs: | ||
113 | name | ||
114 | abritary name which is used as prefix for the internal variables | ||
115 | |||
116 | gb | ||
117 | getbitcontext | ||
118 | |||
119 | OPEN_READER(name, gb) | ||
120 | loads gb into local variables | ||
121 | |||
122 | CLOSE_READER(name, gb) | ||
123 | stores local vars in gb | ||
124 | |||
125 | UPDATE_CACHE(name, gb) | ||
126 | refills the internal cache from the bitstream | ||
127 | after this call at least MIN_CACHE_BITS will be available, | ||
128 | |||
129 | GET_CACHE(name, gb) | ||
130 | will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit) | ||
131 | |||
132 | SHOW_UBITS(name, gb, num) | ||
133 | will return the next num bits | ||
134 | |||
135 | SHOW_SBITS(name, gb, num) | ||
136 | will return the next num bits and do sign extension | ||
137 | |||
138 | SKIP_BITS(name, gb, num) | ||
139 | will skip over the next num bits | ||
140 | note, this is equivalent to SKIP_CACHE; SKIP_COUNTER | ||
141 | |||
142 | SKIP_CACHE(name, gb, num) | ||
143 | will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER) | ||
144 | |||
145 | SKIP_COUNTER(name, gb, num) | ||
146 | will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS) | ||
147 | |||
148 | LAST_SKIP_CACHE(name, gb, num) | ||
149 | will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing | ||
150 | |||
151 | LAST_SKIP_BITS(name, gb, num) | ||
152 | is equivalent to SKIP_LAST_CACHE; SKIP_COUNTER | ||
153 | |||
154 | for examples see get_bits, show_bits, skip_bits, get_vlc | ||
155 | */ | ||
156 | |||
157 | static inline int unaligned32_be(const void *v) | ||
158 | { | ||
159 | #ifdef CONFIG_ALIGN | ||
160 | const uint8_t *p=v; | ||
161 | return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); | ||
162 | #else | ||
163 | return betoh32( unaligned32(v)); //original | ||
164 | #endif | ||
165 | } | ||
166 | |||
167 | static inline int unaligned32_le(const void *v) | ||
168 | { | ||
169 | #ifdef CONFIG_ALIGN | ||
170 | const uint8_t *p=v; | ||
171 | return (((p[3]<<8) | p[2])<<16) | (p[1]<<8) | (p[0]); | ||
172 | #else | ||
173 | return letoh32( unaligned32(v)); //original | ||
174 | #endif | ||
175 | } | ||
176 | |||
177 | # define MIN_CACHE_BITS 25 | ||
178 | |||
179 | # define OPEN_READER(name, gb)\ | ||
180 | int name##_index= (gb)->index;\ | ||
181 | int name##_cache= 0;\ | ||
182 | |||
183 | # define CLOSE_READER(name, gb)\ | ||
184 | (gb)->index= name##_index;\ | ||
185 | |||
186 | # ifdef ALT_BITSTREAM_READER_LE | ||
187 | # define UPDATE_CACHE(name, gb)\ | ||
188 | name##_cache= unaligned32_le( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ | ||
189 | |||
190 | # define SKIP_CACHE(name, gb, num)\ | ||
191 | name##_cache >>= (num); | ||
192 | # else | ||
193 | # define UPDATE_CACHE(name, gb)\ | ||
194 | name##_cache= unaligned32_be( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ | ||
195 | |||
196 | # define SKIP_CACHE(name, gb, num)\ | ||
197 | name##_cache <<= (num); | ||
198 | # endif | ||
199 | |||
200 | // FIXME name? | ||
201 | # define SKIP_COUNTER(name, gb, num)\ | ||
202 | name##_index += (num);\ | ||
203 | |||
204 | # define SKIP_BITS(name, gb, num)\ | ||
205 | {\ | ||
206 | SKIP_CACHE(name, gb, num)\ | ||
207 | SKIP_COUNTER(name, gb, num)\ | ||
208 | }\ | ||
209 | |||
210 | # define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) | ||
211 | # define LAST_SKIP_CACHE(name, gb, num) ; | ||
212 | |||
213 | # ifdef ALT_BITSTREAM_READER_LE | ||
214 | # define SHOW_UBITS(name, gb, num)\ | ||
215 | ((name##_cache) & (NEG_USR32(0xffffffff,num))) | ||
216 | # else | ||
217 | # define SHOW_UBITS(name, gb, num)\ | ||
218 | NEG_USR32(name##_cache, num) | ||
219 | # endif | ||
220 | |||
221 | # define SHOW_SBITS(name, gb, num)\ | ||
222 | NEG_SSR32(name##_cache, num) | ||
223 | |||
224 | # define GET_CACHE(name, gb)\ | ||
225 | ((uint32_t)name##_cache) | ||
226 | |||
227 | static inline int get_bits_count(GetBitContext *s){ | ||
228 | return s->index; | ||
229 | } | ||
230 | |||
231 | static inline int get_sbits(GetBitContext *s, int n){ | ||
232 | register int tmp; | ||
233 | OPEN_READER(re, s) | ||
234 | UPDATE_CACHE(re, s) | ||
235 | tmp= SHOW_SBITS(re, s, n); | ||
236 | LAST_SKIP_BITS(re, s, n) | ||
237 | CLOSE_READER(re, s) | ||
238 | return tmp; | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * reads 0-17 bits. | ||
243 | * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't | ||
244 | */ | ||
245 | static inline unsigned int get_bits(GetBitContext *s, int n){ | ||
246 | register int tmp; | ||
247 | OPEN_READER(re, s) | ||
248 | UPDATE_CACHE(re, s) | ||
249 | tmp= SHOW_UBITS(re, s, n); | ||
250 | LAST_SKIP_BITS(re, s, n) | ||
251 | CLOSE_READER(re, s) | ||
252 | return tmp; | ||
253 | } | ||
254 | |||
255 | unsigned int get_bits_long(GetBitContext *s, int n); | ||
256 | |||
257 | /** | ||
258 | * shows 0-17 bits. | ||
259 | * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't | ||
260 | */ | ||
261 | static inline unsigned int show_bits(GetBitContext *s, int n){ | ||
262 | register int tmp; | ||
263 | OPEN_READER(re, s) | ||
264 | UPDATE_CACHE(re, s) | ||
265 | tmp= SHOW_UBITS(re, s, n); | ||
266 | // CLOSE_READER(re, s) | ||
267 | return tmp; | ||
268 | } | ||
269 | |||
270 | unsigned int show_bits_long(GetBitContext *s, int n); | ||
271 | |||
272 | static inline void skip_bits(GetBitContext *s, int n){ | ||
273 | //Note gcc seems to optimize this to s->index+=n for the ALT_READER :)) | ||
274 | OPEN_READER(re, s) | ||
275 | UPDATE_CACHE(re, s) | ||
276 | LAST_SKIP_BITS(re, s, n) | ||
277 | CLOSE_READER(re, s) | ||
278 | } | ||
279 | |||
280 | static inline unsigned int get_bits1(GetBitContext *s){ | ||
281 | int index= s->index; | ||
282 | uint8_t result= s->buffer[ index>>3 ]; | ||
283 | #ifdef ALT_BITSTREAM_READER_LE | ||
284 | result>>= (index&0x07); | ||
285 | result&= 1; | ||
286 | #else | ||
287 | result<<= (index&0x07); | ||
288 | result>>= 8 - 1; | ||
289 | #endif | ||
290 | index++; | ||
291 | s->index= index; | ||
292 | |||
293 | return result; | ||
294 | } | ||
295 | |||
296 | static inline unsigned int show_bits1(GetBitContext *s){ | ||
297 | return show_bits(s, 1); | ||
298 | } | ||
299 | |||
300 | static inline void skip_bits1(GetBitContext *s){ | ||
301 | skip_bits(s, 1); | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * init GetBitContext. | ||
306 | * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits | ||
307 | * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end | ||
308 | * @param bit_size the size of the buffer in bits | ||
309 | */ | ||
310 | static inline void init_get_bits(GetBitContext *s, | ||
311 | const uint8_t *buffer, int bit_size) | ||
312 | { | ||
313 | int buffer_size= (bit_size+7)>>3; | ||
314 | if(buffer_size < 0 || bit_size < 0) { | ||
315 | buffer_size = bit_size = 0; | ||
316 | buffer = 0; | ||
317 | } | ||
318 | |||
319 | s->buffer= buffer; | ||
320 | s->size_in_bits= bit_size; | ||
321 | s->buffer_end= buffer + buffer_size; | ||
322 | s->index=0; | ||
323 | { | ||
324 | OPEN_READER(re, s) | ||
325 | UPDATE_CACHE(re, s) | ||
326 | UPDATE_CACHE(re, s) | ||
327 | CLOSE_READER(re, s) | ||
328 | } | ||
329 | } | ||
330 | |||
331 | void align_get_bits(GetBitContext *s); | ||
332 | |||
333 | #endif /* BITSTREAM_H */ | ||