mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
I the generc getbits implementation
Original commit message from CVS: I the generc getbits implementation
This commit is contained in:
parent
a3443b51d5
commit
aa1da33e46
4 changed files with 615 additions and 0 deletions
15
libs/getbits/Makefile.am
Normal file
15
libs/getbits/Makefile.am
Normal 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
247
libs/getbits/gstgetbits.c
Normal 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
57
libs/getbits/gstgetbits.h
Normal 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__ */
|
296
libs/getbits/gstgetbits_inl.h
Normal file
296
libs/getbits/gstgetbits_inl.h
Normal 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__ */
|
Loading…
Reference in a new issue