summaryrefslogtreecommitdiff
path: root/libavcodec/aaccoder.c
diff options
context:
space:
mode:
authorAlex Converse <alex.converse@gmail.com>2010-05-14 16:49:40 +0000
committerAlex Converse <alex.converse@gmail.com>2010-05-14 16:49:40 +0000
commit4d986b71721ddf26ab8563b933ec8dd3ec88e59c (patch)
treeeca9efeb26bdb01abe3c2372933fc723b10ea8a1 /libavcodec/aaccoder.c
parent51cbabc79241dc9089d98965079fe1da4742d966 (diff)
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
Diffstat (limited to 'libavcodec/aaccoder.c')
-rw-r--r--libavcodec/aaccoder.c86
1 files changed, 22 insertions, 64 deletions
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index b9ae79927d..0cead754c7 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -65,18 +65,16 @@ static av_always_inline int quant(float coef, const float Q)
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 i;
double qc;
for (i = 0; i < size; i++) {
qc = scaled[i] * Q34;
- out[i][0] = (int)FFMIN(qc, (double)maxval);
- out[i][1] = (int)FFMIN(qc + 0.4054, (double)maxval);
+ out[i] = (int)FFMIN(qc + 0.4054, (double)maxval);
if (is_signed && in[i] < 0.0f) {
- out[i][0] = -out[i][0];
- out[i][1] = -out[i][1];
+ out[i] = -out[i];
}
}
}
@@ -113,12 +111,10 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s,
float cost = 0;
const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
int resbits = 0;
-#ifndef USE_REALLY_FULL_SEARCH
const float Q34 = sqrtf(Q * sqrtf(Q));
const int range = aac_cb_range[cb];
const int maxval = aac_cb_maxval[cb];
- int offs[4];
-#endif /* USE_REALLY_FULL_SEARCH */
+ int off;
if (!cb) {
for (i = 0; i < size; i++)
@@ -127,64 +123,33 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s,
*bits = 0;
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) {
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
}
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) {
- float mincost;
- int minidx = 0;
- int minbits = 0;
const float *vec;
-#ifndef USE_REALLY_FULL_SEARCH
- int (*quants)[2] = &s->qcoefs[i];
- mincost = 0.0f;
- for (j = 0; j < dim; j++)
- mincost += in[i+j]*in[i+j];
- minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- minbits = ff_aac_spectral_bits[cb-1][minidx];
- 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];
+ int *quants = s->qcoefs + i;
+ int curidx = 0;
+ int curbits;
+ float rd = 0.0f;
+ for (j = 0; j < dim; j++) {
+ curidx *= range;
+ curidx += quants[j] + off;
+ }
curbits = ff_aac_spectral_bits[cb-1][curidx];
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)) {
for (k = 0; k < dim; k++) {
float t = fabsf(in[i+k]);
float di;
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) {
di = t - CLIPPED_ESCAPE;
curbits += 21;
@@ -206,26 +171,19 @@ static float quantize_and_encode_band_cost(struct AACEncContext *s,
rd += di*di;
}
}
- rd = rd * lambda + curbits;
- if (rd < mincost) {
- mincost = rd;
- minidx = curidx;
- minbits = curbits;
- }
- }
- cost += mincost;
- resbits += minbits;
+ cost += rd * lambda + curbits;
+ resbits += curbits;
if (cost >= uplim)
return uplim;
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))
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);
if (cb == ESC_BT) {
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 len = av_log2(coef);