Commit 4d986b71 authored by Alex Converse's avatar Alex Converse

aacenc: Use exact values when quantizing, not fuzzy values.

This requires us to code small escapes; we can't avoid it.

Originally committed as revision 23135 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 51cbabc7
...@@ -65,18 +65,16 @@ static av_always_inline int quant(float coef, const float Q) ...@@ -65,18 +65,16 @@ static av_always_inline int quant(float coef, const float Q)
return sqrtf(a * sqrtf(a)) + 0.4054; return sqrtf(a * sqrtf(a)) + 0.4054;
} }
static void quantize_bands(int (*out)[2], const float *in, const float *scaled, static void quantize_bands(int *out, const float *in, const float *scaled,
int size, float Q34, int is_signed, int maxval) int size, float Q34, int is_signed, int maxval)
{ {
int i; int i;
double qc; double qc;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
qc = scaled[i] * Q34; qc = scaled[i] * Q34;
out[i][0] = (int)FFMIN(qc, (double)maxval); out[i] = (int)FFMIN(qc + 0.4054, (double)maxval);
out[i][1] = (int)FFMIN(qc + 0.4054, (double)maxval);
if (is_signed && in[i] < 0.0f) { if (is_signed && in[i] < 0.0f) {
out[i][0] = -out[i][0]; out[i] = -out[i];
out[i][1] = -out[i][1];
} }
} }
} }
...@@ -113,12 +111,10 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s, ...@@ -113,12 +111,10 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s,
float cost = 0; float cost = 0;
const int dim = cb < FIRST_PAIR_BT ? 4 : 2; const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
int resbits = 0; int resbits = 0;
#ifndef USE_REALLY_FULL_SEARCH
const float Q34 = sqrtf(Q * sqrtf(Q)); const float Q34 = sqrtf(Q * sqrtf(Q));
const int range = aac_cb_range[cb]; const int range = aac_cb_range[cb];
const int maxval = aac_cb_maxval[cb]; const int maxval = aac_cb_maxval[cb];
int offs[4]; int off;
#endif /* USE_REALLY_FULL_SEARCH */
if (!cb) { if (!cb) {
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
...@@ -127,64 +123,33 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s, ...@@ -127,64 +123,33 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s,
*bits = 0; *bits = 0;
return cost * lambda; return cost * lambda;
} }
#ifndef USE_REALLY_FULL_SEARCH
offs[0] = 1;
for (i = 1; i < dim; i++)
offs[i] = offs[i-1]*range;
if (!scaled) { if (!scaled) {
abs_pow34_v(s->scoefs, in, size); abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs; scaled = s->scoefs;
} }
quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval); quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval);
#endif /* USE_REALLY_FULL_SEARCH */ if (IS_CODEBOOK_UNSIGNED(cb)) {
off = 0;
} else {
off = maxval;
}
for (i = 0; i < size; i += dim) { for (i = 0; i < size; i += dim) {
float mincost;
int minidx = 0;
int minbits = 0;
const float *vec; const float *vec;
#ifndef USE_REALLY_FULL_SEARCH int *quants = s->qcoefs + i;
int (*quants)[2] = &s->qcoefs[i]; int curidx = 0;
mincost = 0.0f; int curbits;
for (j = 0; j < dim; j++) float rd = 0.0f;
mincost += in[i+j]*in[i+j]; for (j = 0; j < dim; j++) {
minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40; curidx *= range;
minbits = ff_aac_spectral_bits[cb-1][minidx]; curidx += quants[j] + off;
mincost = mincost * lambda + minbits; }
for (j = 0; j < (1<<dim); j++) {
float rd = 0.0f;
int curbits;
int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
int same = 0;
for (k = 0; k < dim; k++) {
if ((j & (1 << k)) && quants[k][0] == quants[k][1]) {
same = 1;
break;
}
}
if (same)
continue;
for (k = 0; k < dim; k++)
curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
curbits = ff_aac_spectral_bits[cb-1][curidx]; curbits = ff_aac_spectral_bits[cb-1][curidx];
vec = &ff_aac_codebook_vectors[cb-1][curidx*dim]; vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
#else
mincost = INFINITY;
vec = ff_aac_codebook_vectors[cb-1];
for (j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim) {
float rd = 0.0f;
int curbits = ff_aac_spectral_bits[cb-1][j];
int curidx = j;
#endif /* USE_REALLY_FULL_SEARCH */
if (IS_CODEBOOK_UNSIGNED(cb)) { if (IS_CODEBOOK_UNSIGNED(cb)) {
for (k = 0; k < dim; k++) { for (k = 0; k < dim; k++) {
float t = fabsf(in[i+k]); float t = fabsf(in[i+k]);
float di; float di;
if (vec[k] == 64.0f) { //FIXME: slow if (vec[k] == 64.0f) { //FIXME: slow
//do not code with escape sequence small values
if (t < 39.0f*IQ) {
rd = INFINITY;
break;
}
if (t >= CLIPPED_ESCAPE) { if (t >= CLIPPED_ESCAPE) {
di = t - CLIPPED_ESCAPE; di = t - CLIPPED_ESCAPE;
curbits += 21; curbits += 21;
...@@ -206,26 +171,19 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s, ...@@ -206,26 +171,19 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s,
rd += di*di; rd += di*di;
} }
} }
rd = rd * lambda + curbits; cost += rd * lambda + curbits;
if (rd < mincost) { resbits += curbits;
mincost = rd;
minidx = curidx;
minbits = curbits;
}
}
cost += mincost;
resbits += minbits;
if (cost >= uplim) if (cost >= uplim)
return uplim; return uplim;
if (pb) { if (pb) {
put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]); put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);
if (IS_CODEBOOK_UNSIGNED(cb)) if (IS_CODEBOOK_UNSIGNED(cb))
for (j = 0; j < dim; j++) for (j = 0; j < dim; j++)
if (ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f) if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)
put_bits(pb, 1, in[i+j] < 0.0f); put_bits(pb, 1, in[i+j] < 0.0f);
if (cb == ESC_BT) { if (cb == ESC_BT) {
for (j = 0; j < 2; j++) { for (j = 0; j < 2; j++) {
if (ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f) { if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) {
int coef = av_clip(quant(fabsf(in[i+j]), Q), 0, 8191); int coef = av_clip(quant(fabsf(in[i+j]), Q), 0, 8191);
int len = av_log2(coef); int len = av_log2(coef);
......
...@@ -64,7 +64,7 @@ typedef struct AACEncContext { ...@@ -64,7 +64,7 @@ typedef struct AACEncContext {
int cur_channel; int cur_channel;
int last_frame; int last_frame;
float lambda; float lambda;
DECLARE_ALIGNED(16, int, qcoefs)[96][2]; ///< quantized coefficients DECLARE_ALIGNED(16, int, qcoefs)[96]; ///< quantized coefficients
DECLARE_ALIGNED(16, float, scoefs)[1024]; ///< scaled coefficients DECLARE_ALIGNED(16, float, scoefs)[1024]; ///< scaled coefficients
} AACEncContext; } AACEncContext;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment