From c2decd39a63edb2bab2a21f66471108033236bcf Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> Date: Sat, 22 Mar 2008 22:58:45 +1100 Subject: [PATCH] Made a second version of ec_{en|de}code optimised for encoding bits (no div required) and using it in ec_{en|de}c_bits() --- libcelt/entdec.c | 4 ++-- libcelt/entdec.h | 1 + libcelt/entenc.c | 4 ++-- libcelt/entenc.h | 1 + libcelt/rangedec.c | 9 +++++++++ libcelt/rangeenc.c | 12 ++++++++++++ 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/libcelt/entdec.c b/libcelt/entdec.c index 76b8c904..3b25dd59 100644 --- a/libcelt/entdec.c +++ b/libcelt/entdec.c @@ -88,13 +88,13 @@ ec_uint32 ec_dec_bits(ec_dec *_this,int _ftb){ unsigned ft; t=0; while(_ftb>EC_UNIT_BITS){ - s=ec_decode(_this,EC_UNIT_MASK+1); + s=ec_decode_bin(_this,EC_UNIT_BITS); ec_dec_update(_this,s,s+1,EC_UNIT_MASK+1); t=t<<EC_UNIT_BITS|s; _ftb-=EC_UNIT_BITS; } ft=1U<<_ftb; - s=ec_decode(_this,ft); + s=ec_decode_bin(_this,_ftb); ec_dec_update(_this,s,s+1,ft); t=t<<_ftb|s; return t; diff --git a/libcelt/entdec.h b/libcelt/entdec.h index 423c574e..f5feb1af 100644 --- a/libcelt/entdec.h +++ b/libcelt/entdec.h @@ -42,6 +42,7 @@ void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf); up to and including the one encoded is fh, then the returned value will fall in the range [fl,fh).*/ unsigned ec_decode(ec_dec *_this,unsigned _ft); +unsigned ec_decode_bin(ec_dec *_this,unsigned bits); /*Advance the decoder past the next symbol using the frequency information the symbol was encoded with. Exactly one call to ec_decode() must have been made so that all necessary diff --git a/libcelt/entenc.c b/libcelt/entenc.c index 1ff07604..7859f638 100644 --- a/libcelt/entenc.c +++ b/libcelt/entenc.c @@ -70,11 +70,11 @@ void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,int _ftb){ while(_ftb>EC_UNIT_BITS){ _ftb-=EC_UNIT_BITS; fl=(unsigned)(_fl>>_ftb)&EC_UNIT_MASK; - ec_encode(_this,fl,fl+1,EC_UNIT_MASK+1); + ec_encode_bin(_this,fl,fl+1,EC_UNIT_BITS); } ft=1<<_ftb; fl=(unsigned)_fl&ft-1; - ec_encode(_this,fl,fl+1,ft); + ec_encode_bin(_this,fl,fl+1,_ftb); } void ec_enc_bits64(ec_enc *_this,ec_uint64 _fl,int _ftb){ diff --git a/libcelt/entenc.h b/libcelt/entenc.h index ebaed887..9b3ab6db 100644 --- a/libcelt/entenc.h +++ b/libcelt/entenc.h @@ -42,6 +42,7 @@ void ec_enc_init(ec_enc *_this,ec_byte_buffer *_buf); decoded value will fall. _ft: The sum of the frequencies of all the symbols*/ void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft); +void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned bits); /*Encodes a sequence of raw bits in the stream. _fl: The bits to encode. _ftb: The number of bits to encode. diff --git a/libcelt/rangedec.c b/libcelt/rangedec.c index 072e9c6a..685ee251 100644 --- a/libcelt/rangedec.c +++ b/libcelt/rangedec.c @@ -168,6 +168,15 @@ unsigned ec_decode(ec_dec *_this,unsigned _ft){ return _ft-EC_MINI(s+1,_ft); } +unsigned ec_decode_bin(ec_dec *_this,unsigned bits){ + unsigned s; + ec_uint32 ft; + ft = (ec_uint32)1<<bits; + _this->nrm=_this->rng>>bits; + s=(unsigned)((_this->dif-1)/_this->nrm); + return ft-EC_MINI(s+1,ft); +} + void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){ ec_uint32 s; s=_this->nrm*(_ft-_fh); diff --git a/libcelt/rangeenc.c b/libcelt/rangeenc.c index 7fcd3d1a..177fcb25 100644 --- a/libcelt/rangeenc.c +++ b/libcelt/rangeenc.c @@ -92,6 +92,18 @@ void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){ ec_enc_normalize(_this); } +void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned bits){ + ec_uint32 r, ft; + r=_this->rng>>bits; + ft = (ec_uint32)1<<bits; + if(_fl>0){ + _this->low+=_this->rng-r*(ft-_fl); + _this->rng=r*(_fh-_fl); + } + else _this->rng-=r*(ft-_fh); + ec_enc_normalize(_this); +} + long ec_enc_tell(ec_enc *_this,int _b){ ec_uint32 r; int l; -- GitLab