I the generc getbits implementation

Original commit message from CVS:
I the generc getbits implementation
This commit is contained in:
Wim Taymans 2000-04-16 18:50:26 +00:00
parent a3443b51d5
commit aa1da33e46
4 changed files with 615 additions and 0 deletions

15
libs/getbits/Makefile.am Normal file
View file

@ -0,0 +1,15 @@
filterdir = $(libdir)/gst
filter_LTLIBRARIES = libgstgetbits.la
libgstgetbits_la_SOURCES = gstgetbits.c gstgetbits_inl.h
libgstgetbitsincludedir = $(includedir)/gst/libs/gstgetbits.h
libgstgetbitsinclude_HEADERS = gstgetbits.h
noinst_HEADERS = gstgetbits.h gstgetbits_inl.h
CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math
INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la

247
libs/getbits/gstgetbits.c Normal file
View file

@ -0,0 +1,247 @@
#include <byteswap.h>
#include "gstgetbits.h"
unsigned long gst_getbits_nBitMask[] = {
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
unsigned long _getbits_masks[] = {
0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000f,
0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
};
#ifdef HAVE_LIBMMX
unsigned long _getbits_64_minus_index[] = {
64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,
40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,
16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 };
/* this routine taken from Intel AppNote AP-527:
"Using MMX[tm] Instructions to Get Bits From a Data Stream"
written in C with libmmx to *closely* mimic Intel's ASM implementation
this isn't as cycle-efficient, due to the simple fact that I must call
emms() at the end. all state must be kept in *gb, not in registers */
unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
signed long remaining;
unsigned long result;
/* NOTE: this is a code-size optimization Intel seems to have missed!
according to the MMX Programmer's Reference Manual, Chapter 5,
neither movd nor movq have any effect on the flags. that means you
can put them before the sub and jl in their code, which I've done
symbolically in this C code. gcc is probably going to lose horribly,
I'll do an inline asm version later. I've a point to prove ;-) */
/* find the right shift value, put it in mm3 */
movd_m2r(_getbits_64_minus_index[bits],mm3);
/* load the current quadword into mm0 */
movq_m2r(gb->qword,mm0);
/* copy it to mm2 */
movq_r2r(mm0,mm2);
remaining = gb->bits - bits;
if (remaining <= 0) {
unsigned long dword1,dword2;
/* shift the pointer by 64 bits (8 bytes) */
gb->ptr += 8;
/* add 64 to bits remaining, to bring it positive */
remaining += 64;
/* grab the first 32 bits from the buffer and swap them around */
dword1 = bswap_32(*(gb->ptr-8));
/* grab the second 32 bits, swap */
dword2 = bswap_32(*(gb->ptr-4));
/* put second dword in mm4 */
movd_m2r(dword2,mm4);
/* shift mm2 over to make room for new bits */
psrlq_r2r(mm3,mm2);
/* put first dword in mm1 */
movd_m2r(dword1,mm1);
/* shift second dword up 32 bits */
psrlq_i2r(32,mm4);
/* put the shift counter in mm3 */
movd_m2r(remaining,mm3);
/* combine the swapped data in mm4 */
por_r2r(mm1,mm4);
/* save off the bits in mm4 to mm0 */
movq_r2r(mm4,mm0);
/* get the new low-order bits in mm4, shifted by 'mm3' */
psrlq_r2r(mm3,mm4);
/* save off new remaining bits */
gb->bits = remaining;
/* combine bits into mm2 */
por_r2r(mm2,mm4);
/* save off the result */
movd_r2m(mm2,result);
/* get rid of the bits we just read */
psllq_r2r(mm1,mm0);
/* save off mm0 */
movq_r2m(mm0,gb->qword);
/* finished with MMX */
emms();
/* we have what we came for */
return(result);
} else {
/* load the number of bits requested into mm1 */
movd_m2r(bits,mm1);
/* shift the quadword in mm2 by 'mm3' bits */
psrlq_r2r(mm3,mm2);
/* update the number of valid bits */
gb->bits = remaining;
/* save off the remaining bits */
movd_r2m(mm2,result);
/* discard those bits in mm0 */
psllq_r2r(mm1,mm0);
/* save off mm0 */
movq_r2m(mm0,gb->qword);
/* finished with MMX */
emms();
/* we have what we came for */
return(result);
}
}
#endif /* HAVE_LIBMMX */
unsigned long getbits_int(gst_getbits_t *gb,unsigned long bits) {
int remaining;
int result = 0;
if (bits == 0) {
// fprintf(stderr,"getbits(0) = 0\n");
return 0;
}
remaining = gb->bits - bits;
if (remaining < 0) {
/* how many bits are left to get? */
remaining = -remaining;
// printf("have to get %d more bits from next dword\n",remaining);
/* move what's left over to accomodate the new stuff */
result = gb->dword >> (32 - bits);
// printf("have \t\t%s from previous dword\n",print_bits(result));
/* get the new word into the buffer */
// fprintf(stderr,"getbits: incrementing %p by 4\n",gb->ptr);
gb->ptr += 4;
gb->dword = bswap_32(*((unsigned long *)(gb->ptr)));
// gb->dword = *((unsigned char *)(gb->ptr)) << 24 |
// *((unsigned char *)(gb->ptr)+1) << 16 |
// *((unsigned char *)(gb->ptr)+2) << 8 |
// *((unsigned char *)(gb->ptr)+3);
// gb->dword = *((unsigned long *)(gb->ptr));
gb->bits = 32;
// fprintf(stderr,"got new dword %08x\n",gb->dword);
/* & in the right number of bits */
result |= (gb->dword >> (32 - remaining));
/* shift the buffer over */
gb->dword <<= remaining;
/* record how many bits are left */
gb->bits -= remaining;
} else {
result = gb->dword >> (32 - bits);
gb->dword <<= bits;
gb->bits -= bits;
// printf("have %d bits left\n",gb->bits);
}
// printf("have \t\t%s left\n",print_bits(gb->dword));
// fprintf(stderr,"getbits.c:getbits(%ld) = %d\n",bits,result);
return result;
}
void getbits_back_int(gst_getbits_t *gb,unsigned long bits) {
fprintf(stderr,"getbits.c:getbits_back(%lu)\n",bits);
// moving within the same dword...
if ((bits + gb->bits) <= 32) {
fprintf(stderr,"moving back %lu bits in the same dword\n",bits);
gb->bits += bits;
// otherwise we're going to have move the pointer (ick)
} else {
// rare case where we're moving a multiple of 32 bits...
if ((bits % 32) == 0) {
fprintf(stderr,"moving back exactly %lu dwords\n",bits/32);
gb->ptr -= (bits / 8);
// we have to both shift bits and the pointer (NOOOOOOO!)
} else {
// strip off the first dword
bits -= (32 - gb->bits);
gb->ptr -= 4;
// now strip off as many others as necessary
gb->ptr -= 4 * (bits/32);
// and set the bits to what's left
gb->bits = bits % 32;
fprintf(stderr,"moved back %lu bytes to %p\n",4 * ((bits/32)+1),gb->ptr);
}
}
gb->dword = bswap_32(*((unsigned long *)(gb->ptr)));
fprintf(stderr,"orignal new loaded word is %08x\n",gb->dword);
gb->dword <<= (32 - gb->bits);
fprintf(stderr,"shifted (by %lu) word is %08x\n",gb->bits,gb->dword);
}
void getbits_byteback_int(gst_getbits_t *gb,unsigned long bytes) {
fprintf(stderr,"getbits.c:getbits_byteback(%lu)\n",bytes);
getbits_back_int(gb,bytes*8);
gb->bits = gb->bits & ~0x07;
}
int getbits_offset(gst_getbits_t *gb) {
fprintf(stderr,"getbits.c:getbits_offset() = %lu\n",gb->bits % 8);
return gb->bits % 8;
}
/* initialize the getbits structure with the proper getbits func */
void getbits_init(gst_getbits_t *gb) {
gb->ptr = NULL;
gb->bits = 0;
#ifdef HAVE_LIBMMX
if (1) {
gb->getbits = getbits_mmx;
// gb->backbits = getbits_back_mmx;
// gb->backbytes = getbits_byteback_mmx;
} else
#endif /* HAVE_LIBMMX */
{
gb->getbits = getbits_int;
gb->backbits = getbits_back_int;
gb->backbytes = getbits_byteback_int;
}
}
/* set up the getbits structure with a new buffer */
void getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer) {
gb->ptr = buffer - 4;
// fprintf(stderr,"setting ptr to %p\n",gb->ptr);
gb->bits = 0;
gb->dword = 0;
#ifdef HAVE_LIBMMX
// gb->qword = 0;
#endif /* HAVE_LIBMMX */
}

57
libs/getbits/gstgetbits.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef __GST_GETBITS_H__
#define __GST_GETBITS_H__
#include <stdio.h>
#include <config.h>
#undef HAVE_LIBMMX
#include <byteswap.h>
#ifdef HAVE_LIBMMX
#include <mmx.h>
#endif /* HAVE_LIBMMX */
#ifdef HAVE_LIBSSE
#include <sse.h>
#endif /* HAVE_LIBSSE */
typedef struct _gst_getbits_t gst_getbits_t;
/* breaks in structure show alignment on quadword boundaries */
/* FIXME: need to find out how to force GCC to align this to octwords */
struct _gst_getbits_t {
unsigned char *ptr;
unsigned long *longptr;
long bits;
unsigned long dword;
unsigned long temp;
unsigned long (*getbits)(gst_getbits_t *gb,unsigned long bits); /* dword */
void (*backbits)(gst_getbits_t *gb,unsigned long bits); /* dword */
void (*backbytes)(gst_getbits_t *gb,unsigned long bytes); /* dword */
#ifdef HAVE_LIBMMX
mmx_t qword; /* qword */
#endif /* HAVE_LIBMMX */
#ifdef HAVE_LIBSSE
sse_t oword; /* oword */
#endif /* HAVE_LIBSSE */
};
#define GST_GETBITS_INLINE
#ifdef GST_GETBITS_INLINE
#include "gstgetbits_inl.h"
#else
void gst_getbits_init(gst_getbits_t *gb);
void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer);
#define getbits(gb,bits) (((gb)->getbits)(gb,bits))
#define getbits_back(gb,bits) (((gb)->backbits)(gb,bits))
#define getbits_back_bytes(gb,bytes) (((gb)->backbytes)(gb,bytes))
#endif
#endif /* __GST_GETBITS_H__ */

View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
Changes to make the code reentrant:
deglobalized: curBits, curVidStream
deglobalized: bitOffset, bitLength, bitBuffer in vid_stream, not used
here
Additional changes:
-lsh@cs.brown.edu (Loring Holden)
*/
#ifndef __GST_GETBITS_INL_H__
#define __GST_GETBITS_INL_H__
#include <glib.h>
//#define DEBUG_ENABLED
#ifdef DEBUG_ENABLED
#define debug2(format,args...) g_print(format,##args)
#define debug(format,args...) g_print(format,##args),
#else
#define debug(format,args...)
#define debug2(format,args...)
#endif
#ifdef WORDS_BIGENDIAN
# define swab32(x) (x)
#else
# if defined (__i386__)
# define swab32(x) __i386_swab32(x)
static inline const guint32 __i386_swab32(guint32 x)
{
__asm__("bswap %0" : "=r" (x) : "0" (x));
return x;
}
# else
# define swab32(x)\
((((guint8*)&x)[0] << 24) | (((guint8*)&x)[1] << 16) | \
(((guint8*)&x)[2] << 8) | (((guint8*)&x)[3]))
# endif
#endif
/* External declarations for bitstream i/o operations. */
extern unsigned long gst_getbits_nBitMask[];
#define gst_getbits_init(gb)
#define gst_getbits_newbuf(gb, buffer) \
{ \
(gb)->longptr = (unsigned long *)buffer; \
(gb)->bits = 0; \
(gb)->dword = swab32(*(gb)->longptr); \
}
#define gst_getbits_bitoffset(gb) \
( \
debug("bitoffset: %ld %p\n", (gb)->bits, (gb)->longptr) \
(gb)->bits \
)
#define gst_getbits_bufferpos(gb) ((gb)->longptr)
#define gst_getbits1(gb) \
( \
((gb)->temp = (((gb)->dword & 0x80000000) != 0)), \
(gb)->dword <<= 1, \
(gb)->bits++, \
\
((gb)->bits & 0x20 ? ( \
(gb)->bits = 0, \
(gb)->longptr++, \
((gb)->dword = swab32(*(gb)->longptr)) \
) \
:0), \
debug("getbits1 : %04lx %08lx %p\n", (gb)->temp, (gb)->dword, (gb)->longptr) \
(gb)->temp \
)
#define gst_getbits2(gb) \
( \
(gb)->bits += 2, \
\
((gb)->bits & 0x20 ? ( \
(gb)->bits -= 32, \
(gb)->longptr++, \
((gb)->bits ? ( \
((gb)->dword |= \
(*(gb)->longptr >> (2 - (gb)->bits))) \
) \
: 0 \
), \
((gb)->temp = (((gb)->dword & 0xc0000000) >> 30)), \
((gb)->dword = swab32(*(gb)->longptr) << (gb)->bits) \
) \
: ( \
((gb)->temp = (((gb)->dword & 0xc0000000) >> 30)), \
((gb)->dword <<= 2) \
) \
), \
debug("getbits2 : %04lx %08lx %p\n", (gb)->temp, (gb)->dword, (gb)->longptr) \
(gb)->temp \
)
#define gst_getbitsX(gb, num, mask, shift) \
( \
(gb)->bits += num, \
\
((gb)->bits & 0x20 ? ( \
(gb)->bits -= 32, \
(gb)->longptr++, \
((gb)->bits ? ( \
((gb)->dword |= (swab32(*(gb)->longptr) >> \
(num - (gb)->bits))) \
) \
:0 \
), \
((gb)->temp = (((gb)->dword & mask) >> shift)), \
((gb)->dword = swab32(*(gb)->longptr) << (gb)->bits) \
) \
: ( \
((gb)->temp = (((gb)->dword & mask) >> shift)), \
((gb)->dword <<= num) \
) \
), \
debug("getbits%-2d: %04lx %08lx %lu %p\n", num, (gb)->temp, (gb)->dword, mask, (gb)->longptr) \
(gb)->temp \
)
#define gst_getbits3(gb) gst_getbitsX(gb, 3, 0xe0000000UL, 29)
#define gst_getbits4(gb) gst_getbitsX(gb, 4, 0xf0000000UL, 28)
#define gst_getbits5(gb) gst_getbitsX(gb, 5, 0xf8000000UL, 27)
#define gst_getbits6(gb) gst_getbitsX(gb, 6, 0xfc000000UL, 26)
#define gst_getbits7(gb) gst_getbitsX(gb, 7, 0xfe000000UL, 25)
#define gst_getbits8(gb) gst_getbitsX(gb, 8, 0xff000000UL, 24)
#define gst_getbits9(gb) gst_getbitsX(gb, 9, 0xff800000UL, 23)
#define gst_getbits10(gb) gst_getbitsX(gb, 10, 0xffc00000UL, 22)
#define gst_getbits11(gb) gst_getbitsX(gb, 11, 0xffe00000UL, 21)
#define gst_getbits12(gb) gst_getbitsX(gb, 12, 0xfff00000UL, 20)
#define gst_getbits13(gb) gst_getbitsX(gb, 13, 0xfff80000UL, 19)
#define gst_getbits14(gb) gst_getbitsX(gb, 14, 0xfffc0000UL, 18)
#define gst_getbits15(gb) gst_getbitsX(gb, 15, 0xfffe0000UL, 17)
#define gst_getbits16(gb) gst_getbitsX(gb, 16, 0xffff0000UL, 16)
#define gst_getbits17(gb) gst_getbitsX(gb, 17, 0xffff8000UL, 15)
#define gst_getbits18(gb) gst_getbitsX(gb, 18, 0xffffc000UL, 14)
#define gst_getbits19(gb) gst_getbitsX(gb, 19, 0xffffe000UL, 13)
#define gst_getbits20(gb) gst_getbitsX(gb, 20, 0xfffff000UL, 12)
#define gst_getbits21(gb) gst_getbitsX(gb, 21, 0xfffff800UL, 11)
#define gst_getbits22(gb) gst_getbitsX(gb, 22, 0xfffffc00UL, 10)
#define gst_getbits32(gb) gst_getbitsX(gb, 32, 0xffffffffUL, 0)
#define gst_getbitsn(gb,num) gst_getbitsX(gb, (num), (num ? ((0xffffffffUL) << (32-num)):0), (32-(num)))
#define gst_showbits32(gb) \
( \
((gb)->bits ? ( \
(gb)->dword | (swab32(*((gb)->longptr+1)) >> \
(32 - (gb)->bits)) \
) \
: ( \
(gb)->dword \
) \
) \
)
#define gst_showbitsX(gb, num, mask, shift) \
( \
((gb)->temp = (gb)->bits + num), \
((gb)->temp > 32 ? ( \
(gb)->temp -= 32, \
(((gb)->dword & mask) >> shift) | \
(swab32(*((gb)->longptr+1)) >> (shift + (num - (gb)->temp))) \
) \
: ( \
(((gb)->dword & mask) >> shift) \
) \
) \
)
#define gst_showbits1(gb) gst_showbitsX(gb, 1, 0x80000000, 31)
#define gst_showbits2(gb) gst_showbitsX(gb, 2, 0xc0000000, 30)
#define gst_showbits3(gb) gst_showbitsX(gb, 3, 0xe0000000, 29)
#define gst_showbits4(gb) gst_showbitsX(gb, 4, 0xf0000000, 28)
#define gst_showbits5(gb) gst_showbitsX(gb, 5, 0xf8000000, 27)
#define gst_showbits6(gb) gst_showbitsX(gb, 6, 0xfc000000, 26)
#define gst_showbits7(gb) gst_showbitsX(gb, 7, 0xfe000000, 25)
#define gst_showbits8(gb) gst_showbitsX(gb, 8, 0xff000000, 24)
#define gst_showbits9(gb) gst_showbitsX(gb, 9, 0xff800000, 23)
#define gst_showbits10(gb) gst_showbitsX(gb, 10, 0xffc00000, 22)
#define gst_showbits11(gb) gst_showbitsX(gb, 11, 0xffe00000, 21)
#define gst_showbits12(gb) gst_showbitsX(gb, 12, 0xfff00000, 20)
#define gst_showbits13(gb) gst_showbitsX(gb, 13, 0xfff80000, 19)
#define gst_showbits14(gb) gst_showbitsX(gb, 14, 0xfffc0000, 18)
#define gst_showbits15(gb) gst_showbitsX(gb, 15, 0xfffe0000, 17)
#define gst_showbits16(gb) gst_showbitsX(gb, 16, 0xffff0000, 16)
#define gst_showbits17(gb) gst_showbitsX(gb, 17, 0xffff8000, 15)
#define gst_showbits18(gb) gst_showbitsX(gb, 18, 0xffffc000, 14)
#define gst_showbits19(gb) gst_showbitsX(gb, 19, 0xffffe000, 13)
#define gst_showbits20(gb) gst_showbitsX(gb, 20, 0xfffff000, 12)
#define gst_showbits21(gb) gst_showbitsX(gb, 21, 0xfffff800, 11)
#define gst_showbits22(gb) gst_showbitsX(gb, 22, 0xfffffc00, 10)
#define gst_showbits23(gb) gst_showbitsX(gb, 23, 0xfffffe00, 9)
#define gst_showbits24(gb) gst_showbitsX(gb, 24, 0xffffff00, 8)
#define gst_showbits25(gb) gst_showbitsX(gb, 25, 0xffffff80, 7)
#define gst_showbits26(gb) gst_showbitsX(gb, 26, 0xffffffc0, 6)
#define gst_showbits27(gb) gst_showbitsX(gb, 27, 0xffffffe0, 5)
#define gst_showbits28(gb) gst_showbitsX(gb, 28, 0xfffffff0, 4)
#define gst_showbits29(gb) gst_showbitsX(gb, 29, 0xfffffff8, 3)
#define gst_showbits30(gb) gst_showbitsX(gb, 30, 0xfffffffc, 2)
#define gst_showbits31(gb) gst_showbitsX(gb, 31, 0xfffffffe, 1)
#define gst_showbitsn(gb,num) gst_showbitsX(gb, (num), ((0xffffffff) << (32-num)), (32-(num)))
#define gst_flushbits32(gb) \
{ \
(gb)->longptr++; \
(gb)->dword = swab32(*(gb)->longptr) << (gb)->bits; \
}
#define gst_flushbits(gb, num) \
{ \
(gb)->bits += num; \
\
if ((gb)->bits & 0x20) { \
(gb)->bits -= 32; \
(gb)->longptr++; \
(gb)->dword = swab32(*(gb)->longptr) << (gb)->bits; \
} \
else { \
(gb)->dword <<= num; \
} \
}
#define gst_backbits24(gb) \
{ \
(gb)->bits -= 24; \
if ((gb)->bits < 0) { \
(gb)->bits += 32; \
(gb)->longptr--; \
} \
(gb)->dword = swab32(*(gb)->longptr) << (gb)->bits; \
}
#define gst_backbitsn(gb, num) \
{ \
(gb)->bits -= num; \
while ((gb)->bits < 0) { \
(gb)->bits += 32; \
(gb)->longptr--; \
} \
(gb)->dword = swab32(*(gb)->longptr) << (gb)->bits; \
debug2("backbits%-2d: %08lx %p\n", num, (gb)->dword, (gb)->longptr); \
}
#endif /* __GST_GETBITS_INL_H__ */