summaryrefslogtreecommitdiff
path: root/apps/codecs/libwma/common.h
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-07-03 09:25:36 +0000
committerDave Chapman <dave@dchapman.com>2007-07-03 09:25:36 +0000
commitc72824786a0e8c68921ebb9b72f02a2e80aaee17 (patch)
treeadf8dac26d074ee3620df4ab482ff108561ead01 /apps/codecs/libwma/common.h
parent2ca895bae7a25ea8ef7f295b4e8ab01ff75a4914 (diff)
downloadrockbox-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.h387
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
51inline 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
70extern 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
77typedef struct GetBitContext {
78 const uint8_t *buffer, *buffer_end;
79 int index;
80 int size_in_bits;
81} GetBitContext;
82
83static inline int get_bits_count(GetBitContext *s);
84
85/* used to avoid missaligned exceptions on some archs (alpha, ...) */
86static 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:
96name
97 abritary name which is used as prefix for the internal variables
98
99gb
100 getbitcontext
101
102OPEN_READER(name, gb)
103 loads gb into local variables
104
105CLOSE_READER(name, gb)
106 stores local vars in gb
107
108UPDATE_CACHE(name, gb)
109 refills the internal cache from the bitstream
110 after this call at least MIN_CACHE_BITS will be available,
111
112GET_CACHE(name, gb)
113 will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
114
115SHOW_UBITS(name, gb, num)
116 will return the nest num bits
117
118SHOW_SBITS(name, gb, num)
119 will return the nest num bits and do sign extension
120
121SKIP_BITS(name, gb, num)
122 will skip over the next num bits
123 note, this is equinvalent to SKIP_CACHE; SKIP_COUNTER
124
125SKIP_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
128SKIP_COUNTER(name, gb, num)
129 will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
130
131LAST_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
134LAST_SKIP_BITS(name, gb, num)
135 is equinvalent to SKIP_LAST_CACHE; SKIP_COUNTER
136
137for examples see get_bits, show_bits, skip_bits, get_vlc
138*/
139
140static 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
187static 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 */
195static 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
205unsigned 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 */
211static 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
220unsigned int show_bits_long(GetBitContext *s, int n);
221
222static 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
230static 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
241static inline unsigned int show_bits1(GetBitContext *s){
242 return show_bits(s, 1);
243}
244
245static inline void skip_bits1(GetBitContext *s){
246 skip_bits(s, 1);
247}
248
249void init_get_bits(GetBitContext *s,
250 const uint8_t *buffer, int buffer_size);
251
252int check_marker(GetBitContext *s, const char *msg);
253void align_get_bits(GetBitContext *s);
254
255//#define TRACE
256
257#ifdef TRACE
258
259static 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
269static 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}
276static 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}
288static 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
315enum {
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
326extern int st_current_index;
327extern unsigned int st_bit_counts[ST_NB];
328extern unsigned int st_out_bit_counts[ST_NB];
329
330void print_stats(void);
331#endif
332
333/* misc math functions */
334extern const uint8_t ff_log2_tab[256];
335
336static 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
354static 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 */
365extern const uint8_t ff_sqrt_tab[128];
366
367int64_t ff_gcd(int64_t a, int64_t b);
368
369static 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 */