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);