diff --git a/libavcodec/common.c b/libavcodec/common.c index 8c50fbc8d6..4f70e6f924 100644 --- a/libavcodec/common.c +++ b/libavcodec/common.c @@ -140,9 +140,19 @@ void init_get_bits(GetBitContext *s, #ifdef ALT_BITSTREAM_READER s->index=0; #elif defined LIBMPEG2_BITSTREAM_READER +#ifdef LIBMPEG2_BITSTREAM_HACK + if ((int)buffer&1) { + /* word alignment */ + s->cache = (*buffer++)<<24; + s->buffer_ptr = buffer; + s->bit_count = 16-8; + } else +#endif + { s->buffer_ptr = buffer; s->bit_count = 16; s->cache = 0; + } #elif defined A32_BITSTREAM_READER s->buffer_ptr = (uint32_t*)buffer; s->bit_count = 32; diff --git a/libavcodec/common.h b/libavcodec/common.h index b7ec2ae41b..494db42e2e 100644 --- a/libavcodec/common.h +++ b/libavcodec/common.h @@ -16,6 +16,7 @@ #define ALT_BITSTREAM_READER //#define LIBMPEG2_BITSTREAM_READER //#define A32_BITSTREAM_READER +#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO #ifdef HAVE_AV_CONFIG_H /* only include the following when compiling package */ @@ -472,6 +473,16 @@ LAST_SKIP_BITS(name, gb, num) 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 +} + #ifdef ALT_BITSTREAM_READER # define MIN_CACHE_BITS 25 @@ -483,7 +494,7 @@ for examples see get_bits, show_bits, skip_bits, get_vlc (gb)->index= name##_index;\ # define UPDATE_CACHE(name, gb)\ - name##_cache= be2me_32( unaligned32( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) ) << (name##_index&0x07);\ + name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ # define SKIP_CACHE(name, gb, num)\ name##_cache <<= (num);\ @@ -528,6 +539,17 @@ static inline int get_bits_count(GetBitContext *s){ (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;\ + name##_buffer_ptr+=2;\ + name##_bit_count-= 16;\ + }\ + +#else + # define UPDATE_CACHE(name, gb)\ if(name##_bit_count > 0){\ name##_cache+= ((name##_buffer_ptr[0]<<8) + name##_buffer_ptr[1]) << name##_bit_count;\ @@ -535,6 +557,8 @@ static inline int get_bits_count(GetBitContext *s){ name##_bit_count-= 16;\ }\ +#endif + # define SKIP_CACHE(name, gb, num)\ name##_cache <<= (num);\ @@ -630,6 +654,37 @@ static inline int get_bits_count(GetBitContext *s){ #endif +/* add BERO + if MSB not set it is negative +*/ +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<h263_rv10) { /* XXX: should patch encoder too */ - level = get_bits(&s->gb, 12); - level= (level + ((-1)<<11)) ^ ((-1)<<11); //sign extension + level = get_sbits(&s->gb, 12); }else{ level = get_bits(&s->gb, 5); - level += get_bits(&s->gb, 6)<<5; - level= (level + ((-1)<<10)) ^ ((-1)<<10); //sign extension + level |= get_sbits(&s->gb, 6)<<5; } } } else { @@ -3619,9 +3617,7 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) if (code == 0) { level = 0; } else { - level = get_bits(&s->gb, code); - if ((level >> (code - 1)) == 0) /* if MSB not set it is negative*/ - level = - (level ^ ((1 << code) - 1)); + level = get_xbits(&s->gb, code); if (code > 8){ if(get_bits1(&s->gb)==0){ /* marker */ if(s->error_resilience>=2){ @@ -4083,19 +4079,13 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s) length= get_vlc(&s->gb, &sprite_trajectory); if(length){ - x= get_bits(&s->gb, length); - - if ((x >> (length - 1)) == 0) /* if MSB not set it is negative*/ - x = - (x ^ ((1 << length) - 1)); + x= get_xbits(&s->gb, length); } if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(&s->gb); /* marker bit */ length= get_vlc(&s->gb, &sprite_trajectory); if(length){ - y=get_bits(&s->gb, length); - - if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/ - y = - (y ^ ((1 << length) - 1)); + y=get_xbits(&s->gb, length); } skip_bits1(&s->gb); /* marker bit */ //printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy); diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 3bbc843429..32d3057831 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1223,9 +1223,7 @@ static inline int decode_dc(MpegEncContext *s, int component) if (code == 0) { diff = 0; } else { - diff = get_bits(&s->gb, code); - if ((diff & (1 << (code - 1))) == 0) - diff = (-1 << code) | (diff + 1); + diff = get_xbits(&s->gb, code); } return diff; }