AAC encoder: refactor to resynchronize MIPS port

This patch refactors the AAC coders to reuse code
between the MIPS port and the regular, portable C code.
There were two main functions that had to use
hand-optimized versions of quantization code:
 - search_for_quantizers_twoloop
 - codebook_trellis_rate

Those two were split into their own template header
files so they can be inlined inside both the MIPS port
and the generic code. In each context, they'll link
to their specialized implementations, and thus be
optimized by the compiler.

This approach I believe is better than maintaining
several copies of each function. As past experience has
proven, having to keep those in sync was error prone.
In this way, they will remain in sync by default.

Also, an implementation of the dequantized output
argument for the optimized quantize_and_encode
functions is included in the patch. While the current
implementation of search_for_pred still isn't using
it, future iterations of main prediction probably will.
It should not imply any measurable performance hit while
not being used.
This commit is contained in:
Claudio Freire
2015-09-15 03:59:45 -03:00
parent 344d519040
commit 8df9bf8e39
6 changed files with 538 additions and 624 deletions

View File

@@ -63,6 +63,7 @@
#include "libavcodec/aacenc.h"
#include "libavcodec/aacenctab.h"
#include "libavcodec/aactab.h"
#include "libavcodec/aacenctab.h"
#if HAVE_INLINE_ASM
typedef struct BandCodingPath {
@@ -199,11 +200,13 @@ static void quantize_and_encode_band_cost_SQUAD_mips(struct AACEncContext *s,
int *bits, const float ROUNDING)
{
const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i;
int qc1, qc2, qc3, qc4;
uint8_t *p_bits = (uint8_t *)ff_aac_spectral_bits[cb-1];
uint16_t *p_codes = (uint16_t *)ff_aac_spectral_codes[cb-1];
float *p_vec = (float *)ff_aac_codebook_vectors[cb-1];
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
@@ -211,6 +214,7 @@ static void quantize_and_encode_band_cost_SQUAD_mips(struct AACEncContext *s,
int curidx;
int *in_int = (int *)&in[i];
int t0, t1, t2, t3, t4, t5, t6, t7;
const float *vec;
qc1 = scaled[i ] * Q34 + ROUND_STANDARD;
qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;
@@ -262,6 +266,14 @@ static void quantize_and_encode_band_cost_SQUAD_mips(struct AACEncContext *s,
curidx += 40;
put_bits(pb, p_bits[curidx], p_codes[curidx]);
if (out) {
vec = &p_vec[curidx*4];
out[i+0] = vec[0] * IQ;
out[i+1] = vec[1] * IQ;
out[i+2] = vec[2] * IQ;
out[i+3] = vec[3] * IQ;
}
}
}
@@ -272,11 +284,13 @@ static void quantize_and_encode_band_cost_UQUAD_mips(struct AACEncContext *s,
int *bits, const float ROUNDING)
{
const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i;
int qc1, qc2, qc3, qc4;
uint8_t *p_bits = (uint8_t *)ff_aac_spectral_bits[cb-1];
uint16_t *p_codes = (uint16_t *)ff_aac_spectral_codes[cb-1];
float *p_vec = (float *)ff_aac_codebook_vectors[cb-1];
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
@@ -286,6 +300,7 @@ static void quantize_and_encode_band_cost_UQUAD_mips(struct AACEncContext *s,
uint8_t v_bits;
unsigned int v_codes;
int t0, t1, t2, t3, t4;
const float *vec;
qc1 = scaled[i ] * Q34 + ROUND_STANDARD;
qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;
@@ -354,6 +369,14 @@ static void quantize_and_encode_band_cost_UQUAD_mips(struct AACEncContext *s,
v_codes = (p_codes[curidx] << count) | (sign & ((1 << count) - 1));
v_bits = p_bits[curidx] + count;
put_bits(pb, v_bits, v_codes);
if (out) {
vec = &p_vec[curidx*4];
out[i+0] = copysignf(vec[0] * IQ, in[i+0]);
out[i+1] = copysignf(vec[1] * IQ, in[i+1]);
out[i+2] = copysignf(vec[2] * IQ, in[i+2]);
out[i+3] = copysignf(vec[3] * IQ, in[i+3]);
}
}
}
@@ -364,11 +387,13 @@ static void quantize_and_encode_band_cost_SPAIR_mips(struct AACEncContext *s,
int *bits, const float ROUNDING)
{
const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i;
int qc1, qc2, qc3, qc4;
uint8_t *p_bits = (uint8_t *)ff_aac_spectral_bits[cb-1];
uint16_t *p_codes = (uint16_t *)ff_aac_spectral_codes[cb-1];
float *p_vec = (float *)ff_aac_codebook_vectors[cb-1];
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
@@ -378,6 +403,7 @@ static void quantize_and_encode_band_cost_SPAIR_mips(struct AACEncContext *s,
uint8_t v_bits;
unsigned int v_codes;
int t0, t1, t2, t3, t4, t5, t6, t7;
const float *vec1, *vec2;
qc1 = scaled[i ] * Q34 + ROUND_STANDARD;
qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;
@@ -433,6 +459,15 @@ static void quantize_and_encode_band_cost_SPAIR_mips(struct AACEncContext *s,
v_codes = (p_codes[curidx] << p_bits[curidx2]) | (p_codes[curidx2]);
v_bits = p_bits[curidx] + p_bits[curidx2];
put_bits(pb, v_bits, v_codes);
if (out) {
vec1 = &p_vec[curidx*2 ];
vec2 = &p_vec[curidx2*2];
out[i+0] = vec1[0] * IQ;
out[i+1] = vec1[1] * IQ;
out[i+2] = vec2[0] * IQ;
out[i+3] = vec2[1] * IQ;
}
}
}
@@ -443,20 +478,23 @@ static void quantize_and_encode_band_cost_UPAIR7_mips(struct AACEncContext *s,
int *bits, const float ROUNDING)
{
const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i;
int qc1, qc2, qc3, qc4;
uint8_t *p_bits = (uint8_t*) ff_aac_spectral_bits[cb-1];
uint16_t *p_codes = (uint16_t*)ff_aac_spectral_codes[cb-1];
float *p_vec = (float *)ff_aac_codebook_vectors[cb-1];
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
for (i = 0; i < size; i += 4) {
int curidx, sign1, count1, sign2, count2;
int curidx1, curidx2, sign1, count1, sign2, count2;
int *in_int = (int *)&in[i];
uint8_t v_bits;
unsigned int v_codes;
int t0, t1, t2, t3, t4;
const float *vec1, *vec2;
qc1 = scaled[i ] * Q34 + ROUND_STANDARD;
qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;
@@ -514,19 +552,28 @@ static void quantize_and_encode_band_cost_UPAIR7_mips(struct AACEncContext *s,
"memory"
);
curidx = 8 * qc1;
curidx += qc2;
curidx1 = 8 * qc1;
curidx1 += qc2;
v_codes = (p_codes[curidx] << count1) | sign1;
v_bits = p_bits[curidx] + count1;
v_codes = (p_codes[curidx1] << count1) | sign1;
v_bits = p_bits[curidx1] + count1;
put_bits(pb, v_bits, v_codes);
curidx = 8 * qc3;
curidx += qc4;
curidx2 = 8 * qc3;
curidx2 += qc4;
v_codes = (p_codes[curidx] << count2) | sign2;
v_bits = p_bits[curidx] + count2;
v_codes = (p_codes[curidx2] << count2) | sign2;
v_bits = p_bits[curidx2] + count2;
put_bits(pb, v_bits, v_codes);
if (out) {
vec1 = &p_vec[curidx1*2];
vec2 = &p_vec[curidx2*2];
out[i+0] = copysignf(vec1[0] * IQ, in[i+0]);
out[i+1] = copysignf(vec1[1] * IQ, in[i+1]);
out[i+2] = copysignf(vec2[0] * IQ, in[i+2]);
out[i+3] = copysignf(vec2[1] * IQ, in[i+3]);
}
}
}
@@ -537,20 +584,23 @@ static void quantize_and_encode_band_cost_UPAIR12_mips(struct AACEncContext *s,
int *bits, const float ROUNDING)
{
const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i;
int qc1, qc2, qc3, qc4;
uint8_t *p_bits = (uint8_t*) ff_aac_spectral_bits[cb-1];
uint16_t *p_codes = (uint16_t*)ff_aac_spectral_codes[cb-1];
float *p_vec = (float *)ff_aac_codebook_vectors[cb-1];
abs_pow34_v(s->scoefs, in, size);
scaled = s->scoefs;
for (i = 0; i < size; i += 4) {
int curidx, sign1, count1, sign2, count2;
int curidx1, curidx2, sign1, count1, sign2, count2;
int *in_int = (int *)&in[i];
uint8_t v_bits;
unsigned int v_codes;
int t0, t1, t2, t3, t4;
const float *vec1, *vec2;
qc1 = scaled[i ] * Q34 + ROUND_STANDARD;
qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;
@@ -607,19 +657,28 @@ static void quantize_and_encode_band_cost_UPAIR12_mips(struct AACEncContext *s,
: "memory"
);
curidx = 13 * qc1;
curidx += qc2;
curidx1 = 13 * qc1;
curidx1 += qc2;
v_codes = (p_codes[curidx] << count1) | sign1;
v_bits = p_bits[curidx] + count1;
v_codes = (p_codes[curidx1] << count1) | sign1;
v_bits = p_bits[curidx1] + count1;
put_bits(pb, v_bits, v_codes);
curidx = 13 * qc3;
curidx += qc4;
curidx2 = 13 * qc3;
curidx2 += qc4;
v_codes = (p_codes[curidx] << count2) | sign2;
v_bits = p_bits[curidx] + count2;
v_codes = (p_codes[curidx2] << count2) | sign2;
v_bits = p_bits[curidx2] + count2;
put_bits(pb, v_bits, v_codes);
if (out) {
vec1 = &p_vec[curidx1*2];
vec2 = &p_vec[curidx2*2];
out[i+0] = copysignf(vec1[0] * IQ, in[i+0]);
out[i+1] = copysignf(vec1[1] * IQ, in[i+1]);
out[i+2] = copysignf(vec2[0] * IQ, in[i+2]);
out[i+3] = copysignf(vec2[1] * IQ, in[i+3]);
}
}
}
@@ -630,6 +689,7 @@ static void quantize_and_encode_band_cost_ESC_mips(struct AACEncContext *s,
int *bits, const float ROUNDING)
{
const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i;
int qc1, qc2, qc3, qc4;
@@ -647,6 +707,7 @@ static void quantize_and_encode_band_cost_ESC_mips(struct AACEncContext *s,
uint8_t v_bits;
unsigned int v_codes;
int t0, t1, t2, t3, t4;
const float *vec1, *vec2;
qc1 = scaled[i ] * Q34 + ROUNDING;
qc2 = scaled[i+1] * Q34 + ROUNDING;
@@ -715,6 +776,15 @@ static void quantize_and_encode_band_cost_ESC_mips(struct AACEncContext *s,
v_codes = (p_codes[curidx2] << count2) | sign2;
v_bits = p_bits[curidx2] + count2;
put_bits(pb, v_bits, v_codes);
if (out) {
vec1 = &p_vectors[curidx*2 ];
vec2 = &p_vectors[curidx2*2];
out[i+0] = copysignf(vec1[0] * IQ, in[i+0]);
out[i+1] = copysignf(vec1[1] * IQ, in[i+1]);
out[i+2] = copysignf(vec2[0] * IQ, in[i+2]);
out[i+3] = copysignf(vec2[1] * IQ, in[i+3]);
}
}
} else {
for (i = 0; i < size; i += 4) {
@@ -724,6 +794,7 @@ static void quantize_and_encode_band_cost_ESC_mips(struct AACEncContext *s,
unsigned int v_codes;
int c1, c2, c3, c4;
int t0, t1, t2, t3, t4;
const float *vec1, *vec2;
qc1 = scaled[i ] * Q34 + ROUNDING;
qc2 = scaled[i+1] * Q34 + ROUNDING;
@@ -825,6 +896,15 @@ static void quantize_and_encode_band_cost_ESC_mips(struct AACEncContext *s,
v_codes = (((1 << (len - 3)) - 2) << len) | (c4 & ((1 << len) - 1));
put_bits(pb, len * 2 - 3, v_codes);
}
if (out) {
vec1 = &p_vectors[curidx*2];
vec2 = &p_vectors[curidx2*2];
out[i+0] = copysignf(c1 * cbrtf(c1) * IQ, in[i+0]);
out[i+1] = copysignf(c2 * cbrtf(c2) * IQ, in[i+1]);
out[i+2] = copysignf(c3 * cbrtf(c3) * IQ, in[i+2]);
out[i+3] = copysignf(c4 * cbrtf(c4) * IQ, in[i+3]);
}
}
}
}
@@ -1370,7 +1450,7 @@ static float (*const get_band_numbits_arr[])(struct AACEncContext *s,
static float quantize_band_cost_bits(struct AACEncContext *s, const float *in,
const float *scaled, int size, int scale_idx,
int cb, const float lambda, const float uplim,
int *bits)
int *bits, int rtz)
{
return get_band_numbits(s, NULL, in, scaled, size, scale_idx, cb, lambda, uplim, bits);
}
@@ -2175,195 +2255,12 @@ static float (*const get_band_cost_arr[])(struct AACEncContext *s,
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,
int *bits)
int *bits, int rtz)
{
return get_band_cost(s, NULL, in, scaled, size, scale_idx, cb, lambda, uplim, bits);
}
static void search_for_quantizers_twoloop_mips(AVCodecContext *avctx,
AACEncContext *s,
SingleChannelElement *sce,
const float lambda)
{
int start = 0, i, w, w2, g;
int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f);
float dists[128] = { 0 }, uplims[128] = { 0 };
float maxvals[128];
int fflag, minscaler;
int its = 0;
int allz = 0;
float minthr = INFINITY;
// for values above this the decoder might end up in an endless loop
// due to always having more bits than what can be encoded.
destbits = FFMIN(destbits, 5800);
//XXX: some heuristic to determine initial quantizers will reduce search time
//determine zero bands and upper limits
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
for (g = 0; g < sce->ics.num_swb; g++) {
int nz = 0;
float uplim = 0.0f, energy = 0.0f;
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
uplim += band->threshold;
energy += band->energy;
if (band->energy <= band->threshold || band->threshold == 0.0f) {
sce->zeroes[(w+w2)*16+g] = 1;
continue;
}
nz = 1;
}
uplims[w*16+g] = uplim *512;
sce->zeroes[w*16+g] = !nz;
if (nz)
minthr = FFMIN(minthr, uplim);
allz |= nz;
}
}
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
for (g = 0; g < sce->ics.num_swb; g++) {
if (sce->zeroes[w*16+g]) {
sce->sf_idx[w*16+g] = SCALE_ONE_POS;
continue;
}
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 {
int tbits, qstep;
minscaler = sce->sf_idx[0];
//inner loop - quantize spectrum to fit into given number of bits
qstep = its ? 1 : 32;
do {
int prev = -1;
tbits = 0;
fflag = 0;
if (qstep > 1) {
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 *coefs = sce->coeffs + start;
const float *scaled = s->scoefs + start;
int bits = 0;
int cb;
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]);
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;
bits += quantize_band_cost_bits(s, coefs + w2*128,
scaled + w2*128,
sce->ics.swb_sizes[g],
sce->sf_idx[w*16+g],
cb,
1.0f,
INFINITY,
&b);
}
if (prev != -1) {
bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
}
tbits += bits;
start += sce->ics.swb_sizes[g];
prev = sce->sf_idx[w*16+g];
}
}
}
else {
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 *coefs = sce->coeffs + start;
const float *scaled = s->scoefs + start;
int bits = 0;
int cb;
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]);
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] = dist - bits;
if (prev != -1) {
bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
}
tbits += bits;
start += sce->ics.swb_sizes[g];
prev = sce->sf_idx[w*16+g];
}
}
}
if (tbits > destbits) {
for (i = 0; i < 128; i++)
if (sce->sf_idx[i] < 218 - qstep)
sce->sf_idx[i] += qstep;
} else {
for (i = 0; i < 128; i++)
if (sce->sf_idx[i] > 60 - qstep)
sce->sf_idx[i] -= qstep;
}
qstep >>= 1;
if (!qstep && tbits > destbits*1.02 && sce->sf_idx[0] < 217)
qstep = 1;
} 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]) {
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 (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++;
} while (fflag && its < 10);
}
#include "libavcodec/aaccoder_twoloop.h"
static void search_for_ms_mips(AACEncContext *s, ChannelElement *cpe)
{
@@ -2413,25 +2310,25 @@ static void search_for_ms_mips(AACEncContext *s, ChannelElement *cpe)
sce0->ics.swb_sizes[g],
sce0->sf_idx[(w+w2)*16+g],
sce0->band_type[(w+w2)*16+g],
lambda / band0->threshold, INFINITY, NULL);
lambda / band0->threshold, INFINITY, NULL, 0);
dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
R34,
sce1->ics.swb_sizes[g],
sce1->sf_idx[(w+w2)*16+g],
sce1->band_type[(w+w2)*16+g],
lambda / band1->threshold, INFINITY, NULL);
lambda / band1->threshold, INFINITY, NULL, 0);
dist2 += quantize_band_cost(s, M,
M34,
sce0->ics.swb_sizes[g],
sce0->sf_idx[(w+w2)*16+g],
sce0->band_type[(w+w2)*16+g],
lambda / maxthr, INFINITY, NULL);
lambda / maxthr, INFINITY, NULL, 0);
dist2 += quantize_band_cost(s, S,
S34,
sce1->ics.swb_sizes[g],
sce1->sf_idx[(w+w2)*16+g],
sce1->band_type[(w+w2)*16+g],
lambda / minthr, INFINITY, NULL);
lambda / minthr, INFINITY, NULL, 0);
}
cpe->ms_mask[w*16+g] = dist2 < dist1;
}
@@ -2441,137 +2338,8 @@ static void search_for_ms_mips(AACEncContext *s, ChannelElement *cpe)
}
#endif /*HAVE_MIPSFPU */
static void codebook_trellis_rate_mips(AACEncContext *s, SingleChannelElement *sce,
int win, int group_len, const float lambda)
{
BandCodingPath path[120][CB_TOT_ALL];
int w, swb, cb, start, size;
int i, j;
const int max_sfb = sce->ics.max_sfb;
const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
const int run_esc = (1 << run_bits) - 1;
int idx, ppos, count;
int stackrun[120], stackcb[120], stack_len;
float next_minbits = INFINITY;
int next_mincb = 0;
#include "libavcodec/aaccoder_trellis.h"
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
start = win*128;
for (cb = 0; cb < CB_TOT_ALL; cb++) {
path[0][cb].cost = run_bits+4;
path[0][cb].prev_idx = -1;
path[0][cb].run = 0;
}
for (swb = 0; swb < max_sfb; swb++) {
size = sce->ics.swb_sizes[swb];
if (sce->zeroes[win*16 + swb]) {
float cost_stay_here = path[swb][0].cost;
float cost_get_here = next_minbits + run_bits + 4;
if ( run_value_bits[sce->ics.num_windows == 8][path[swb][0].run]
!= run_value_bits[sce->ics.num_windows == 8][path[swb][0].run+1])
cost_stay_here += run_bits;
if (cost_get_here < cost_stay_here) {
path[swb+1][0].prev_idx = next_mincb;
path[swb+1][0].cost = cost_get_here;
path[swb+1][0].run = 1;
} else {
path[swb+1][0].prev_idx = 0;
path[swb+1][0].cost = cost_stay_here;
path[swb+1][0].run = path[swb][0].run + 1;
}
next_minbits = path[swb+1][0].cost;
next_mincb = 0;
for (cb = 1; cb < CB_TOT_ALL; cb++) {
path[swb+1][cb].cost = 61450;
path[swb+1][cb].prev_idx = -1;
path[swb+1][cb].run = 0;
}
} else {
float minbits = next_minbits;
int mincb = next_mincb;
int startcb = sce->band_type[win*16+swb];
startcb = aac_cb_in_map[startcb];
next_minbits = INFINITY;
next_mincb = 0;
for (cb = 0; cb < startcb; cb++) {
path[swb+1][cb].cost = 61450;
path[swb+1][cb].prev_idx = -1;
path[swb+1][cb].run = 0;
}
for (cb = startcb; cb < CB_TOT_ALL; cb++) {
float cost_stay_here, cost_get_here;
float bits = 0.0f;
if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) {
path[swb+1][cb].cost = 61450;
path[swb+1][cb].prev_idx = -1;
path[swb+1][cb].run = 0;
continue;
}
for (w = 0; w < group_len; w++) {
bits += quantize_band_cost_bits(s, sce->coeffs + start + w*128,
s->scoefs + start + w*128, size,
sce->sf_idx[(win+w)*16+swb],
aac_cb_out_map[cb],
0, INFINITY, NULL);
}
cost_stay_here = path[swb][cb].cost + bits;
cost_get_here = minbits + bits + run_bits + 4;
if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
!= run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
cost_stay_here += run_bits;
if (cost_get_here < cost_stay_here) {
path[swb+1][cb].prev_idx = mincb;
path[swb+1][cb].cost = cost_get_here;
path[swb+1][cb].run = 1;
} else {
path[swb+1][cb].prev_idx = cb;
path[swb+1][cb].cost = cost_stay_here;
path[swb+1][cb].run = path[swb][cb].run + 1;
}
if (path[swb+1][cb].cost < next_minbits) {
next_minbits = path[swb+1][cb].cost;
next_mincb = cb;
}
}
}
start += sce->ics.swb_sizes[swb];
}
//convert resulting path from backward-linked list
stack_len = 0;
idx = 0;
for (cb = 1; cb < CB_TOT_ALL; cb++)
if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
idx = cb;
ppos = max_sfb;
while (ppos > 0) {
av_assert1(idx >= 0);
cb = idx;
stackrun[stack_len] = path[ppos][cb].run;
stackcb [stack_len] = cb;
idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;
ppos -= path[ppos][cb].run;
stack_len++;
}
//perform actual band info encoding
start = 0;
for (i = stack_len - 1; i >= 0; i--) {
cb = aac_cb_out_map[stackcb[i]];
put_bits(&s->pb, 4, cb);
count = stackrun[i];
memset(sce->zeroes + win*16 + start, !cb, count);
//XXX: memset when band_type is also uint8_t
for (j = 0; j < count; j++) {
sce->band_type[win*16 + start] = cb;
start++;
}
while (count >= run_esc) {
put_bits(&s->pb, run_bits, run_esc);
count -= run_esc;
}
put_bits(&s->pb, run_bits, count);
}
}
#endif /* HAVE_INLINE_ASM */
void ff_aac_coder_init_mips(AACEncContext *c) {
@@ -2581,11 +2349,13 @@ void ff_aac_coder_init_mips(AACEncContext *c) {
if (option == 2) {
e->quantize_and_encode_band = quantize_and_encode_band_mips;
e->encode_window_bands_info = codebook_trellis_rate_mips;
e->encode_window_bands_info = codebook_trellis_rate;
#if HAVE_MIPSFPU
e->search_for_quantizers = search_for_quantizers_twoloop_mips;
e->search_for_ms = search_for_ms_mips;
e->search_for_quantizers = search_for_quantizers_twoloop;
#endif /* HAVE_MIPSFPU */
}
#if HAVE_MIPSFPU
e->search_for_ms = search_for_ms_mips;
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
}