The coarse energy budget is no longer part of the bit-stream.
authorJean-Marc Valin <jean-marc.valin@octasic.com>
Mon, 19 Jul 2010 18:32:40 +0000 (14:32 -0400)
committerJean-Marc Valin <jean-marc.valin@octasic.com>
Mon, 19 Jul 2010 18:32:40 +0000 (14:32 -0400)
It is now the encoder's responsability to take care of it to avoid
busting the budget.

libcelt/celt.c
libcelt/quant_bands.c
libcelt/quant_bands.h

index 5adaee2..763aea4 100644 (file)
@@ -556,6 +556,13 @@ static int tf_analysis(celt_word16 *bandLogE, celt_word16 *oldBandE, int len, in
    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 celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
    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 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
 #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 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
      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 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
 
    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);
index 484c024..4a7abf9 100644 (file)
@@ -84,10 +84,9 @@ void quant_prob_free(int *freq)
    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 @@ unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_w
    {
       c=0;
       do {
+         int bits_left;
          int qi;
          celt_word16 q;
          celt_word16 x;
@@ -131,22 +131,24 @@ unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_w
          }
          /* 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);
          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 @@ void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBa
    } 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 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBa
          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);
index bc786f3..ab61f7a 100644 (file)
@@ -56,13 +56,13 @@ void compute_fine_allocation(const CELTMode *m, int *bits, int budget);
 
 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);