diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/common.h')
-rw-r--r-- | src/libffmpeg/libavcodec/common.h | 440 |
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 */ |