ref: e86fb268b029d68d07ede37d35cfe82e8db3e86d
parent: 8c23a3a0fd2dae1407a56e994485b0f9c57910cc
author: Timothy B. Terriberry <[email protected]>
date: Fri Dec 17 09:50:19 EST 2010
Replace ec_{enc|dec}_bit_prob() with ec_{enc|dec}_bit_logp(). All of our usage of ec_{enc|dec}_bit_prob had the probability of a "one" being a power of two. This adds a new ec_{enc|dec}_bit_logp() function that takes this explicitly into account. It introduces less rounding error than the bit_prob version, does not require 17-bit integers to be emulated by ec_{encode|decode}_bin(), and does not require any multiplies or divisions at all. It is exactly equivalent to ec_encode_bin(enc,_val?0:(1<<_logp)-1,(1<<_logp)-(_val?1:0),1<<_logp) The old ec_{enc|dec}_bit_prob functions are left in place for now, because I am not sure if SILK is still using them or not when combined in Opus.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -675,9 +675,9 @@
if (b>2<<BITRES && *remaining_bits > 2<<BITRES)
{
if (encode)
- ec_enc_bit_prob(ec, inv, 16384);
+ ec_enc_bit_logp(ec, inv, 2);
else
- inv = ec_dec_bit_prob(ec, 16384);
+ inv = ec_dec_bit_logp(ec, 2);
qalloc = inv ? 16 : 4;
} else
inv = 0;
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -592,11 +592,11 @@
static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
{
int curr, i;
- ec_enc_bit_prob(enc, tf_res[start], isTransient ? 16384 : 4096);
+ ec_enc_bit_logp(enc, tf_res[start], isTransient ? 2 : 4);
curr = tf_res[start];
for (i=start+1;i<end;i++)
{
- ec_enc_bit_prob(enc, tf_res[i] ^ curr, isTransient ? 4096 : 2048);
+ ec_enc_bit_logp(enc, tf_res[i] ^ curr, isTransient ? 4 : 5);
curr = tf_res[i];
}
if (LM!=0)
@@ -609,11 +609,11 @@
static void tf_decode(int start, int end, int C, int isTransient, int *tf_res, int LM, ec_dec *dec)
{
int i, curr, tf_select;
- tf_res[start] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
+ tf_res[start] = ec_dec_bit_logp(dec, isTransient ? 2 : 4);
curr = tf_res[start];
for (i=start+1;i<end;i++)
{
- tf_res[i] = ec_dec_bit_prob(dec, isTransient ? 4096 : 2048) ^ curr;
+ tf_res[i] = ec_dec_bit_logp(dec, isTransient ? 4 : 5) ^ curr;
curr = tf_res[i];
}
if (LM!=0)
@@ -850,7 +850,7 @@
}
if (gain1<QCONST16(.2f,15) || (nbAvailableBytes<30 && gain1<QCONST16(.4f,15)))
{
- ec_enc_bit_prob(enc, 0, 32768);
+ ec_enc_bit_logp(enc, 0, 1);
gain1 = 0;
} else {
int qg;
@@ -860,7 +860,7 @@
#else
qg = floor(.5+gain1*8)-2;
#endif
- ec_enc_bit_prob(enc, 1, 32768);
+ ec_enc_bit_logp(enc, 1, 1);
octave = EC_ILOG(pitch_index)-5;
ec_enc_uint(enc, octave, 6);
ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
@@ -869,7 +869,7 @@
}
/*printf("%d %f\n", pitch_index, gain1);*/
#else /* ENABLE_POSTFILTER */
- ec_enc_bit_prob(enc, 0, 32768);
+ ec_enc_bit_logp(enc, 0, 1);
#endif /* ENABLE_POSTFILTER */
c=0; do {
@@ -942,7 +942,7 @@
&st->delayedIntra, st->complexity >= 4);
if (LM > 0)
- ec_enc_bit_prob(enc, shortBlocks!=0, 8192);
+ ec_enc_bit_logp(enc, shortBlocks!=0, 3);
tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
@@ -994,12 +994,12 @@
for (i=0;i<st->mode->nbEBands;i++)
{
int j;
- ec_enc_bit_prob(enc, offsets[i]!=0, 1024);
+ ec_enc_bit_logp(enc, offsets[i]!=0, 6);
if (offsets[i]!=0)
{
for (j=0;j<offsets[i]-1;j++)
- ec_enc_bit_prob(enc, 1, 32768);
- ec_enc_bit_prob(enc, 0, 32768);
+ ec_enc_bit_logp(enc, 1, 1);
+ ec_enc_bit_logp(enc, 0, 1);
}
offsets[i] *= (6<<BITRES);
}
@@ -1088,7 +1088,7 @@
dual_stereo = 0;
else
dual_stereo = stereo_analysis(st->mode, X, st->mode->nbEBands, LM, C, N);
- ec_enc_bit_prob(enc, dual_stereo, 32768);
+ ec_enc_bit_logp(enc, dual_stereo, 1);
}
if (C==2)
{
@@ -1786,7 +1786,7 @@
}
nbAvailableBytes = len-nbFilledBytes;
- if (ec_dec_bit_prob(dec, 32768))
+ if (ec_dec_bit_logp(dec, 1))
{
#ifdef ENABLE_POSTFILTER
int qg, octave;
@@ -1805,13 +1805,13 @@
}
/* Decode the global flags (first symbols in the stream) */
- intra_ener = ec_dec_bit_prob(dec, 8192);
+ intra_ener = ec_dec_bit_logp(dec, 3);
/* Get band energies */
unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
intra_ener, dec, C, LM);
if (LM > 0)
- isTransient = ec_dec_bit_prob(dec, 8192);
+ isTransient = ec_dec_bit_logp(dec, 3);
else
isTransient = 0;
@@ -1833,9 +1833,9 @@
offsets[i] = 0;
for (i=0;i<st->mode->nbEBands;i++)
{
- if (ec_dec_bit_prob(dec, 1024))
+ if (ec_dec_bit_logp(dec, 6))
{
- while (ec_dec_bit_prob(dec, 32768))
+ while (ec_dec_bit_logp(dec, 1))
offsets[i]++;
offsets[i]++;
offsets[i] *= (6<<BITRES);
@@ -1847,7 +1847,7 @@
if (C==2)
{
- dual_stereo = ec_dec_bit_prob(dec, 32768);
+ dual_stereo = ec_dec_bit_logp(dec, 1);
intensity = ec_dec_uint(dec, 1+st->end-st->start);
}
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -124,6 +124,9 @@
/* Decode a bit that has a _prob/65536 probability of being a one */
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
+/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
+int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
+
/*Returns the number of bits "used" by the encoded symbols so far.
This same number can be computed by the encoder, and is suitable for making
coding decisions.
--- a/libcelt/entenc.h
+++ b/libcelt/entenc.h
@@ -96,6 +96,9 @@
/* Encode a bit that has a _prob/65536 probability of being a one */
void ec_enc_bit_prob(ec_enc *_this,int val,unsigned _prob);
+/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
+void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
+
/*Returns the number of bits "used" by the encoded symbols so far.
This same number can be computed by the decoder, and is suitable for making
coding decisions.
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -163,7 +163,7 @@
celt_word16 coef;
celt_word16 beta;
- ec_enc_bit_prob(enc, intra, 8192);
+ ec_enc_bit_logp(enc, intra, 3);
if (intra)
{
coef = 0;
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -190,12 +190,28 @@
/*The probability of having a "one" is given in 1/65536.*/
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
ec_uint32 r;
- ec_uint32 s;
ec_uint32 d;
+ ec_uint32 s;
int val;
r=_this->rng;
d=_this->dif;
s=(r>>16)*_prob;
+ val=d<s;
+ if(!val)_this->dif=d-s;
+ _this->rng=val?s:r-s;
+ ec_dec_normalize(_this);
+ return val;
+}
+
+/*The probability of having a "one" is 1/(1<<_logp).*/
+int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
+ ec_uint32 r;
+ ec_uint32 d;
+ ec_uint32 s;
+ int val;
+ r=_this->rng;
+ d=_this->dif;
+ s=r>>_logp;
val=d<s;
if(!val)_this->dif=d-s;
_this->rng=val?s:r-s;
--- a/libcelt/rangeenc.c
+++ b/libcelt/rangeenc.c
@@ -153,6 +153,20 @@
ec_enc_normalize(_this);
}
+/*The probability of having a "one" is 1/(1<<_logp).*/
+void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
+ ec_uint32 r;
+ ec_uint32 s;
+ ec_uint32 l;
+ r=_this->rng;
+ l=_this->low;
+ s=r>>_logp;
+ r-=s;
+ if(_val)_this->low=l+r;
+ _this->rng=_val?s:r;
+ ec_enc_normalize(_this);
+}
+
void ec_enc_bits(ec_enc *_this,unsigned _fl,unsigned bits){
_this->nb_end_bits += bits;
while (bits >= _this->end_bits_left)
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -245,11 +245,11 @@
fluctuating in and out.*/
if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
{
- ec_enc_bit_prob((ec_enc *)ec, 1, 32768);
+ ec_enc_bit_logp((ec_enc *)ec, 1, 1);
break;
}
- ec_enc_bit_prob((ec_enc *)ec, 0, 32768);
- } else if (ec_dec_bit_prob((ec_dec *)ec, 32768)) {
+ ec_enc_bit_logp((ec_enc *)ec, 0, 1);
+ } else if (ec_dec_bit_logp((ec_dec *)ec, 1)) {
break;
}
/*We used a bit to skip this band.*/