shithub: opus

Download patch

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.*/