summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/common.h')
-rw-r--r--src/libffmpeg/libavcodec/common.h440
1 files changed, 422 insertions, 18 deletions
diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h
index aa8f9b54a..fd4bba129 100644
--- a/src/libffmpeg/libavcodec/common.h
+++ b/src/libffmpeg/libavcodec/common.h
@@ -3,14 +3,17 @@
#define FFMPEG_VERSION_INT 0x000406
#define FFMPEG_VERSION "0.4.6"
-/* CVS version as 26-12-2001 */
-#undef DEBUG
-
-#if defined(WIN32) && !defined(__MINGW32__)
+#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
#define CONFIG_WIN32
#endif
+//#define ALT_BITSTREAM_WRITER
+//#define ALIGNED_BITSTREAM_WRITER
+//#define ALT_BITSTREAM_READER
+//#define ALIGNED_BITSTREAM
+#define FAST_GET_FIRST_VLC
+
#ifdef HAVE_AV_CONFIG_H
/* only include the following when compiling package */
#include "../config.h"
@@ -127,6 +130,7 @@ typedef signed long long INT64;
#endif /* !CONFIG_WIN32 */
+
/* debug stuff */
#ifdef HAVE_AV_CONFIG_H
@@ -142,19 +146,11 @@ inline void dprintf(const char* fmt,...) {}
#else
-#ifdef __GNUC__
#ifdef DEBUG
#define dprintf(fmt,args...) printf(fmt, ## args)
#else
#define dprintf(fmt,args...)
#endif
-#else
-#ifdef DEBUG
-#define dprintf(fmt,...) printf(fmt, __VA_ARGS__)
-#else
-#define dprintf(fmt,...)
-#endif
-#endif
#endif /* !CONFIG_WIN32 */
@@ -167,33 +163,40 @@ struct PutBitContext;
typedef void (*WriteDataFunc)(void *, UINT8 *, int);
typedef struct PutBitContext {
+#ifdef ALT_BITSTREAM_WRITER
+ UINT8 *buf, *buf_end;
+ int index;
+#else
UINT32 bit_buf;
- int bit_cnt;
+ int bit_left;
UINT8 *buf, *buf_ptr, *buf_end;
+#endif
INT64 data_out_size; /* in bytes */
- void *opaque;
- WriteDataFunc write_data;
} PutBitContext;
void init_put_bits(PutBitContext *s,
UINT8 *buffer, int buffer_size,
void *opaque,
void (*write_data)(void *, UINT8 *, int));
-void put_bits(PutBitContext *s, int n, unsigned int value);
+
INT64 get_bit_count(PutBitContext *s); /* XXX: change function name */
void align_put_bits(PutBitContext *s);
void flush_put_bits(PutBitContext *s);
/* jpeg specific put_bits */
-void jput_bits(PutBitContext *s, int n, unsigned int value);
void jflush_put_bits(PutBitContext *s);
/* bit input */
typedef struct GetBitContext {
+#ifdef ALT_BITSTREAM_READER
+ int index;
+ UINT8 *buffer;
+#else
UINT32 bit_buf;
int bit_cnt;
UINT8 *buf, *buf_ptr, *buf_end;
+#endif
} GetBitContext;
typedef struct VLC {
@@ -203,13 +206,270 @@ typedef struct VLC {
int table_size, table_allocated;
} VLC;
+/* used to avoid missaligned exceptions on some archs (alpha, ...) */
+#ifdef ARCH_X86
+#define unaligned32(a) (*(UINT32*)(a))
+#else
+#ifdef __GNUC__
+static inline uint32_t unaligned32(const void *v) {
+ struct Unaligned {
+ uint32_t i;
+ } __attribute__((packed));
+
+ return ((const struct Unaligned *) v)->i;
+}
+#elif defined(__DECC)
+static inline uint32_t unaligned32(const void *v) {
+ return *(const __unaligned uint32_t *) v;
+}
+#else
+static inline uint32_t unaligned32(const void *v) {
+ return *(const uint32_t *) v;
+}
+#endif
+#endif //!ARCH_X86
+
+#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));
+
+ 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);
+ *(UINT32 *)s->buf_ptr = be2me_32(bit_buf);
+ //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
+
+
+#ifdef ALT_BITSTREAM_WRITER
+static inline void put_bits(PutBitContext *s, int n, unsigned int value)
+{
+#ifdef ALIGNED_BITSTREAM_WRITER
+#ifdef ARCH_X86
+ 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
+ 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
+ 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
+ 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
+}
+#endif
+
+#ifndef ALT_BITSTREAM_WRITER
+/* for jpeg : escape 0xff with 0x00 after it */
+static inline void jput_bits(PutBitContext *s, int n, unsigned int value)
+{
+ unsigned int bit_buf, b;
+ int bit_left, i;
+
+ assert(n == 32 || value < (1U << n));
+
+ 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);
+ /* handle escape */
+ for(i=0;i<4;i++) {
+ b = (bit_buf >> 24);
+ *(s->buf_ptr++) = b;
+ if (b == 0xff)
+ *(s->buf_ptr++) = 0;
+ bit_buf <<= 8;
+ }
+
+ bit_left+= 32 - n;
+ bit_buf = value;
+ }
+
+ s->bit_buf = bit_buf;
+ s->bit_left = bit_left;
+}
+#endif
+
+
+#ifdef ALT_BITSTREAM_WRITER
+static inline void jput_bits(PutBitContext *s, int n, int value)
+{
+ int index= s->index;
+ uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
+ int v= ptr[0];
+//if(n>24) printf("%d %d\n", n, value);
+
+ v |= be2me_32(value<<(32-n-(index&7) ));
+ if(((v+0x01010101)^0xFFFFFFFF)&v&0x80808080)
+ {
+ /* handle idiotic (m)jpeg escapes */
+ uint8_t *bPtr= (uint8_t*)ptr;
+ int numChecked= ((index+n)>>3) - (index>>3);
+
+ v= be2me_32(v);
+
+ *(bPtr++)= v>>24;
+ if((v&0xFF000000)==0xFF000000 && numChecked>0){
+ *(bPtr++)= 0x00;
+ index+=8;
+ }
+ *(bPtr++)= (v>>16)&0xFF;
+ if((v&0x00FF0000)==0x00FF0000 && numChecked>1){
+ *(bPtr++)= 0x00;
+ index+=8;
+ }
+ *(bPtr++)= (v>>8)&0xFF;
+ if((v&0x0000FF00)==0x0000FF00 && numChecked>2){
+ *(bPtr++)= 0x00;
+ index+=8;
+ }
+ *(bPtr++)= v&0xFF;
+ if((v&0x000000FF)==0x000000FF && numChecked>3){
+ *(bPtr++)= 0x00;
+ index+=8;
+ }
+ *((uint32_t*)bPtr)= 0;
+ }
+ else
+ {
+ ptr[0] = v;
+ ptr[1] = 0;
+ }
+
+ index+= n;
+ s->index= index;
+ }
+#endif
+
+
+static inline uint8_t* pbBufPtr(PutBitContext *s)
+{
+#ifdef ALT_BITSTREAM_WRITER
+ return s->buf + (s->index>>3);
+#else
+ return s->buf_ptr;
+#endif
+}
+
void init_get_bits(GetBitContext *s,
UINT8 *buffer, int buffer_size);
+#ifndef ALT_BITSTREAM_READER
unsigned int get_bits_long(GetBitContext *s, int n);
unsigned int show_bits_long(GetBitContext *s, int n);
+#endif
static inline unsigned int get_bits(GetBitContext *s, int n){
+#ifdef ALT_BITSTREAM_READER
+#ifdef ALIGNED_BITSTREAM
+ int index= s->index;
+ uint32_t result1= be2me_32( ((uint32_t *)s->buffer)[index>>5] );
+ uint32_t result2= be2me_32( ((uint32_t *)s->buffer)[(index>>5) + 1] );
+#ifdef ARCH_X86
+ asm ("shldl %%cl, %2, %0\n\t"
+ : "=r" (result1)
+ : "0" (result1), "r" (result2), "c" (index));
+#else
+ result1<<= (index&0x1F);
+ result2= (result2>>1) >> (31-(index&0x1F));
+ result1|= result2;
+#endif
+ result1>>= 32 - n;
+ index+= n;
+ s->index= index;
+
+ return result1;
+#else //ALIGNED_BITSTREAM
+ int index= s->index;
+ uint32_t result= be2me_32( unaligned32( ((uint8_t *)s->buffer)+(index>>3) ) );
+
+ result<<= (index&0x07);
+ result>>= 32 - n;
+ index+= n;
+ s->index= index;
+
+ return result;
+#endif //!ALIGNED_BITSTREAM
+#else //ALT_BITSTREAM_READER
if(s->bit_cnt>=n){
/* most common case here */
unsigned int val = s->bit_buf >> (32 - n);
@@ -221,9 +481,20 @@ static inline unsigned int get_bits(GetBitContext *s, int n){
return val;
}
return get_bits_long(s,n);
+#endif //!ALT_BITSTREAM_READER
}
static inline unsigned int get_bits1(GetBitContext *s){
+#ifdef ALT_BITSTREAM_READER
+ int index= s->index;
+ uint8_t result= s->buffer[ index>>3 ];
+ result<<= (index&0x07);
+ result>>= 8 - 1;
+ index++;
+ s->index= index;
+
+ return result;
+#else
if(s->bit_cnt>0){
/* most common case here */
unsigned int val = s->bit_buf >> 31;
@@ -235,6 +506,7 @@ static inline unsigned int get_bits1(GetBitContext *s){
return val;
}
return get_bits_long(s,1);
+#endif
}
/* This function is identical to get_bits(), the only */
@@ -242,15 +514,46 @@ static inline unsigned int get_bits1(GetBitContext *s){
/* it is usefull to see the buffer. */
static inline unsigned int show_bits(GetBitContext *s, int n)
{
+#ifdef ALT_BITSTREAM_READER
+#ifdef ALIGNED_BITSTREAM
+ int index= s->index;
+ uint32_t result1= be2me_32( ((uint32_t *)s->buffer)[index>>5] );
+ uint32_t result2= be2me_32( ((uint32_t *)s->buffer)[(index>>5) + 1] );
+#ifdef ARCH_X86
+ asm ("shldl %%cl, %2, %0\n\t"
+ : "=r" (result1)
+ : "0" (result1), "r" (result2), "c" (index));
+#else
+ result1<<= (index&0x1F);
+ result2= (result2>>1) >> (31-(index&0x1F));
+ result1|= result2;
+#endif
+ result1>>= 32 - n;
+
+ return result1;
+#else //ALIGNED_BITSTREAM
+ int index= s->index;
+ uint32_t result= be2me_32( unaligned32( ((uint8_t *)s->buffer)+(index>>3) ) );
+
+ result<<= (index&0x07);
+ result>>= 32 - n;
+
+ return result;
+#endif //!ALIGNED_BITSTREAM
+#else //ALT_BITSTREAM_READER
if(s->bit_cnt>=n) {
/* most common case here */
unsigned int val = s->bit_buf >> (32 - n);
return val;
}
return show_bits_long(s,n);
+#endif //!ALT_BITSTREAM_READER
}
static inline void skip_bits(GetBitContext *s, int n){
+#ifdef ALT_BITSTREAM_READER
+ s->index+= n;
+#else
if(s->bit_cnt>=n){
/* most common case here */
s->bit_buf <<= n;
@@ -261,9 +564,13 @@ static inline void skip_bits(GetBitContext *s, int n){
} else {
get_bits_long(s,n);
}
+#endif
}
static inline void skip_bits1(GetBitContext *s){
+#ifdef ALT_BITSTREAM_READER
+ s->index++;
+#else
if(s->bit_cnt>0){
/* most common case here */
s->bit_buf <<= 1;
@@ -274,11 +581,16 @@ static inline void skip_bits1(GetBitContext *s){
} else {
get_bits_long(s,1);
}
+#endif
}
static inline int get_bits_count(GetBitContext *s)
{
+#ifdef ALT_BITSTREAM_READER
+ return s->index;
+#else
return (s->buf_ptr - s->buf) * 8 - s->bit_cnt;
+#endif
}
void align_get_bits(GetBitContext *s);
@@ -286,7 +598,36 @@ 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);
-int get_vlc(GetBitContext *s, VLC *vlc);
+
+#ifdef ALT_BITSTREAM_READER
+#ifdef ALIGNED_BITSTREAM
+#ifdef ARCH_X86
+#define SHOW_BITS(s, val, n) \
+ val= be2me_32( ((uint32_t *)(s)->buffer)[bit_cnt>>5] );\
+ {uint32_t result2= be2me_32( ((uint32_t *)(s)->buffer)[(bit_cnt>>5) + 1] );\
+ asm ("shldl %%cl, %2, %0\n\t"\
+ : "=r" (val)\
+ : "0" (val), "r" (result2), "c" (bit_cnt));\
+ ((uint32_t)val)>>= 32 - n;}
+#else //ARCH_X86
+#define SHOW_BITS(s, val, n) \
+ val= be2me_32( ((uint32_t *)(s)->buffer)[bit_cnt>>5] );\
+ {uint32_t result2= be2me_32( ((uint32_t *)(s)->buffer)[(bit_cnt>>5) + 1] );\
+ val<<= (bit_cnt&0x1F);\
+ result2= (result2>>1) >> (31-(bit_cnt&0x1F));\
+ val|= result2;\
+ ((uint32_t)val)>>= 32 - n;}
+#endif //!ARCH_X86
+#else //ALIGNED_BITSTREAM
+#define SHOW_BITS(s, val, n) \
+ val= be2me_32( unaligned32( ((uint8_t *)(s)->buffer)+(bit_cnt>>3) ) );\
+ val<<= (bit_cnt&0x07);\
+ ((uint32_t)val)>>= 32 - n;
+#endif // !ALIGNED_BITSTREAM
+#define FLUSH_BITS(n) bit_cnt+=n;
+#define SAVE_BITS(s) bit_cnt= (s)->index;
+#define RESTORE_BITS(s) (s)->index= bit_cnt;
+#else
/* macro to go faster */
/* n must be <= 24 */
@@ -328,6 +669,69 @@ int get_vlc(GetBitContext *s, VLC *vlc);
(s)->bit_buf = bit_buf;\
(s)->bit_cnt = bit_cnt;\
}
+#endif // !ALT_BITSTREAM_READER
+
+static inline int get_vlc(GetBitContext *s, VLC *vlc)
+{
+ int code, n, nb_bits, index;
+ INT16 *table_codes;
+ INT8 *table_bits;
+ int bit_cnt;
+#ifndef ALT_BITSTREAM_READER
+ UINT32 bit_buf;
+ UINT8 *buf_ptr;
+#endif
+
+ SAVE_BITS(s);
+ nb_bits = vlc->bits;
+ table_codes = vlc->table_codes;
+ table_bits = vlc->table_bits;
+
+#ifdef FAST_GET_FIRST_VLC
+ SHOW_BITS(s, index, nb_bits);
+ code = table_codes[index];
+ n = table_bits[index];
+ if (n > 0) {
+ /* most common case (90%)*/
+ FLUSH_BITS(n);
+ RESTORE_BITS(s);
+ return code;
+ } else if (n == 0) {
+ return -1;
+ } else {
+ FLUSH_BITS(nb_bits);
+ nb_bits = -n;
+ table_codes = vlc->table_codes + code;
+ table_bits = vlc->table_bits + code;
+ }
+#endif
+ for(;;) {
+ SHOW_BITS(s, index, nb_bits);
+ code = table_codes[index];
+ n = table_bits[index];
+ if (n > 0) {
+ /* most common case */
+ FLUSH_BITS(n);
+#ifdef STATS
+ st_bit_counts[st_current_index] += n;
+#endif
+ break;
+ } else if (n == 0) {
+ return -1;
+ } else {
+ FLUSH_BITS(nb_bits);
+#ifdef STATS
+ st_bit_counts[st_current_index] += nb_bits;
+#endif
+ nb_bits = -n;
+ table_codes = vlc->table_codes + code;
+ table_bits = vlc->table_bits + code;
+ }
+ }
+ RESTORE_BITS(s);
+ return code;
+}
+
/* define it to include statistics code (useful only for optimizing
codec efficiency */