diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/golomb.h')
-rw-r--r-- | src/libffmpeg/libavcodec/golomb.h | 110 |
1 files changed, 91 insertions, 19 deletions
diff --git a/src/libffmpeg/libavcodec/golomb.h b/src/libffmpeg/libavcodec/golomb.h index 510d913ae..9861b18d1 100644 --- a/src/libffmpeg/libavcodec/golomb.h +++ b/src/libffmpeg/libavcodec/golomb.h @@ -32,6 +32,10 @@ extern const uint8_t ff_ue_golomb_vlc_code[512]; extern const int8_t ff_se_golomb_vlc_code[512]; extern const uint8_t ff_ue_golomb_len[256]; +extern const uint8_t ff_interleaved_golomb_vlc_len[256]; +extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; +extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; + /** * read unsigned exp golomb code. @@ -62,24 +66,33 @@ static inline int get_ue_golomb(GetBitContext *gb){ } static inline int svq3_get_ue_golomb(GetBitContext *gb){ - unsigned int buf; + uint32_t buf; int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb)|1; - - if((buf & 0xAAAAAAAA) == 0) - return INVALID_VLC; + buf=GET_CACHE(re, gb); + + if(buf&0xAA800000){ + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_ue_golomb_vlc_code[buf]; + }else{ + buf|=1; + if((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; - for(log=31; (buf & 0x80000000) == 0; log--){ - buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); - } + for(log=31; (buf & 0x80000000) == 0; log--){ + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + } - LAST_SKIP_BITS(re, gb, 63 - 2*log); - CLOSE_READER(re, gb); + LAST_SKIP_BITS(re, gb, 63 - 2*log); + CLOSE_READER(re, gb); - return ((buf << log) >> log) - 1; + return ((buf << log) >> log) - 1; + } } /** @@ -141,19 +154,59 @@ static inline int svq3_get_se_golomb(GetBitContext *gb){ OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb)|1; + buf=GET_CACHE(re, gb); + + if(buf&0xAA800000){ + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_se_golomb_vlc_code[buf]; + }else{ + buf |=1; + if((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; - if((buf & 0xAAAAAAAA) == 0) - return INVALID_VLC; + for(log=31; (buf & 0x80000000) == 0; log--){ + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + } - for(log=31; (buf & 0x80000000) == 0; log--){ - buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + LAST_SKIP_BITS(re, gb, 63 - 2*log); + CLOSE_READER(re, gb); + + return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; } +} - LAST_SKIP_BITS(re, gb, 63 - 2*log); - CLOSE_READER(re, gb); +/** + * read unsigned golomb rice code. + */ +static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); - return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; + log= av_log2(buf); +//printf("buf:%X log:%d\n", buf, log); + if(log > 31-limit){ + buf >>= log - k; + buf += (30-log)<<k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + }else if(log == 31-limit){ + buf >>= log - esc_len; + buf -= 1<<esc_len; + LAST_SKIP_BITS(re, gb, esc_len + limit + 1); + CLOSE_READER(re, gb); + + return buf + 1; + }else + return -1; } #ifdef TRACE @@ -257,3 +310,22 @@ static inline void set_se_golomb(PutBitContext *pb, int i){ #endif set_ue_golomb(pb, i); } + +/** + * write unsigned golomb rice code. + */ +static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int e; + + assert(i>=0); + + e= i>>k; + if(e<limit){ + put_bits(pb, e + k + 1, (1<<k) + (i&((1<<k)-1))); + }else{ +// printf("set %08X, %d\n", (1<<esc_len) + i - 1, limit + esc_len + 1); + put_bits(pb, limit + esc_len + 1, (1<<esc_len) + i - 1); +// put_bits(pb, 1, limit + 1); +// put_bits(pb, i - 1, esc_len); + } +} |