Newer
Older
/**
* @file common.h
* common internal api header.
*/
#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# define CONFIG_WIN32
Michael Niedermayer
committed
//#define ALT_BITSTREAM_WRITER
Michael Niedermayer
committed
//#define ALIGNED_BITSTREAM_WRITER
Michael Niedermayer
committed
#define ALT_BITSTREAM_READER
//#define LIBMPEG2_BITSTREAM_READER
//#define A32_BITSTREAM_READER
#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO
Michael Niedermayer
committed
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
# include "config.h"
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# ifndef __BEOS__
# include <errno.h>
# else
# include "berrno.h"
# endif
# include <math.h>
# ifndef ENODATA
# define ENODATA 61
# endif
#include <stddef.h>
#ifndef offsetof
# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F))
#endif
#define AVOPTION_CODEC_BOOL(name, help, field) \
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_BOOL }
#define AVOPTION_CODEC_DOUBLE(name, help, field, minv, maxv, defval) \
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_DOUBLE, minv, maxv, defval }
#define AVOPTION_CODEC_FLAG(name, help, field, flag, defval) \
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_FLAG, flag, 0, defval }
#define AVOPTION_CODEC_INT(name, help, field, minv, maxv, defval) \
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_INT, minv, maxv, defval }
#define AVOPTION_CODEC_STRING(name, help, field, str, val) \
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_STRING, .defval = val, .defstr = str }
#define AVOPTION_CODEC_RCOVERRIDE(name, help, field) \
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_RCOVERRIDE, .defval = 0, .defstr = NULL }
#define AVOPTION_SUB(ptr) { .name = NULL, .help = (const char*)ptr }
#define AVOPTION_END() AVOPTION_SUB(NULL)
struct AVOption;
#ifdef HAVE_MMX
extern const struct AVOption avoptions_common[3 + 5];
#else
extern const struct AVOption avoptions_common[3];
#endif
extern const struct AVOption avoptions_workaround_bug[11];
#endif /* HAVE_AV_CONFIG_H */
/* Suppress restrict if it was not defined in config.h. */
#ifndef restrict
# define restrict
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define always_inline __attribute__((always_inline)) inline
# define always_inline inline
Michael Niedermayer
committed
#ifndef EMULATE_INTTYPES
Chris Flerackers
committed
# include <inttypes.h>
#else
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
# ifdef CONFIG_WIN32
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
# else /* other OS */
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
# endif /* other OS */
#endif /* HAVE_INTTYPES_H */
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807LL
#endif
#ifdef EMULATE_FAST_INT
/* note that we don't emulate 64bit ints */
typedef signed char int_fast8_t;
typedef signed int int_fast16_t;
typedef signed int int_fast32_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
#endif
#if defined(CONFIG_OS2) || defined(CONFIG_SUNOS)
static inline float floorf(float f) {
return floor(f);
}
#endif
# ifndef __MINGW32__
# define int64_t_C(c) (c ## i64)
# define uint64_t_C(c) (c ## i64)
# ifdef HAVE_AV_CONFIG_H
# define inline __inline
# endif
# else
# define int64_t_C(c) (c ## LL)
# define uint64_t_C(c) (c ## ULL)
# endif /* __MINGW32__ */
# ifdef HAVE_AV_CONFIG_H
# ifdef _DEBUG
# define DEBUG
# endif
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# endif
/* CONFIG_WIN32 end */
#elif defined (CONFIG_OS2)
/* OS/2 EMX */
#ifndef int64_t_C
#define int64_t_C(c) (c ## LL)
#define uint64_t_C(c) (c ## ULL)
#endif
#ifdef HAVE_AV_CONFIG_H
#ifdef USE_FASTMEMCPY
#include "fastmemcpy.h"
#endif
#include <float.h>
#endif /* HAVE_AV_CONFIG_H */
/* CONFIG_OS2 end */
#else
#ifndef int64_t_C
#define int64_t_C(c) (c ## LL)
#define uint64_t_C(c) (c ## ULL)
#endif
#ifdef HAVE_AV_CONFIG_H
# ifdef USE_FASTMEMCPY
# include "fastmemcpy.h"
# endif
# endif /* HAVE_AV_CONFIG_H */
#endif /* !CONFIG_WIN32 && !CONFIG_OS2 */
# include "bswap.h"
# if defined(__MINGW32__) || defined(__CYGWIN__) || \
Michael Niedermayer
committed
defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
# define MANGLE(a) "_" #a
# else
# define MANGLE(a) #a
# endif
# ifndef DEBUG
# define NDEBUG
# endif
# include <assert.h>
# if defined(CONFIG_WIN32) && !defined(__MINGW32__)
# else
# ifdef DEBUG
Dan Christiansen
committed
# define dprintf(fmt,...) printf(fmt, __VA_ARGS__)
# else
Dan Christiansen
committed
# define dprintf(fmt,...)
# endif
# endif /* !CONFIG_WIN32 */
# define av_abort() do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0)
Philip Gladstone
committed
//rounded divison & shift
#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b))
/* assume b>0 */
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
extern const uint32_t inverse[256];
#ifdef ARCH_X86
# define FASTDIV(a,b) \
({\
int ret,dmy;\
asm volatile(\
"mull %3"\
:"=d"(ret),"=a"(dmy)\
:"1"(a),"g"(inverse[b])\
);\
ret;\
})
#elif defined(CONFIG_FASTDIV)
# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a)*inverse[b])>>32))
#else
# define FASTDIV(a,b) ((a)/(b))
#endif
#ifdef ARCH_X86
// avoid +32 for shift optimization (gcc should do that ...)
static inline int32_t NEG_SSR32( int32_t a, int8_t s){
asm ("sarl %1, %0\n\t"
: "+r" (a)
: "ic" ((uint8_t)(-s))
);
return a;
}
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
asm ("shrl %1, %0\n\t"
: "+r" (a)
: "ic" ((uint8_t)(-s))
);
return a;
}
Michael Niedermayer
committed
#else
# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
Michael Niedermayer
committed
#endif
typedef void (*WriteDataFunc)(void *, uint8_t *, int);
Michael Niedermayer
committed
#ifdef ALT_BITSTREAM_WRITER
Michael Niedermayer
committed
int index;
#else
Michael Niedermayer
committed
int bit_left;
Michael Niedermayer
committed
#endif
void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size);
Michael Niedermayer
committed
int put_bits_count(PutBitContext *s);
void align_put_bits(PutBitContext *s);
void flush_put_bits(PutBitContext *s);
void put_string(PutBitContext * pbc, char *s, int put_zero);
/* bit input */
typedef struct GetBitContext {
Michael Niedermayer
committed
#ifdef ALT_BITSTREAM_READER
int index;
Michael Niedermayer
committed
#elif defined LIBMPEG2_BITSTREAM_READER
uint8_t *buffer_ptr;
uint32_t cache;
Michael Niedermayer
committed
int bit_count;
#elif defined A32_BITSTREAM_READER
uint32_t *buffer_ptr;
uint32_t cache0;
uint32_t cache1;
Michael Niedermayer
committed
int bit_count;
Michael Niedermayer
committed
#endif
Michael Niedermayer
committed
int size_in_bits;
static inline int get_bits_count(GetBitContext *s);
Michael Niedermayer
committed
VLC_TYPE (*table)[2]; ///< code, bits
typedef struct RL_VLC_ELEM {
int16_t level;
int8_t len;
uint8_t run;
} RL_VLC_ELEM;
#ifdef ARCH_SPARC64
#define UNALIGNED_STORES_ARE_BAD
#endif
Michael Niedermayer
committed
/* used to avoid missaligned exceptions on some archs (alpha, ...) */
#ifdef ARCH_X86
# define unaligned32(a) (*(uint32_t*)(a))
Michael Niedermayer
committed
#else
# ifdef __GNUC__
Michael Niedermayer
committed
static inline uint32_t unaligned32(const void *v) {
struct Unaligned {
uint32_t i;
} __attribute__((packed));
return ((const struct Unaligned *) v)->i;
}
# elif defined(__DECC)
Michael Niedermayer
committed
static inline uint32_t unaligned32(const void *v) {
return *(const __unaligned uint32_t *) v;
}
# else
Michael Niedermayer
committed
static inline uint32_t unaligned32(const void *v) {
return *(const uint32_t *) v;
}
# endif
Michael Niedermayer
committed
#endif //!ARCH_X86
Michael Niedermayer
committed
#ifndef ALT_BITSTREAM_WRITER
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
{
unsigned int bit_buf;
int bit_left;
#ifdef STATS
st_out_bit_counts[st_current_index] += n;
#endif
// printf("put_bits=%d %x\n", n, value);
assert(n == 32 || value < (1U << n));
Michael Niedermayer
committed
bit_buf = s->bit_buf;
bit_left = s->bit_left;
// printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
/* XXX: optimize */
if (n < bit_left) {
bit_buf = (bit_buf<<n) | value;
bit_left-=n;
} else {
bit_buf<<=bit_left;
bit_buf |= value >> (n - bit_left);
#ifdef UNALIGNED_STORES_ARE_BAD
if (3 & (int) s->buf_ptr) {
s->buf_ptr[0] = bit_buf >> 24;
s->buf_ptr[1] = bit_buf >> 16;
s->buf_ptr[2] = bit_buf >> 8;
s->buf_ptr[3] = bit_buf ;
} else
#endif
*(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
Michael Niedermayer
committed
//printf("bitbuf = %08x\n", bit_buf);
s->buf_ptr+=4;
bit_left+=32 - n;
bit_buf = value;
}
s->bit_buf = bit_buf;
s->bit_left = bit_left;
}
#endif
Michael Niedermayer
committed
#ifdef ALT_BITSTREAM_WRITER
Michael Niedermayer
committed
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
Michael Niedermayer
committed
{
# ifdef ALIGNED_BITSTREAM_WRITER
# ifdef ARCH_X86
Michael Niedermayer
committed
asm volatile(
"movl %0, %%ecx \n\t"
"xorl %%eax, %%eax \n\t"
"shrdl %%cl, %1, %%eax \n\t"
"shrl %%cl, %1 \n\t"
"movl %0, %%ecx \n\t"
"shrl $3, %%ecx \n\t"
"andl $0xFFFFFFFC, %%ecx \n\t"
"bswapl %1 \n\t"
"orl %1, (%2, %%ecx) \n\t"
"bswapl %%eax \n\t"
"addl %3, %0 \n\t"
"movl %%eax, 4(%2, %%ecx) \n\t"
: "=&r" (s->index), "=&r" (value)
: "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
: "%eax", "%ecx"
);
# else
Michael Niedermayer
committed
int index= s->index;
uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
value<<= 32-n;
ptr[0] |= be2me_32(value>>(index&31));
ptr[1] = be2me_32(value<<(32-(index&31)));
//if(n>24) printf("%d %d\n", n, value);
index+= n;
s->index= index;
# endif
# else //ALIGNED_BITSTREAM_WRITER
# ifdef ARCH_X86
Michael Niedermayer
committed
asm volatile(
"movl $7, %%ecx \n\t"
"andl %0, %%ecx \n\t"
"addl %3, %%ecx \n\t"
"negl %%ecx \n\t"
"shll %%cl, %1 \n\t"
"bswapl %1 \n\t"
"movl %0, %%ecx \n\t"
"shrl $3, %%ecx \n\t"
"orl %1, (%%ecx, %2) \n\t"
"addl %3, %0 \n\t"
"movl $0, 4(%%ecx, %2) \n\t"
: "=&r" (s->index), "=&r" (value)
: "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
: "%ecx"
);
# else
Michael Niedermayer
committed
int index= s->index;
uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
ptr[0] |= be2me_32(value<<(32-n-(index&7) ));
ptr[1] = 0;
//if(n>24) printf("%d %d\n", n, value);
index+= n;
s->index= index;
# endif
# endif //!ALIGNED_BITSTREAM_WRITER
Michael Niedermayer
committed
}
#endif
static inline uint8_t* pbBufPtr(PutBitContext *s)
{
#ifdef ALT_BITSTREAM_WRITER
return s->buf + (s->index>>3);
#else
return s->buf_ptr;
#endif
}
/**
*
* PutBitContext must be flushed & aligned to a byte boundary before calling this.
*/
static inline void skip_put_bytes(PutBitContext *s, int n){
assert((put_bits_count(s)&7)==0);
#ifdef ALT_BITSTREAM_WRITER
FIXME may need some cleaning of the buffer
s->index += n<<3;
#else
assert(s->bit_left==32);
s->buf_ptr += n;
#endif
}
/**
* Changes the end of the buffer.
*/
static inline void set_put_bits_buffer_size(PutBitContext *s, int size){
s->buf_end= s->buf + size;
}
Michael Niedermayer
committed
/* Bitstream reader API docs:
name
abritary name which is used as prefix for the internal variables
Michael Niedermayer
committed
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
gb
getbitcontext
OPEN_READER(name, gb)
loads gb into local variables
CLOSE_READER(name, gb)
stores local vars in gb
UPDATE_CACHE(name, gb)
refills the internal cache from the bitstream
after this call at least MIN_CACHE_BITS will be available,
GET_CACHE(name, gb)
will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
SHOW_UBITS(name, gb, num)
will return the nest num bits
SHOW_SBITS(name, gb, num)
will return the nest num bits and do sign extension
SKIP_BITS(name, gb, num)
will skip over the next num bits
note, this is equinvalent to SKIP_CACHE; SKIP_COUNTER
SKIP_CACHE(name, gb, num)
will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
SKIP_COUNTER(name, gb, num)
will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
LAST_SKIP_CACHE(name, gb, num)
will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
LAST_SKIP_BITS(name, gb, num)
is equinvalent to SKIP_LAST_CACHE; SKIP_COUNTER
for examples see get_bits, show_bits, skip_bits, get_vlc
*/
static inline int unaligned32_be(const void *v)
{
#ifdef CONFIG_ALIGN
const uint8_t *p=v;
return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]);
#else
return be2me_32( unaligned32(v)); //original
#endif
}
Michael Niedermayer
committed
#ifdef ALT_BITSTREAM_READER
Michael Niedermayer
committed
# define MIN_CACHE_BITS 25
Michael Niedermayer
committed
Michael Niedermayer
committed
# define OPEN_READER(name, gb)\
int name##_index= (gb)->index;\
int name##_cache= 0;\
# define CLOSE_READER(name, gb)\
(gb)->index= name##_index;\
# define UPDATE_CACHE(name, gb)\
name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\
Michael Niedermayer
committed
# define SKIP_CACHE(name, gb, num)\
name##_cache <<= (num);\
// FIXME name?
# define SKIP_COUNTER(name, gb, num)\
name##_index += (num);\
# define SKIP_BITS(name, gb, num)\
{\
SKIP_CACHE(name, gb, num)\
SKIP_COUNTER(name, gb, num)\
}\
# define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
# define LAST_SKIP_CACHE(name, gb, num) ;
# define SHOW_UBITS(name, gb, num)\
NEG_USR32(name##_cache, num)
Michael Niedermayer
committed
# define SHOW_SBITS(name, gb, num)\
NEG_SSR32(name##_cache, num)
Michael Niedermayer
committed
# define GET_CACHE(name, gb)\
((uint32_t)name##_cache)
static inline int get_bits_count(GetBitContext *s){
return s->index;
}
Michael Niedermayer
committed
#elif defined LIBMPEG2_BITSTREAM_READER
//libmpeg2 like reader
# define MIN_CACHE_BITS 17
Michael Niedermayer
committed
# define OPEN_READER(name, gb)\
int name##_bit_count=(gb)->bit_count;\
int name##_cache= (gb)->cache;\
uint8_t * name##_buffer_ptr=(gb)->buffer_ptr;\
# define CLOSE_READER(name, gb)\
(gb)->bit_count= name##_bit_count;\
(gb)->cache= name##_cache;\
(gb)->buffer_ptr= name##_buffer_ptr;\
#ifdef LIBMPEG2_BITSTREAM_READER_HACK
# define UPDATE_CACHE(name, gb)\
if(name##_bit_count >= 0){\
name##_cache+= (int)be2me_16(*(uint16_t*)name##_buffer_ptr) << name##_bit_count;\
((uint16_t*)name##_buffer_ptr)++;\
name##_bit_count-= 16;\
}\
#else
Michael Niedermayer
committed
# define UPDATE_CACHE(name, gb)\
if(name##_bit_count >= 0){\
Michael Niedermayer
committed
name##_cache+= ((name##_buffer_ptr[0]<<8) + name##_buffer_ptr[1]) << name##_bit_count;\
name##_buffer_ptr+=2;\
name##_bit_count-= 16;\
}\
#endif
Michael Niedermayer
committed
# define SKIP_CACHE(name, gb, num)\
name##_cache <<= (num);\
# define SKIP_COUNTER(name, gb, num)\
name##_bit_count += (num);\
# define SKIP_BITS(name, gb, num)\
{\
SKIP_CACHE(name, gb, num)\
SKIP_COUNTER(name, gb, num)\
}\
# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num)
# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num)
# define SHOW_UBITS(name, gb, num)\
NEG_USR32(name##_cache, num)
Michael Niedermayer
committed
# define SHOW_SBITS(name, gb, num)\
NEG_SSR32(name##_cache, num)
Michael Niedermayer
committed
# define GET_CACHE(name, gb)\
((uint32_t)name##_cache)
static inline int get_bits_count(GetBitContext *s){
return (s->buffer_ptr - s->buffer)*8 - 16 + s->bit_count;
Michael Niedermayer
committed
#elif defined A32_BITSTREAM_READER
# define MIN_CACHE_BITS 32
# define OPEN_READER(name, gb)\
int name##_bit_count=(gb)->bit_count;\
uint32_t name##_cache0= (gb)->cache0;\
uint32_t name##_cache1= (gb)->cache1;\
uint32_t * name##_buffer_ptr=(gb)->buffer_ptr;\
# define CLOSE_READER(name, gb)\
(gb)->bit_count= name##_bit_count;\
(gb)->cache0= name##_cache0;\
(gb)->cache1= name##_cache1;\
(gb)->buffer_ptr= name##_buffer_ptr;\
# define UPDATE_CACHE(name, gb)\
if(name##_bit_count > 0){\
const uint32_t next= be2me_32( *name##_buffer_ptr );\
name##_cache0 |= NEG_USR32(next,name##_bit_count);\
Michael Niedermayer
committed
name##_cache1 |= next<<name##_bit_count;\
name##_buffer_ptr++;\
name##_bit_count-= 32;\
}\
Michael Niedermayer
committed
#ifdef ARCH_X86
Michael Niedermayer
committed
# define SKIP_CACHE(name, gb, num)\
asm(\
"shldl %2, %1, %0 \n\t"\
"shll %2, %1 \n\t"\
: "+r" (name##_cache0), "+r" (name##_cache1)\
: "Ic" ((uint8_t)num)\
);
Michael Niedermayer
committed
#else
Michael Niedermayer
committed
# define SKIP_CACHE(name, gb, num)\
name##_cache0 <<= (num);\
name##_cache0 |= NEG_USR32(name##_cache1,num);\
Michael Niedermayer
committed
name##_cache1 <<= (num);
Michael Niedermayer
committed
#endif
Michael Niedermayer
committed
Michael Niedermayer
committed
# define SKIP_COUNTER(name, gb, num)\
name##_bit_count += (num);\
# define SKIP_BITS(name, gb, num)\
{\
SKIP_CACHE(name, gb, num)\
SKIP_COUNTER(name, gb, num)\
}\
# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num)
# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num)
# define SHOW_UBITS(name, gb, num)\
NEG_USR32(name##_cache0, num)
Michael Niedermayer
committed
# define SHOW_SBITS(name, gb, num)\
NEG_SSR32(name##_cache0, num)
Michael Niedermayer
committed
# define GET_CACHE(name, gb)\
(name##_cache0)
static inline int get_bits_count(GetBitContext *s){
return ((uint8_t*)s->buffer_ptr - s->buffer)*8 - 32 + s->bit_count;
/**
* read mpeg1 dc style vlc (sign bit + mantisse with no MSB).
* if MSB not set it is negative
* @param n length in bits
* @author BERO
*/
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
static inline int get_xbits(GetBitContext *s, int n){
register int tmp;
register int32_t cache;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
cache = GET_CACHE(re,s);
if ((int32_t)cache<0) { //MSB=1
tmp = NEG_USR32(cache,n);
} else {
// tmp = (-1<<n) | NEG_USR32(cache,n) + 1; mpeg12.c algo
// tmp = - (NEG_USR32(cache,n) ^ ((1 << n) - 1)); h263.c algo
tmp = - NEG_USR32(~cache,n);
}
LAST_SKIP_BITS(re, s, n)
CLOSE_READER(re, s)
return tmp;
}
static inline int get_sbits(GetBitContext *s, int n){
register int tmp;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
tmp= SHOW_SBITS(re, s, n);
LAST_SKIP_BITS(re, s, n)
CLOSE_READER(re, s)
return tmp;
}
/**
* reads 0-17 bits.
* Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant
*/
Michael Niedermayer
committed
static inline unsigned int get_bits(GetBitContext *s, int n){
register int tmp;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
tmp= SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n)
CLOSE_READER(re, s)
return tmp;
}
unsigned int get_bits_long(GetBitContext *s, int n);
/**
* shows 0-17 bits.
* Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant
*/
Michael Niedermayer
committed
static inline unsigned int show_bits(GetBitContext *s, int n){
register int tmp;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
tmp= SHOW_UBITS(re, s, n);
// CLOSE_READER(re, s)
return tmp;
unsigned int show_bits_long(GetBitContext *s, int n);
static inline void skip_bits(GetBitContext *s, int n){
Michael Niedermayer
committed
//Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
LAST_SKIP_BITS(re, s, n)
CLOSE_READER(re, s)
}
static inline unsigned int get_bits1(GetBitContext *s){
Michael Niedermayer
committed
#ifdef ALT_BITSTREAM_READER
Michael Niedermayer
committed
int index= s->index;
uint8_t result= s->buffer[ index>>3 ];
result<<= (index&0x07);
result>>= 8 - 1;
index++;
s->index= index;
Michael Niedermayer
committed
return result;
Michael Niedermayer
committed
#else
Michael Niedermayer
committed
return get_bits(s, 1);
Michael Niedermayer
committed
#endif
Michael Niedermayer
committed
static inline unsigned int show_bits1(GetBitContext *s){
return show_bits(s, 1);
Michael Niedermayer
committed
static inline void skip_bits1(GetBitContext *s){
skip_bits(s, 1);
Michael Niedermayer
committed
void init_get_bits(GetBitContext *s,
const uint8_t *buffer, int buffer_size);
Michael Niedermayer
committed
int check_marker(GetBitContext *s, const char *msg);
void align_get_bits(GetBitContext *s);
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size);
void free_vlc(VLC *vlc);
Michael Niedermayer
committed
/**
*
* if the vlc code is invalid and max_depth=1 than no bits will be removed
* if the vlc code is invalid and max_depth>1 than the number of bits removed
* is undefined
*/
#define GET_VLC(code, name, gb, table, bits, max_depth)\
{\
int n, index, nb_bits;\
\
index= SHOW_UBITS(name, gb, bits);\
code = table[index][0];\
n = table[index][1];\
\
if(max_depth > 1 && n < 0){\
LAST_SKIP_BITS(name, gb, bits)\
UPDATE_CACHE(name, gb)\
\
nb_bits = -n;\
\
index= SHOW_UBITS(name, gb, nb_bits) + code;\
code = table[index][0];\
n = table[index][1];\
if(max_depth > 2 && n < 0){\
LAST_SKIP_BITS(name, gb, nb_bits)\
UPDATE_CACHE(name, gb)\
\
nb_bits = -n;\
\
index= SHOW_UBITS(name, gb, nb_bits) + code;\
code = table[index][0];\
n = table[index][1];\
}\
}\
SKIP_BITS(name, gb, n)\
}
#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth)\
{\
int n, index, nb_bits;\
\
index= SHOW_UBITS(name, gb, bits);\
level = table[index].level;\
n = table[index].len;\
\
if(max_depth > 1 && n < 0){\
LAST_SKIP_BITS(name, gb, bits)\
UPDATE_CACHE(name, gb)\
\
nb_bits = -n;\
\
index= SHOW_UBITS(name, gb, nb_bits) + level;\
level = table[index].level;\
n = table[index].len;\
}\
run= table[index].run;\
SKIP_BITS(name, gb, n)\
}
// deprecated, dont use get_vlc for new code, use get_vlc2 instead or use GET_VLC directly
Michael Niedermayer
committed
static inline int get_vlc(GetBitContext *s, VLC *vlc)
{
int code;
VLC_TYPE (*table)[2]= vlc->table;
Michael Niedermayer
committed
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
Michael Niedermayer
committed
Michael Niedermayer
committed
CLOSE_READER(re, s)
return code;
}
/**
* parses a vlc code, faster then get_vlc()
* @param bits is the number of bits which will be read at once, must be
* identical to nb_bits in init_vlc()
* @param max_depth is the number of times bits bits must be readed to completly
* read the longest vlc code
* = (max_vlc_length + bits - 1) / bits
*/
static always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
int bits, int max_depth)
{
int code;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
GET_VLC(code, re, s, table, bits, max_depth)
Michael Niedermayer
committed
CLOSE_READER(re, s)
Michael Niedermayer
committed
return code;
}
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
//#define TRACE
#ifdef TRACE
static inline void print_bin(int bits, int n){
int i;
for(i=n-1; i>=0; i--){
printf("%d", (bits>>i)&1);
}
for(i=n; i<24; i++)
printf(" ");
}
static inline int get_bits_trace(GetBitContext *s, int n, char *file, char *func, int line){
int r= get_bits(s, n);
print_bin(r, n);
printf("%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line);
return r;
}
static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, char *func, int line){
int show= show_bits(s, 24);
int pos= get_bits_count(s);
int r= get_vlc2(s, table, bits, max_depth);
int len= get_bits_count(s) - pos;
int bits2= show>>(24-len);
print_bin(bits2, len);
printf("%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line);
return r;
}
static inline int get_xbits_trace(GetBitContext *s, int n, char *file, char *func, int line){
int show= show_bits(s, n);
int r= get_xbits(s, n);
print_bin(show, n);
printf("%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line);
return r;
}
#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define tprintf printf
#else //TRACE
#define tprintf(_arg...) {}
/* define it to include statistics code (useful only for optimizing
codec efficiency */
//#define STATS
#ifdef STATS
enum {
ST_UNKNOWN,
ST_DC,
ST_INTRA_AC,
ST_INTER_AC,
ST_INTRA_MB,
ST_INTER_MB,
ST_MV,
ST_NB,
};
extern int st_current_index;
extern unsigned int st_bit_counts[ST_NB];