*
* @return quantization distortion
*/
-static float quantize_and_encode_band_cost(struct AACEncContext *s,
+static av_always_inline float quantize_and_encode_band_cost_template(
+ struct AACEncContext *s,
PutBitContext *pb, const float *in,
const float *scaled, int size, int scale_idx,
int cb, const float lambda, const float uplim,
- int *bits)
+ int *bits, int BT_ZERO, int BT_UNSIGNED,
+ int BT_PAIR, int BT_ESC)
{
const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float CLIPPED_ESCAPE = 165140.0f*IQ;
int i, j, k;
float cost = 0;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
+ const int dim = BT_PAIR ? 2 : 4;
int resbits = 0;
const float Q34 = sqrtf(Q * sqrtf(Q));
const int range = aac_cb_range[cb];
const int maxval = aac_cb_maxval[cb];
int off;
- if (!cb) {
+ if (BT_ZERO) {
for (i = 0; i < size; i++)
cost += in[i]*in[i];
if (bits)
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
}
- quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval);
- if (IS_CODEBOOK_UNSIGNED(cb)) {
+ quantize_bands(s->qcoefs, in, scaled, size, Q34, !BT_UNSIGNED, maxval);
+ if (BT_UNSIGNED) {
off = 0;
} else {
off = maxval;
}
curbits = ff_aac_spectral_bits[cb-1][curidx];
vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
- if (IS_CODEBOOK_UNSIGNED(cb)) {
+ if (BT_UNSIGNED) {
for (k = 0; k < dim; k++) {
float t = fabsf(in[i+k]);
float di;
- if (vec[k] == 64.0f) { //FIXME: slow
+ if (BT_ESC && vec[k] == 64.0f) { //FIXME: slow
if (t >= CLIPPED_ESCAPE) {
di = t - CLIPPED_ESCAPE;
curbits += 21;
if (cost >= uplim)
return uplim;
if (pb) {
- 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][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][curidx*2+j] == 64.0f) {
- int coef = av_clip(quant(fabsf(in[i+j]), Q), 0, 8191);
- int len = av_log2(coef);
+ put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);
+ if (BT_UNSIGNED)
+ for (j = 0; j < dim; j++)
+ if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)
+ put_bits(pb, 1, in[i+j] < 0.0f);
+ if (BT_ESC) {
+ for (j = 0; j < 2; j++) {
+ 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);
- put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
- put_bits(pb, len, coef & ((1 << len) - 1));
+ put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
+ put_bits(pb, len, coef & ((1 << len) - 1));
+ }
}
}
}
- }
}
if (bits)
*bits = resbits;
return cost;
}
+
+#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC) \
+static float quantize_and_encode_band_cost_ ## NAME( \
+ struct AACEncContext *s, \
+ PutBitContext *pb, const float *in, \
+ const float *scaled, int size, int scale_idx, \
+ int cb, const float lambda, const float uplim, \
+ int *bits) { \
+ return quantize_and_encode_band_cost_template( \
+ s, pb, in, scaled, size, scale_idx, \
+ BT_ESC ? ESC_BT : cb, lambda, uplim, bits, \
+ BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC); \
+}
+
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1)
+
+static float (*const quantize_and_encode_band_cost_arr[])(
+ struct AACEncContext *s,
+ PutBitContext *pb, const float *in,
+ const float *scaled, int size, int scale_idx,
+ int cb, const float lambda, const float uplim,
+ int *bits) = {
+ quantize_and_encode_band_cost_ZERO,
+ quantize_and_encode_band_cost_SQUAD,
+ quantize_and_encode_band_cost_SQUAD,
+ quantize_and_encode_band_cost_UQUAD,
+ quantize_and_encode_band_cost_UQUAD,
+ quantize_and_encode_band_cost_SPAIR,
+ quantize_and_encode_band_cost_SPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_ESC,
+};
+
+#define quantize_and_encode_band_cost( \
+ s, pb, in, scaled, size, scale_idx, cb, \
+ lambda, uplim, bits) \
+ quantize_and_encode_band_cost_arr[cb]( \
+ s, pb, in, scaled, size, scale_idx, cb, \
+ lambda, uplim, bits)
+
static float quantize_band_cost(struct AACEncContext *s, const float *in,
const float *scaled, int size, int scale_idx,
int cb, const float lambda, const float uplim,
idx = cb;
ppos = max_sfb;
while (ppos > 0) {
- if (idx < 0) abort();
+ assert(idx >= 0);
cb = idx;
stackrun[stack_len] = path[ppos][cb].run;
stackcb [stack_len] = cb;
}
}
+/** Return the minimum scalefactor where the quantized coef does not clip. */
+static av_always_inline uint8_t coef2minsf(float coef) {
+ return av_clip_uint8(log2f(coef)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
+}
+
+/** Return the maximum scalefactor where the quantized coef is not zero. */
+static av_always_inline uint8_t coef2maxsf(float coef) {
+ return av_clip_uint8(log2f(coef)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
+}
+
typedef struct TrellisPath {
float cost;
int prev;
}
//minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped
- q0 = av_clip_uint8(log2(q0f)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
+ q0 = coef2minsf(q0f);
//maximum scalefactor index is when maximum coefficient after quantizing is still not zero
- q1 = av_clip_uint8(log2(q1f)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
+ q1 = coef2maxsf(q1f);
//av_log(NULL, AV_LOG_ERROR, "q0 %d, q1 %d\n", q0, q1);
if (q1 - q0 > 60) {
int q0low = q0;
int q1high = q1;
//minimum scalefactor index is when maximum nonzero coefficient after quantizing is not clipped
- int qnrg = av_clip_uint8(log2(sqrt(qnrgf/qcnt))*4 - 31 + SCALE_ONE_POS - SCALE_DIV_512);
+ int qnrg = av_clip_uint8(log2f(sqrtf(qnrgf/qcnt))*4 - 31 + SCALE_ONE_POS - SCALE_DIV_512);
q1 = qnrg + 30;
q0 = qnrg - 30;
//av_log(NULL, AV_LOG_ERROR, "q0 %d, q1 %d\n", q0, q1);
float minrd = INFINITY;
float maxval;
//minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped
- minscale = av_clip_uint8(log2(qmin)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
+ minscale = coef2minsf(qmin);
//maximum scalefactor index is when maximum coefficient after quantizing is still not zero
- maxscale = av_clip_uint8(log2(qmax)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
+ maxscale = coef2maxsf(qmax);
minscale = av_clip(minscale - q0, 0, TRELLIS_STATES - 1);
maxscale = av_clip(maxscale - q0, 0, TRELLIS_STATES);
maxval = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], s->scoefs+start);
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
- q + q0, cb, lambda / band->threshold, INFINITY, NULL);
+ q + q0, cb, lambda / band->threshold, INFINITY, NULL);
}
minrd = FFMIN(minrd, dist);
}
} else {
for (q = 0; q < q1 - q0; q++) {
- paths[idx][q].cost = paths[idx - 1][q].cost + 1;
- paths[idx][q].prev = q;
+ paths[idx][q].cost = paths[idx - 1][q].cost + 1;
+ paths[idx][q].prev = q;
}
}
sce->zeroes[w*16+g] = !nz;
int start = 0, i, w, w2, g;
int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
float dists[128], uplims[128];
+ float maxvals[128];
int fflag, minscaler;
int its = 0;
int allz = 0;
sce->sf_idx[w*16+g] = SCALE_ONE_POS;
continue;
}
- sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2(uplims[w*16+g]/minthr)*4,59);
+ sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2f(uplims[w*16+g]/minthr)*4,59);
}
}
if (!allz)
return;
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
+
+ for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
+ start = w*128;
+ for (g = 0; g < sce->ics.num_swb; g++) {
+ const float *scaled = s->scoefs + start;
+ maxvals[w*16+g] = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], scaled);
+ start += sce->ics.swb_sizes[g];
+ }
+ }
+
//perform two-loop search
//outer loop - improve quality
do {
const float *scaled = s->scoefs + start;
int bits = 0;
int cb;
- float mindist = INFINITY;
- int minbits = 0;
+ float dist = 0.0f;
if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) {
start += sce->ics.swb_sizes[g];
continue;
}
minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
- {
- float dist = 0.0f;
- int bb = 0;
- cb = find_min_book(find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], scaled), sce->sf_idx[w*16+g]);
- sce->band_type[w*16+g] = cb;
- for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- int b;
- dist += quantize_band_cost(s, coefs + w2*128,
- scaled + w2*128,
- sce->ics.swb_sizes[g],
- sce->sf_idx[w*16+g],
- cb,
- lambda,
- INFINITY,
- &b);
- bb += b;
- }
- mindist = dist;
- minbits = bb;
+ cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
+ for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
+ int b;
+ dist += quantize_band_cost(s, coefs + w2*128,
+ scaled + w2*128,
+ sce->ics.swb_sizes[g],
+ sce->sf_idx[w*16+g],
+ cb,
+ 1.0f,
+ INFINITY,
+ &b);
+ bits += b;
}
- dists[w*16+g] = (mindist - minbits) / lambda;
- bits = minbits;
+ dists[w*16+g] = dist - bits;
if (prev != -1) {
bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
}
sce->sf_idx[i] -= qstep;
}
qstep >>= 1;
- if (!qstep && tbits > destbits*1.02)
+ if (!qstep && tbits > destbits*1.02 && sce->sf_idx[0] < 217)
qstep = 1;
- if (sce->sf_idx[0] >= 217)
- break;
} while (qstep);
fflag = 0;
minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- start = w*128;
for (g = 0; g < sce->ics.num_swb; g++) {
int prevsc = sce->sf_idx[w*16+g];
- if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60)
+ if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) {
+ if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1))
sce->sf_idx[w*16+g]--;
+ else //Try to make sure there is some energy in every band
+ sce->sf_idx[w*16+g]-=2;
+ }
sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);
if (sce->sf_idx[w*16+g] != prevsc)
fflag = 1;
+ sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
}
}
its++;
continue;
}
sce->zeroes[w*16+g] = 0;
- scf = prev_scf = av_clip(SCALE_ONE_POS - SCALE_DIV_512 - log2(1/maxq[w*16+g])*16/3, 60, 218);
+ scf = prev_scf = av_clip(SCALE_ONE_POS - SCALE_DIV_512 - log2f(1/maxq[w*16+g])*16/3, 60, 218);
step = 16;
for (;;) {
float dist = 0.0f;
if (curdiff <= 1.0f)
step = 0;
else
- step = log2(curdiff);
+ step = log2f(curdiff);
if (dist > uplim[w*16+g])
step = -step;
scf += step;
sce->sf_idx[(w+w2)*16+g] = 218;
sce->zeroes[(w+w2)*16+g] = 1;
} else {
- sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2(band->threshold), 80, 218);
+ sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2f(band->threshold), 80, 218);
sce->zeroes[(w+w2)*16+g] = 0;
}
minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);