AAC encoder: refactor to resynchronize MIPS port
[ffmpeg.git] / libavcodec / mips / aaccoder_mips.c
index 0f12168..bc3268f 100644 (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;
-
-    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];
-    }
+#include "libavcodec/aaccoder_trellis.h"
 
-    //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 */
 }