diff options
author | Dave Chapman <dave@dchapman.com> | 2007-07-03 09:25:36 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-07-03 09:25:36 +0000 |
commit | c72824786a0e8c68921ebb9b72f02a2e80aaee17 (patch) | |
tree | adf8dac26d074ee3620df4ab482ff108561ead01 /apps/codecs/libwma/common.h | |
parent | 2ca895bae7a25ea8ef7f295b4e8ab01ff75a4914 (diff) | |
download | rockbox-c72824786a0e8c68921ebb9b72f02a2e80aaee17.tar.gz rockbox-c72824786a0e8c68921ebb9b72f02a2e80aaee17.zip |
Initial, work-in-progress, version of a WMA codec using Michael Giacomelli's fixed-point and malloc-less WMA decoder (based on the ffmpeg WMA decoder from early 2006, and also building on the work started by Paul Jones). The codec itself and the ASF parsing code were written by me, inspired by the ASF parser in libasf. Current performance is around 400% realtime on gigabeat, 100% realtime on PP and 20% realtime on Coldfire.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13769 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwma/common.h')
-rw-r--r-- | apps/codecs/libwma/common.h | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/apps/codecs/libwma/common.h b/apps/codecs/libwma/common.h new file mode 100644 index 0000000000..dc55dcaed2 --- /dev/null +++ b/apps/codecs/libwma/common.h | |||
@@ -0,0 +1,387 @@ | |||
1 | /** | ||
2 | * @file common.h | ||
3 | * common internal api header. | ||
4 | */ | ||
5 | |||
6 | #ifndef COMMON_H | ||
7 | #define COMMON_H | ||
8 | |||
9 | /* only include the following when compiling package */ | ||
10 | #include "ffmpeg_config.h" | ||
11 | |||
12 | #include <stdlib.h> | ||
13 | #include <stdio.h> | ||
14 | #include <string.h> | ||
15 | #include <ctype.h> | ||
16 | #include <math.h> | ||
17 | #include <stddef.h> | ||
18 | #include <inttypes.h> | ||
19 | |||
20 | #ifndef M_PI | ||
21 | #define M_PI 3.14159265358979323846 | ||
22 | #endif | ||
23 | |||
24 | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) | ||
25 | # define always_inline __attribute__((always_inline)) inline | ||
26 | #else | ||
27 | # define always_inline inline | ||
28 | #endif | ||
29 | |||
30 | #ifndef INT64_MAX | ||
31 | #define INT64_MAX 9223372036854775807LL | ||
32 | #endif | ||
33 | |||
34 | # if defined(__MINGW32__) || defined(__CYGWIN__) || \ | ||
35 | defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__)) | ||
36 | # define MANGLE(a) "_" #a | ||
37 | # else | ||
38 | # define MANGLE(a) #a | ||
39 | # endif | ||
40 | |||
41 | /* debug stuff */ | ||
42 | |||
43 | # ifndef DEBUG | ||
44 | # define NDEBUG | ||
45 | # endif | ||
46 | # include <assert.h> | ||
47 | |||
48 | /* dprintf macros */ | ||
49 | # if defined(CONFIG_WIN32) && !defined(__MINGW32__) | ||
50 | |||
51 | inline void dprintf(const char* fmt,...) {} | ||
52 | |||
53 | # else | ||
54 | |||
55 | # ifdef DEBUG | ||
56 | # define dprintf(fmt,...) printf(fmt, __VA_ARGS__) | ||
57 | # else | ||
58 | # define dprintf(fmt,...) | ||
59 | # endif | ||
60 | |||
61 | # endif /* !CONFIG_WIN32 */ | ||
62 | |||
63 | # define av_abort() do { av_log(AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0) | ||
64 | |||
65 | //rounded divison & shift | ||
66 | #define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b)) | ||
67 | /* assume b>0 */ | ||
68 | #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) | ||
69 | |||
70 | extern const uint32_t inverse[256]; | ||
71 | |||
72 | #define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) | ||
73 | #define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) | ||
74 | |||
75 | /* bit input */ | ||
76 | |||
77 | typedef struct GetBitContext { | ||
78 | const uint8_t *buffer, *buffer_end; | ||
79 | int index; | ||
80 | int size_in_bits; | ||
81 | } GetBitContext; | ||
82 | |||
83 | static inline int get_bits_count(GetBitContext *s); | ||
84 | |||
85 | /* used to avoid missaligned exceptions on some archs (alpha, ...) */ | ||
86 | static inline uint32_t unaligned32(const void *v) { | ||
87 | struct Unaligned { | ||
88 | uint32_t i; | ||
89 | } __attribute__((packed)); | ||
90 | |||
91 | return ((const struct Unaligned *) v)->i; | ||
92 | } | ||
93 | |||
94 | |||
95 | /* Bitstream reader API docs: | ||
96 | name | ||
97 | abritary name which is used as prefix for the internal variables | ||
98 | |||
99 | gb | ||
100 | getbitcontext | ||
101 | |||
102 | OPEN_READER(name, gb) | ||
103 | loads gb into local variables | ||
104 | |||
105 | CLOSE_READER(name, gb) | ||
106 | stores local vars in gb | ||
107 | |||
108 | UPDATE_CACHE(name, gb) | ||
109 | refills the internal cache from the bitstream | ||
110 | after this call at least MIN_CACHE_BITS will be available, | ||
111 | |||
112 | GET_CACHE(name, gb) | ||
113 | will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit) | ||
114 | |||
115 | SHOW_UBITS(name, gb, num) | ||
116 | will return the nest num bits | ||
117 | |||
118 | SHOW_SBITS(name, gb, num) | ||
119 | will return the nest num bits and do sign extension | ||
120 | |||
121 | SKIP_BITS(name, gb, num) | ||
122 | will skip over the next num bits | ||
123 | note, this is equinvalent to SKIP_CACHE; SKIP_COUNTER | ||
124 | |||
125 | SKIP_CACHE(name, gb, num) | ||
126 | will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER) | ||
127 | |||
128 | SKIP_COUNTER(name, gb, num) | ||
129 | will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS) | ||
130 | |||
131 | LAST_SKIP_CACHE(name, gb, num) | ||
132 | will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing | ||
133 | |||
134 | LAST_SKIP_BITS(name, gb, num) | ||
135 | is equinvalent to SKIP_LAST_CACHE; SKIP_COUNTER | ||
136 | |||
137 | for examples see get_bits, show_bits, skip_bits, get_vlc | ||
138 | */ | ||
139 | |||
140 | static inline int unaligned32_be(const void *v) | ||
141 | { | ||
142 | #ifdef CONFIG_ALIGN | ||
143 | const uint8_t *p=v; | ||
144 | return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); | ||
145 | #else | ||
146 | return be2me_32( unaligned32(v)); //original | ||
147 | #endif | ||
148 | } | ||
149 | |||
150 | #define MIN_CACHE_BITS 25 | ||
151 | |||
152 | #define OPEN_READER(name, gb)\ | ||
153 | int name##_index= (gb)->index;\ | ||
154 | int name##_cache= 0;\ | ||
155 | |||
156 | #define CLOSE_READER(name, gb)\ | ||
157 | (gb)->index= name##_index;\ | ||
158 | |||
159 | #define UPDATE_CACHE(name, gb)\ | ||
160 | name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ | ||
161 | |||
162 | #define SKIP_CACHE(name, gb, num)\ | ||
163 | name##_cache <<= (num);\ | ||
164 | |||
165 | // FIXME name? | ||
166 | #define SKIP_COUNTER(name, gb, num)\ | ||
167 | name##_index += (num);\ | ||
168 | |||
169 | #define SKIP_BITS(name, gb, num)\ | ||
170 | {\ | ||
171 | SKIP_CACHE(name, gb, num)\ | ||
172 | SKIP_COUNTER(name, gb, num)\ | ||
173 | }\ | ||
174 | |||
175 | #define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) | ||
176 | #define LAST_SKIP_CACHE(name, gb, num) ; | ||
177 | |||
178 | #define SHOW_UBITS(name, gb, num)\ | ||
179 | NEG_USR32(name##_cache, num) | ||
180 | |||
181 | #define SHOW_SBITS(name, gb, num)\ | ||
182 | NEG_SSR32(name##_cache, num) | ||
183 | |||
184 | #define GET_CACHE(name, gb)\ | ||
185 | ((uint32_t)name##_cache) | ||
186 | |||
187 | static inline int get_bits_count(GetBitContext *s){ | ||
188 | return s->index; | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * reads 0-17 bits. | ||
193 | * Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant | ||
194 | */ | ||
195 | static inline unsigned int get_bits(GetBitContext *s, int n){ | ||
196 | register int tmp; | ||
197 | OPEN_READER(re, s) | ||
198 | UPDATE_CACHE(re, s) | ||
199 | tmp= SHOW_UBITS(re, s, n); | ||
200 | LAST_SKIP_BITS(re, s, n) | ||
201 | CLOSE_READER(re, s) | ||
202 | return tmp; | ||
203 | } | ||
204 | |||
205 | unsigned int get_bits_long(GetBitContext *s, int n); | ||
206 | |||
207 | /** | ||
208 | * shows 0-17 bits. | ||
209 | * Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant | ||
210 | */ | ||
211 | static inline unsigned int show_bits(GetBitContext *s, int n){ | ||
212 | register int tmp; | ||
213 | OPEN_READER(re, s) | ||
214 | UPDATE_CACHE(re, s) | ||
215 | tmp= SHOW_UBITS(re, s, n); | ||
216 | // CLOSE_READER(re, s) | ||
217 | return tmp; | ||
218 | } | ||
219 | |||
220 | unsigned int show_bits_long(GetBitContext *s, int n); | ||
221 | |||
222 | static inline void skip_bits(GetBitContext *s, int n){ | ||
223 | //Note gcc seems to optimize this to s->index+=n for the ALT_READER :)) | ||
224 | OPEN_READER(re, s) | ||
225 | UPDATE_CACHE(re, s) | ||
226 | LAST_SKIP_BITS(re, s, n) | ||
227 | CLOSE_READER(re, s) | ||
228 | } | ||
229 | |||
230 | static inline unsigned int get_bits1(GetBitContext *s){ | ||
231 | int index= s->index; | ||
232 | uint8_t result= s->buffer[ index>>3 ]; | ||
233 | result<<= (index&0x07); | ||
234 | result>>= 8 - 1; | ||
235 | index++; | ||
236 | s->index= index; | ||
237 | |||
238 | return result; | ||
239 | } | ||
240 | |||
241 | static inline unsigned int show_bits1(GetBitContext *s){ | ||
242 | return show_bits(s, 1); | ||
243 | } | ||
244 | |||
245 | static inline void skip_bits1(GetBitContext *s){ | ||
246 | skip_bits(s, 1); | ||
247 | } | ||
248 | |||
249 | void init_get_bits(GetBitContext *s, | ||
250 | const uint8_t *buffer, int buffer_size); | ||
251 | |||
252 | int check_marker(GetBitContext *s, const char *msg); | ||
253 | void align_get_bits(GetBitContext *s); | ||
254 | |||
255 | //#define TRACE | ||
256 | |||
257 | #ifdef TRACE | ||
258 | |||
259 | static inline void print_bin(int bits, int n){ | ||
260 | int i; | ||
261 | |||
262 | for(i=n-1; i>=0; i--){ | ||
263 | printf("%d", (bits>>i)&1); | ||
264 | } | ||
265 | for(i=n; i<24; i++) | ||
266 | printf(" "); | ||
267 | } | ||
268 | |||
269 | static inline int get_bits_trace(GetBitContext *s, int n, char *file, char *func, int line){ | ||
270 | int r= get_bits(s, n); | ||
271 | |||
272 | print_bin(r, n); | ||
273 | printf("%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line); | ||
274 | return r; | ||
275 | } | ||
276 | static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, char *func, int line){ | ||
277 | int show= show_bits(s, 24); | ||
278 | int pos= get_bits_count(s); | ||
279 | int r= get_vlc2(s, table, bits, max_depth); | ||
280 | int len= get_bits_count(s) - pos; | ||
281 | int bits2= show>>(24-len); | ||
282 | |||
283 | print_bin(bits2, len); | ||
284 | |||
285 | printf("%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line); | ||
286 | return r; | ||
287 | } | ||
288 | static inline int get_xbits_trace(GetBitContext *s, int n, char *file, char *func, int line){ | ||
289 | int show= show_bits(s, n); | ||
290 | int r= get_xbits(s, n); | ||
291 | |||
292 | print_bin(show, n); | ||
293 | printf("%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line); | ||
294 | return r; | ||
295 | } | ||
296 | |||
297 | #define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) | ||
298 | #define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__) | ||
299 | #define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) | ||
300 | #define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__) | ||
301 | #define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__) | ||
302 | |||
303 | #define tprintf printf | ||
304 | |||
305 | #else //TRACE | ||
306 | #define tprintf(_arg...) {} | ||
307 | #endif | ||
308 | |||
309 | /* define it to include statistics code (useful only for optimizing | ||
310 | codec efficiency */ | ||
311 | //#define STATS | ||
312 | |||
313 | #ifdef STATS | ||
314 | |||
315 | enum { | ||
316 | ST_UNKNOWN, | ||
317 | ST_DC, | ||
318 | ST_INTRA_AC, | ||
319 | ST_INTER_AC, | ||
320 | ST_INTRA_MB, | ||
321 | ST_INTER_MB, | ||
322 | ST_MV, | ||
323 | ST_NB, | ||
324 | }; | ||
325 | |||
326 | extern int st_current_index; | ||
327 | extern unsigned int st_bit_counts[ST_NB]; | ||
328 | extern unsigned int st_out_bit_counts[ST_NB]; | ||
329 | |||
330 | void print_stats(void); | ||
331 | #endif | ||
332 | |||
333 | /* misc math functions */ | ||
334 | extern const uint8_t ff_log2_tab[256]; | ||
335 | |||
336 | static inline int av_log2(unsigned int v) | ||
337 | { | ||
338 | int n; | ||
339 | |||
340 | n = 0; | ||
341 | if (v & 0xffff0000) { | ||
342 | v >>= 16; | ||
343 | n += 16; | ||
344 | } | ||
345 | if (v & 0xff00) { | ||
346 | v >>= 8; | ||
347 | n += 8; | ||
348 | } | ||
349 | n += ff_log2_tab[v]; | ||
350 | |||
351 | return n; | ||
352 | } | ||
353 | |||
354 | static inline int clip(int a, int amin, int amax) | ||
355 | { | ||
356 | if (a < amin) | ||
357 | return amin; | ||
358 | else if (a > amax) | ||
359 | return amax; | ||
360 | else | ||
361 | return a; | ||
362 | } | ||
363 | |||
364 | /* math */ | ||
365 | extern const uint8_t ff_sqrt_tab[128]; | ||
366 | |||
367 | int64_t ff_gcd(int64_t a, int64_t b); | ||
368 | |||
369 | static inline int ff_sqrt(int a) | ||
370 | { | ||
371 | int ret=0; | ||
372 | int s; | ||
373 | int ret_sq=0; | ||
374 | |||
375 | if(a<128) return ff_sqrt_tab[a]; | ||
376 | |||
377 | for(s=15; s>=0; s--){ | ||
378 | int b= ret_sq + (1<<(s*2)) + (ret<<s)*2; | ||
379 | if(b<=a){ | ||
380 | ret_sq=b; | ||
381 | ret+= 1<<s; | ||
382 | } | ||
383 | } | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | #endif /* COMMON_H */ | ||