shithub: opus

Download patch

ref: 6bf3b0a7a13e469d4a2e161143a240220f563150
parent: b1e017f58d2bb319eb7bc3305048185a9c8fe9d9
author: Jean-Marc Valin <[email protected]>
date: Mon Jul 19 10:32:40 EDT 2010

The coarse energy budget is no longer part of the bit-stream.

It is now the encoder's responsability to take care of it to avoid
busting the budget.

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -556,6 +556,13 @@
    int tf_select=0;
    SAVE_STACK;
 
+   /* FIXME: Should check number of bytes *left* */
+   if (nbCompressedBytes<15*C)
+   {
+      for (i=0;i<len;i++)
+         tf_res[i] = 0;
+      return 0;
+   }
    if (nbCompressedBytes<40)
       lambda = QCONST16(5.f, DB_SHIFT);
    else if (nbCompressedBytes<60)
@@ -692,7 +699,6 @@
    int pitch_index;
    int bits;
    int has_fold=1;
-   int coarse_needed;
    ec_byte_buffer buf;
    ec_enc         _enc;
    VARDECL(celt_sig, in);
@@ -980,11 +986,7 @@
 #else
    max_decay = .125*nbAvailableBytes;
 #endif
-   coarse_needed = quant_coarse_energy(st->mode, st->start, st->end, bandLogE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C, max_decay);
-   coarse_needed -= nbFilledBytes*8;
-   coarse_needed = ((coarse_needed*3-1)>>3)+1;
-   if (coarse_needed > nbAvailableBytes)
-      coarse_needed = nbAvailableBytes;
+   quant_coarse_energy(st->mode, st->start, st->end, bandLogE, st->oldBandE, nbCompressedBytes*8, intra_ener, st->mode->prob, error, enc, C, max_decay);
    /* Variable bitrate */
    if (vbr_rate>0)
    {
@@ -1005,7 +1007,6 @@
      target=target+st->vbr_offset-588+ec_enc_tell(enc, BITRES);
 
      /* In VBR mode the frame size must not be reduced so much that it would result in the coarse energy busting its budget */
-     target=IMAX(coarse_needed,(target+64)/128);
      target=IMIN(nbAvailableBytes,target);
      /* Make the adaptation coef (alpha) higher at the beginning */
      if (st->vbr_count < 990)
@@ -1799,7 +1800,7 @@
 
    ALLOC(fine_quant, st->mode->nbEBands, int);
    /* Get band energies */
-   unquant_coarse_energy(st->mode, st->start, st->end, bandE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, dec, C);
+   unquant_coarse_energy(st->mode, st->start, st->end, bandE, st->oldBandE, intra_ener, st->mode->prob, dec, C);
 
    ALLOC(tf_res, st->mode->nbEBands, int);
    tf_decode(st->start, st->end, C, isTransient, tf_res, nbAvailableBytes, LM, dec);
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -84,10 +84,9 @@
    celt_free(freq);
 }
 
-unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay)
+void quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay)
 {
    int i, c;
-   unsigned bits_used = 0;
    celt_word32 prev[2] = {0,0};
    celt_word16 coef = m->ePredCoef;
    celt_word16 beta;
@@ -106,6 +105,7 @@
    {
       c=0;
       do {
+         int bits_left;
          int qi;
          celt_word16 q;
          celt_word16 x;
@@ -131,15 +131,18 @@
          }
          /* If we don't have enough bits to encode all the energy, just assume something safe.
             We allow slightly busting the budget here */
-         bits_used=ec_enc_tell(enc, 0);
-         if (bits_used > budget)
+         bits_left = budget-(int)ec_enc_tell(enc, 0)-2*C*(end-i);
+         if (bits_left < 24)
          {
-            qi = -1;
-            error[i+c*m->nbEBands] = QCONST16(.5f,DB_SHIFT);
-         } else {
-            ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
-            error[i+c*m->nbEBands] = PSHR32(f,15) - SHL16(qi,DB_SHIFT);
+            if (qi > 1)
+               qi = 1;
+            if (qi < -1)
+               qi = -1;
+            if (bits_left<8)
+               qi = 0;
          }
+         ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
+         error[i+c*m->nbEBands] = PSHR32(f,15) - SHL16(qi,DB_SHIFT);
          q = SHL16(qi,DB_SHIFT);
          
          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + mean + prev[c] + SHL32(EXTEND32(q),15), 15);
@@ -146,7 +149,6 @@
          prev[c] = mean + prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
       } while (++c < C);
    }
-   return bits_used;
 }
 
 void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
@@ -226,7 +228,7 @@
    } while (++c < C);
 }
 
-void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C)
+void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int intra, int *prob, ec_dec *dec, int _C)
 {
    int i, c;
    celt_word32 prev[2] = {0, 0};
@@ -250,12 +252,7 @@
          int qi;
          celt_word16 q;
          celt_word32 mean =  (i-start < E_MEANS_SIZE) ? SUB32(SHL32(EXTEND32(eMeans[i-start]),15), MULT16_16(coef,eMeans[i-start])) : 0;
-         /* If we didn't have enough bits to encode all the energy, just assume something safe.
-            We allow slightly busting the budget here */
-         if (ec_dec_tell(dec, 0) > budget)
-            qi = -1;
-         else
-            qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
+         qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
          q = SHL16(qi,DB_SHIFT);
 
          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + mean + prev[c] + SHL32(EXTEND32(q),15), 15);
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -56,13 +56,13 @@
 
 int intra_decision(celt_word16 *eBands, celt_word16 *oldEBands, int len);
 
-unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay);
+void quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay);
 
 void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C);
 
 void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C);
 
-void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C);
+void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int intra, int *prob, ec_dec *dec, int _C);
 
 void unquant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C);