]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - libs/gst/getbits/getbits.c
gst-indent run on core
[glsdk/gstreamer0-10.git] / libs / gst / getbits / getbits.c
1 #include "config.h"
3 #include "getbits.h"
5 /* Defined in gstgetbits_i386.s */
6 extern unsigned long _gst_get1bit_i386 (gst_getbits_t * gb, unsigned long bits);
7 extern unsigned long _gst_getbits_i386 (gst_getbits_t * gb, unsigned long bits);
8 extern unsigned long _gst_getbits_fast_i386 (gst_getbits_t * gb,
9     unsigned long bits);
10 extern unsigned long _gst_showbits_i386 (gst_getbits_t * gb,
11     unsigned long bits);
12 extern void _gst_flushbits_i386 (gst_getbits_t * gb, unsigned long bits);
13 extern void _gst_getbits_back_i386 (gst_getbits_t * gb, unsigned long bits);
15 /* Defined in gstgetbits_generic.c */
16 extern unsigned long _gst_getbits_int_cb (gst_getbits_t * gb,
17     unsigned long bits);
18 extern unsigned long _gst_get1bit_int (gst_getbits_t * gb, unsigned long bits);
19 extern unsigned long _gst_getbits_int (gst_getbits_t * gb, unsigned long bits);
20 extern unsigned long _gst_getbits_fast_int (gst_getbits_t * gb,
21     unsigned long bits);
22 extern unsigned long _gst_showbits_int (gst_getbits_t * gb, unsigned long bits);
23 extern void _gst_flushbits_int (gst_getbits_t * gb, unsigned long bits);
24 extern void _gst_getbits_back_int (gst_getbits_t * gb, unsigned long bits);
27 unsigned long gst_getbits_nBitMask[] = {
28   0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
29   0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
30   0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
31   0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
32   0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
33   0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
34   0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
35   0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe
36 };
38 unsigned long _getbits_masks[] = {
39   0x00000000,
40   0x00000001, 0x00000003, 0x00000007, 0x0000000f,
41   0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
42   0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
43   0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
44   0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
45   0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
46   0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
47   0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
48 };
50 #ifdef unused
51 unsigned long _getbits_64_minus_index[] = {
52   64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
53       45, 44, 43, 42, 41,
54   40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
55       21, 20, 19, 18, 17,
56   16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
57 };
59 /* this routine taken from Intel AppNote AP-527:
60    "Using MMX[tm] Instructions to Get Bits From a Data Stream"
61    written in C with libmmx to *closely* mimic Intel's ASM implementation
63    this isn't as cycle-efficient, due to the simple fact that I must call
64    emms() at the end.  all state must be kept in *gb, not in registers */
65 unsigned long
66 _gst_getbits_mmx (gst_getbits_t * gb, unsigned long bits)
67 {
68   signed long remaining;
69   unsigned long result;
71   /* NOTE: this is a code-size optimization Intel seems to have missed!
72      according to the MMX Programmer's Reference Manual, Chapter 5,
73      neither movd nor movq have any effect on the flags.  that means you
74      can put them before the sub and jl in their code, which I've done
75      symbolically in this C code.  gcc is probably going to lose horribly,
76      I'll do an inline asm version later.  I've a point to prove ;-) */
77   /* find the right shift value, put it in mm3 */
78   movd_m2r (_getbits_64_minus_index[bits], mm3);
79   /* load the current quadword into mm0 */
80   movq_m2r (gb->qword, mm0);
81   /* copy it to mm2 */
82   movq_r2r (mm0, mm2);
84   remaining = gb->bits - bits;
86   if (remaining <= 0) {
87     unsigned long dword1, dword2;
89     /* shift the pointer by 64 bits (8 bytes) */
90     gb->ptr += 8;
91     /* add 64 to bits remaining, to bring it positive */
92     remaining += 64;
94     /* grab the first 32 bits from the buffer and swap them around */
95     dword1 = swab32 (*(gb->ptr - 8));
96     /* grab the second 32 bits, swap */
97     dword2 = swab32 (*(gb->ptr - 4));
99     /* put second dword in mm4 */
100     movd_m2r (dword2, mm4);
101     /* shift mm2 over to make room for new bits */
102     psrlq_r2r (mm3, mm2);
104     /* put first dword in mm1 */
105     movd_m2r (dword1, mm1);
106     /* shift second dword up 32 bits */
107     psrlq_i2r (32, mm4);
109     /* put the shift counter in mm3 */
110     movd_m2r (remaining, mm3);
111     /* combine the swapped data in mm4 */
112     por_r2r (mm1, mm4);
114     /* save off the bits in mm4 to mm0 */
115     movq_r2r (mm4, mm0);
116     /* get the new low-order bits in mm4, shifted by 'mm3' */
117     psrlq_r2r (mm3, mm4);
119     /* save off new remaining bits */
120     gb->bits = remaining;
121     /* combine bits into mm2 */
122     por_r2r (mm2, mm4);
124     /* save off the result */
125     movd_r2m (mm2, result);
126     /* get rid of the bits we just read */
127     psllq_r2r (mm1, mm0);
129     /* save off mm0 */
130     movq_r2m (mm0, gb->qword);
132     /* finished with MMX */
133     emms ();
135     /* we have what we came for */
136     return (result);
137   } else {
138     /* load the number of bits requested into mm1 */
139     movd_m2r (bits, mm1);
140     /* shift the quadword in mm2 by 'mm3' bits */
141     psrlq_r2r (mm3, mm2);
143     /* update the number of valid bits */
144     gb->bits = remaining;
146     /* save off the remaining bits */
147     movd_r2m (mm2, result);
148     /* discard those bits in mm0 */
149     psllq_r2r (mm1, mm0);
151     /* save off mm0 */
152     movq_r2m (mm0, gb->qword);
153     /* finished with MMX */
154     emms ();
156     /* we have what we came for */
157     return (result);
158   }
160 #endif /* HAVE_LIBMMX */
162 unsigned long
163 _gst_getbyte (gst_getbits_t * gb, unsigned long bits)
165   return *gb->ptr++;
168 /* initialize the getbits structure with the proper getbits func */
169 void
170 gst_getbits_init (gst_getbits_t * gb, GstGetbitsCallback callback, void *data)
172   gb->ptr = NULL;
173   gb->bits = 0;
174   gb->callback = callback;
175   gb->data = data;
177 #ifdef unused
178   if (1) {
179     gb->getbits = _gst_getbits_mmx;
180 /*    gb->backbits = _gst_getbits_back_mmx; */
181 /*    gb->backbytes = _gst_getbits_byteback_mmx; */
182 /*    printf("gstgetbits: using MMX optimized versions\n"); */
183   } else
184 #endif /* HAVE_LIBMMX */
185   {
186     if (gb->callback) {
187       gb->getbits = _gst_getbits_int_cb;
188       gb->showbits = _gst_showbits_int;
189       gb->flushbits = _gst_flushbits_int;
190       gb->backbits = _gst_getbits_back_int;
191 /*      printf("gstgetbits: using callback versions\n"); */
192     } else {
193 #ifdef HAVE_CPU_I386
194       gb->get1bit = _gst_get1bit_i386;
195       gb->getbits = _gst_getbits_i386;
196       gb->getbits_fast = _gst_getbits_fast_i386;
197       gb->getbyte = _gst_getbyte;
198       gb->show1bit = _gst_showbits_i386;
199       gb->showbits = _gst_showbits_i386;
200       gb->flushbits = _gst_flushbits_i386;
201       gb->backbits = _gst_getbits_back_i386;
202 /*      printf("gstgetbits: using i386 optimized versions\n"); */
203 #else
204       gb->get1bit = _gst_get1bit_int;
205       gb->getbits = _gst_getbits_int;
206       gb->getbits_fast = _gst_getbits_fast_int;
207       gb->getbyte = _gst_getbyte;
208       gb->show1bit = _gst_showbits_int;
209       gb->showbits = _gst_showbits_int;
210       gb->flushbits = _gst_flushbits_int;
211       gb->backbits = _gst_getbits_back_int;
212 /*      printf("gstgetbits: using normal versions\n"); */
213 #endif
214     }
215   }
218 /* set up the getbits structure with a new buffer */
219 void
220 gst_getbits_newbuf (gst_getbits_t * gb, unsigned char *buffer,
221     unsigned long len)
223   gb->ptr = buffer;
224   gb->endptr = buffer + len;
225   gb->bits = 0;
226 #ifdef unused
227 /*  gb->qword = 0; */
228 #endif /* HAVE_LIBMMX */
232 static gboolean
233 plugin_init (GstPlugin * plugin)
235   return TRUE;
238 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
239     GST_VERSION_MINOR,
240     "gstgetbits",
241     "Accelerated routines for getting bits from a data stream",
242     plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)