[FFmpeg-soc] [soc]: r4008 - in aacenc: aac_enc.patch aaccoder.c aacenc.c aacenc.h

kostya subversion at mplayerhq.hu
Mon Jan 26 15:07:29 CET 2009


Author: kostya
Date: Mon Jan 26 15:07:28 2009
New Revision: 4008

Log:
Split out from AAC encoder core file all functions with heuristics for selecting
scalefactors, band codebooks, etc.

Added:
   aacenc/aaccoder.c
      - copied, changed from r4006, aacenc/aacenc.c
   aacenc/aacenc.h
      - copied, changed from r4006, aacenc/aacenc.c
Modified:
   aacenc/aac_enc.patch
   aacenc/aacenc.c

Modified: aacenc/aac_enc.patch
==============================================================================
--- aacenc/aac_enc.patch	Mon Jan 26 15:00:57 2009	(r4007)
+++ aacenc/aac_enc.patch	Mon Jan 26 15:07:28 2009	(r4008)
@@ -2,14 +2,14 @@ diff --git a/libavcodec/Makefile b/libav
 index d4f6d1c..0ed9057 100644
 --- a/libavcodec/Makefile
 +++ b/libavcodec/Makefile
-@@ -25,6 +25,7 @@
- 
- OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
+@@ -33,6 +33,7 @@
  
-+OBJS-$(CONFIG_AAC_ENCODER)             += aacenc.o aacpsy.o aactab.o psymodel.o iirfilter.o mdct.o fft.o mpeg4audio.o
- OBJS-$(CONFIG_AAC_DECODER)             += aac.o aactab.o mdct.o fft.o
- OBJS-$(CONFIG_AASC_DECODER)            += aasc.o
- OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3tab.o ac3dec_data.o ac3.o mdct.o fft.o
+ # decoders/encoders
+ OBJS-$(CONFIG_AAC_DECODER)             += aac.o aactab.o
++OBJS-$(CONFIG_AAC_ENCODER)             += aacenc.o aaccoder.o aacpsy.o aactab.o psymodel.o iirfilter.o mdct.o fft.o mpeg4audio.o
+ OBJS-$(CONFIG_AASC_DECODER)            += aasc.o msrledec.o
+ OBJS-$(CONFIG_AC3_DECODER)             += eac3dec.o ac3dec.o ac3tab.o ac3dec_data.o ac3.o
+ OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc.o ac3tab.o ac3.o
 diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
 index 33a4242..6871496 100644
 --- a/libavcodec/allcodecs.c

Copied and modified: aacenc/aaccoder.c (from r4006, aacenc/aacenc.c)
==============================================================================
--- aacenc/aacenc.c	Mon Jan 26 14:37:36 2009	(r4006, copy source)
+++ aacenc/aaccoder.c	Mon Jan 26 15:07:28 2009	(r4008)
@@ -1,6 +1,6 @@
 /*
- * AAC encoder
- * Copyright (C) 2008 Konstantin Shishkov
+ * AAC coefficients encoder
+ * Copyright (C) 2008-2009 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  *
@@ -20,106 +20,16 @@
  */
 
 /**
- * @file aacenc.c
- * AAC encoder
+ * @file aaccoder.c
+ * AAC coefficients encoder
  */
 
-/***********************************
- *              TODOs:
- * speedup quantizer selection
- * add sane pulse detection
- * add temporal noise shaping
- ***********************************/
-
 #include "avcodec.h"
 #include "bitstream.h"
-#include "dsputil.h"
-#include "mpeg4audio.h"
-
 #include "aac.h"
+#include "aacenc.h"
 #include "aactab.h"
 
-#include "psymodel.h"
-
-static const uint8_t swb_size_1024_96[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-};
-
-static const uint8_t swb_size_1024_64[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
-    12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36,
-    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40
-};
-
-static const uint8_t swb_size_1024_48[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    96
-};
-
-static const uint8_t swb_size_1024_32[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
-};
-
-static const uint8_t swb_size_1024_24[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28,
-    32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
-};
-
-static const uint8_t swb_size_1024_16[] = {
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28,
-    32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64
-};
-
-static const uint8_t swb_size_1024_8[] = {
-    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-    16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28,
-    32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80
-};
-
-static const uint8_t *swb_size_1024[] = {
-    swb_size_1024_96, swb_size_1024_96, swb_size_1024_64,
-    swb_size_1024_48, swb_size_1024_48, swb_size_1024_32,
-    swb_size_1024_24, swb_size_1024_24, swb_size_1024_16,
-    swb_size_1024_16, swb_size_1024_16, swb_size_1024_8
-};
-
-static const uint8_t swb_size_128_96[] = {
-    4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
-};
-
-static const uint8_t swb_size_128_48[] = {
-    4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16
-};
-
-static const uint8_t swb_size_128_24[] = {
-    4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20
-};
-
-static const uint8_t swb_size_128_16[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20
-};
-
-static const uint8_t swb_size_128_8[] = {
-    4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20
-};
-
-static const uint8_t *swb_size_128[] = {
-    /* the last entry on the following row is swb_size_128_64 but is a
-       duplicate of swb_size_128_96 */
-    swb_size_128_96, swb_size_128_96, swb_size_128_96,
-    swb_size_128_48, swb_size_128_48, swb_size_128_48,
-    swb_size_128_24, swb_size_128_24, swb_size_128_16,
-    swb_size_128_16, swb_size_128_16, swb_size_128_8
-};
-
 /** bits needed to code codebook run value for long windows */
 static const uint8_t run_value_bits_long[64] = {
      5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
@@ -137,199 +47,6 @@ static const uint8_t* run_value_bits[2] 
     run_value_bits_long, run_value_bits_short
 };
 
-/** default channel configurations */
-static const uint8_t aac_chan_configs[6][5] = {
- {1, TYPE_SCE},                               // 1 channel  - single channel element
- {1, TYPE_CPE},                               // 2 channels - channel pair
- {2, TYPE_SCE, TYPE_CPE},                     // 3 channels - center + stereo
- {3, TYPE_SCE, TYPE_CPE, TYPE_SCE},           // 4 channels - front center + stereo + back center
- {3, TYPE_SCE, TYPE_CPE, TYPE_CPE},           // 5 channels - front center + stereo + back stereo
- {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
-};
-
-/**
- * AAC encoder context
- */
-typedef struct {
-    PutBitContext pb;
-    MDCTContext mdct1024;                        ///< long (1024 samples) frame transform context
-    MDCTContext mdct128;                         ///< short (128 samples) frame transform context
-    DSPContext  dsp;
-    DECLARE_ALIGNED_16(FFTSample, output[2048]); ///< temporary buffer for MDCT input coefficients
-    int16_t* samples;                            ///< saved preprocessed input
-
-    int samplerate_index;                        ///< MPEG-4 samplerate index
-
-    ChannelElement *cpe;                         ///< channel elements
-    FFPsyContext psy;
-    struct FFPsyPreprocessContext* psypp;
-    int cur_channel;
-    int last_frame;
-    float lambda;
-} AACEncContext;
-
-/**
- * Make AAC audio config object.
- * @see 1.6.2.1 "Syntax - AudioSpecificConfig"
- */
-static void put_audio_specific_config(AVCodecContext *avctx)
-{
-    PutBitContext pb;
-    AACEncContext *s = avctx->priv_data;
-
-    init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8);
-    put_bits(&pb, 5, 2); //object type - AAC-LC
-    put_bits(&pb, 4, s->samplerate_index); //sample rate index
-    put_bits(&pb, 4, avctx->channels);
-    //GASpecificConfig
-    put_bits(&pb, 1, 0); //frame length - 1024 samples
-    put_bits(&pb, 1, 0); //does not depend on core coder
-    put_bits(&pb, 1, 0); //is not extension
-    flush_put_bits(&pb);
-}
-
-static av_cold int aac_encode_init(AVCodecContext *avctx)
-{
-    AACEncContext *s = avctx->priv_data;
-    int i;
-    const uint8_t *sizes[2];
-    int lengths[2];
-
-    avctx->frame_size = 1024;
-
-    for(i = 0; i < 16; i++)
-        if(avctx->sample_rate == ff_mpeg4audio_sample_rates[i])
-            break;
-    if(i == 16){
-        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);
-        return -1;
-    }
-    if(avctx->channels > 6){
-        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels);
-        return -1;
-    }
-    s->samplerate_index = i;
-
-    dsputil_init(&s->dsp, avctx);
-    ff_mdct_init(&s->mdct1024, 11, 0);
-    ff_mdct_init(&s->mdct128,   8, 0);
-    // window init
-    ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
-    ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
-    ff_sine_window_init(ff_sine_1024, 1024);
-    ff_sine_window_init(ff_sine_128, 128);
-
-    s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));
-    s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]);
-    avctx->extradata = av_malloc(2);
-    avctx->extradata_size = 2;
-    put_audio_specific_config(avctx);
-
-    sizes[0] = swb_size_1024[i];
-    sizes[1] = swb_size_128[i];
-    lengths[0] = ff_aac_num_swb_1024[i];
-    lengths[1] = ff_aac_num_swb_128[i];
-    ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
-    s->psypp = ff_psy_preprocess_init(avctx);
-
-#if !CONFIG_HARDCODED_TABLES
-    for (i = 0; i < 316; i++)
-        ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.);
-#endif /* CONFIG_HARDCODED_TABLES */
-
-    return 0;
-}
-
-static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s,
-                                  SingleChannelElement *sce, short *audio, int channel)
-{
-    int i, j, k;
-    const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
-    const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
-    const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
-
-    if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
-        memcpy(s->output, sce->saved, sizeof(float)*1024);
-        if(sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE){
-            memset(s->output, 0, sizeof(s->output[0]) * 448);
-            for(i = 448; i < 576; i++)
-                s->output[i] = sce->saved[i] * pwindow[i - 448];
-            for(i = 576; i < 704; i++)
-                s->output[i] = sce->saved[i];
-        }
-        if(sce->ics.window_sequence[0] != LONG_START_SEQUENCE){
-            j = channel;
-            for (i = 0; i < 1024; i++, j += avctx->channels){
-                s->output[i+1024]         = audio[j] * lwindow[1024 - i - 1];
-                sce->saved[i] = audio[j] * lwindow[i];
-            }
-        }else{
-            j = channel;
-            for(i = 0; i < 448; i++, j += avctx->channels)
-                s->output[i+1024]         = audio[j];
-            for(i = 448; i < 576; i++, j += avctx->channels)
-                s->output[i+1024]         = audio[j] * swindow[576 - i - 1];
-            memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448);
-            j = channel;
-            for(i = 0; i < 1024; i++, j += avctx->channels)
-                sce->saved[i] = audio[j];
-        }
-        ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output);
-    }else{
-        j = channel;
-        for (k = 0; k < 1024; k += 128) {
-            for(i = 448 + k; i < 448 + k + 256; i++)
-                s->output[i - 448 - k] = (i < 1024)
-                                         ? sce->saved[i]
-                                         : audio[channel + (i-1024)*avctx->channels];
-            s->dsp.vector_fmul        (s->output,     k ?  swindow : pwindow, 128);
-            s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128);
-            ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output);
-        }
-        j = channel;
-        for(i = 0; i < 1024; i++, j += avctx->channels)
-            sce->saved[i] = audio[j];
-    }
-}
-
-/**
- * Encode ics_info element.
- * @see Table 4.6 (syntax of ics_info)
- */
-static void put_ics_info(AACEncContext *s, IndividualChannelStream *info)
-{
-    int w;
-
-    put_bits(&s->pb, 1, 0);                // ics_reserved bit
-    put_bits(&s->pb, 2, info->window_sequence[0]);
-    put_bits(&s->pb, 1, info->use_kb_window[0]);
-    if(info->window_sequence[0] != EIGHT_SHORT_SEQUENCE){
-        put_bits(&s->pb, 6, info->max_sfb);
-        put_bits(&s->pb, 1, 0);            // no prediction
-    }else{
-        put_bits(&s->pb, 4, info->max_sfb);
-        for(w = 1; w < 8; w++){
-            put_bits(&s->pb, 1, !info->group_len[w]);
-        }
-    }
-}
-
-/**
- * Encode MS data.
- * @see 4.6.8.1 "Joint Coding - M/S Stereo"
- */
-static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
-{
-    int i, w;
-
-    put_bits(pb, 2, cpe->ms_mode);
-    if(cpe->ms_mode == 1){
-        for(w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w]){
-            for(i = 0; i < cpe->ch[0].ics.max_sfb; i++)
-                put_bits(pb, 1, cpe->ms_mask[w*16 + i]);
-        }
-    }
-}
 
 /**
  * Quantize one coefficient.
@@ -381,13 +98,13 @@ static float quantize_band_cost(const fl
         float mincost;
         int minidx = 0;
         int minbits = 0;
-        int quants[4][2], realquants[4][2];
+        int quants[4][2];
         mincost = 0.0f;
         for(j = 0; j < dim; j++){
-            realquants[j][0] = quant2(in[i+j], Q);
-            realquants[j][1] = quant (in[i+j], Q);
+            quants[j][0] = quant2(in[i+j], Q);
+            quants[j][1] = quant (in[i+j], Q);
             for(k = 0; k < 2; k++){
-                quants[j][k] = FFMIN(realquants[j][k], maxval);
+                quants[j][k] = FFMIN(quants[j][k], maxval);
                 if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
                     quants[j][k] = -quants[j][k];
             }
@@ -428,7 +145,7 @@ static float quantize_band_cost(const fl
                             di = t - 165140.0f;
                             curbits += 21;
                         }else{
-                            int c = realquants[k];
+                            int c = quant(t, Q);
                             di = t - c*cbrt(c)*IQ;
                             curbits += av_log2(c)*2 - 4 + 1;
                         }
@@ -664,7 +381,7 @@ static void quantize_and_encode_band(Put
     const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
     int i, j, k;
     const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-
+//START_TIMER
     if(!cb)
         return;
 
@@ -731,6 +448,7 @@ static void quantize_and_encode_band(Put
             }
         }
     }
+//STOP_TIMER("quantize_and_encode")
 }
 
 #endif
@@ -844,65 +562,6 @@ static void encode_window_bands_info(AAC
     }
 }
 
-/**
- * Produce integer coefficients from scalefactors provided by the model.
- */
-static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
-{
-    int i, w, w2, g, ch;
-    int start, sum, maxsfb, cmaxsfb;
-
-    for(ch = 0; ch < chans; ch++){
-        IndividualChannelStream *ics = &cpe->ch[ch].ics;
-        start = 0;
-        maxsfb = 0;
-        cpe->ch[ch].pulse.num_pulse = 0;
-        for(w = 0; w < ics->num_windows*16; w += 16){
-            for(g = 0; g < ics->num_swb; g++){
-                sum = 0;
-                //apply M/S
-                if(!ch && cpe->ms_mask[w + g]){
-                    for(i = 0; i < ics->swb_sizes[g]; i++){
-                        cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
-                        cpe->ch[1].coeffs[start+i] =  cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i];
-                    }
-                }
-                start += ics->swb_sizes[g];
-            }
-            for(cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w+cmaxsfb-1]; cmaxsfb--);
-            maxsfb = FFMAX(maxsfb, cmaxsfb);
-        }
-        ics->max_sfb = maxsfb;
-
-        //adjust zero bands for window groups
-        for(w = 0; w < ics->num_windows; w += ics->group_len[w]){
-            for(g = 0; g < ics->max_sfb; g++){
-                i = 1;
-                for(w2 = w; w2 < w + ics->group_len[w]; w2++){
-                    if(!cpe->ch[ch].zeroes[w2*16 + g]){
-                        i = 0;
-                        break;
-                    }
-                }
-                cpe->ch[ch].zeroes[w*16 + g] = i;
-            }
-        }
-    }
-
-    if(chans > 1 && cpe->common_window){
-        IndividualChannelStream *ics0 = &cpe->ch[0].ics;
-        IndividualChannelStream *ics1 = &cpe->ch[1].ics;
-        int msc = 0;
-        ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb);
-        ics1->max_sfb = ics0->max_sfb;
-        for(w = 0; w < ics0->num_windows*16; w += 16)
-            for(i = 0; i < ics0->max_sfb; i++)
-                if(cpe->ms_mask[w+i]) msc++;
-        if(msc == 0 || ics0->max_sfb == 0) cpe->ms_mode = 0;
-        else cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
-    }
-}
-
 typedef struct TrellisPath {
     float cost;
     int prev;
@@ -910,7 +569,8 @@ typedef struct TrellisPath {
     int max_val;
 } TrellisPath;
 
-static void search_for_quantizers_anmr(AACEncContext *s, SingleChannelElement *sce, const float lambda)
+static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
+                                       SingleChannelElement *sce, const float lambda)
 {
     int q, w, w2, g, start = 0;
     int i;
@@ -1186,7 +846,8 @@ static void search_for_quantizers_twoloo
     }while(fflag && its < 10);
 }
 
-static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
+static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
+                                       SingleChannelElement *sce, const float lambda)
 {
     int start = 0, i, w, w2, g;
     float uplim[128], maxq[128];
@@ -1351,7 +1012,8 @@ static void search_for_quantizers_faac(A
     }
 }
 
-static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
+static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
+                                       SingleChannelElement *sce, const float lambda)
 {
     int start = 0, i, w, w2, g;
     int minq = 255;
@@ -1374,7 +1036,7 @@ static void search_for_quantizers_fast(A
         }
     }
     for(i = 0; i < 128; i++){
-        sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
+        sce->sf_idx[i] = 140;//av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
     }
     //set the same quantizers inside window groups
     for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
@@ -1383,15 +1045,6 @@ static void search_for_quantizers_fast(A
                 sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
 }
 
-static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
-                                  SingleChannelElement *sce)
-{
-    search_for_quantizers_anmr(s, sce, s->lambda);
-//    search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
-//    search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
-//    search_for_quantizers_fast(s, sce);
-}
-
 static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
 {
     int start = 0, i, w, w2, g;
@@ -1443,246 +1096,29 @@ static void search_for_ms(AACEncContext 
     }
 }
 
-/**
- * Encode scalefactor band coding type.
- */
-static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
-{
-    int w;
-
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
-    }
-}
-
-/**
- * Encode scalefactors.
- */
-static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce)
-{
-    int off = sce->sf_idx[0], diff;
-    int i, w;
-
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        for(i = 0; i < sce->ics.max_sfb; i++){
-            if(!sce->zeroes[w*16 + i]){
-                diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO;
-                if(diff < 0 || diff > 120) av_log(avctx, AV_LOG_ERROR, "Scalefactor difference is too big to be coded\n");
-                off = sce->sf_idx[w*16 + i];
-                put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]);
-            }
-        }
-    }
-}
-
-/**
- * Encode pulse data.
- */
-static void encode_pulses(AACEncContext *s, Pulse *pulse)
-{
-    int i;
-
-    put_bits(&s->pb, 1, !!pulse->num_pulse);
-    if(!pulse->num_pulse) return;
-
-    put_bits(&s->pb, 2, pulse->num_pulse - 1);
-    put_bits(&s->pb, 6, pulse->start);
-    for(i = 0; i < pulse->num_pulse; i++){
-        put_bits(&s->pb, 5, pulse->pos[i]);
-        put_bits(&s->pb, 4, pulse->amp[i]);
-    }
-}
-
-/**
- * Encode spectral coefficients processed by psychoacoustic model.
- */
-static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
-{
-    int start, i, w, w2;
-
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        start = 0;
-        for(i = 0; i < sce->ics.max_sfb; i++){
-            if(sce->zeroes[w*16 + i]){
-                start += sce->ics.swb_sizes[i];
-                continue;
-            }
-            for(w2 = w; w2 < w + sce->ics.group_len[w]; w2++){
-                quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
-                                         sce->ics.swb_sizes[i],
-                                         sce->sf_idx[w*16 + i],
-                                         sce->band_type[w*16 + i],
-                                         s->lambda);
-            }
-            start += sce->ics.swb_sizes[i];
-        }
-    }
-}
-
-/**
- * Encode one channel of audio data.
- */
-static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce, int common_window)
-{
-    put_bits(&s->pb, 8, sce->sf_idx[0]);
-    if(!common_window) put_ics_info(s, &sce->ics);
-    encode_band_info(s, sce);
-    encode_scale_factors(avctx, s, sce);
-    encode_pulses(s, &sce->pulse);
-    put_bits(&s->pb, 1, 0); //tns
-    put_bits(&s->pb, 1, 0); //ssr
-    encode_spectral_coeffs(s, sce);
-    return 0;
-}
-
-/**
- * Write some auxiliary information about the created AAC file.
- */
-static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, const char *name)
-{
-    int i, namelen, padbits;
-
-    namelen = strlen(name) + 2;
-    put_bits(&s->pb, 3, TYPE_FIL);
-    put_bits(&s->pb, 4, FFMIN(namelen, 15));
-    if(namelen >= 15)
-        put_bits(&s->pb, 8, namelen - 16);
-    put_bits(&s->pb, 4, 0); //extension type - filler
-    padbits = 8 - (put_bits_count(&s->pb) & 7);
-    align_put_bits(&s->pb);
-    for(i = 0; i < namelen - 2; i++)
-        put_bits(&s->pb, 8, name[i]);
-    put_bits(&s->pb, 12 - padbits, 0);
-}
-
-static int aac_encode_frame(AVCodecContext *avctx,
-                            uint8_t *frame, int buf_size, void *data)
-{
-    AACEncContext *s = avctx->priv_data;
-    int16_t *samples = s->samples, *samples2, *la;
-    ChannelElement *cpe;
-    int i, j, chans, tag, start_ch;
-    const uint8_t *chan_map = aac_chan_configs[avctx->channels-1];
-    int chan_el_counter[4];
-
-    if(s->last_frame)
-        return 0;
-    if(data){
-        if(!s->psypp){
-            memcpy(s->samples + 1024 * avctx->channels, data, 1024 * avctx->channels * sizeof(s->samples[0]));
-        }else{
-            start_ch = 0;
-            samples2 = s->samples + 1024 * avctx->channels;
-            for(i = 0; i < chan_map[0]; i++){
-                tag = chan_map[i+1];
-                chans = tag == TYPE_CPE ? 2 : 1;
-                ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch, samples2 + start_ch, start_ch + i, chans);
-                start_ch += chans;
-            }
-        }
-    }
-    if(!avctx->frame_number){
-        memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
-        return 0;
-    }
-
-    init_put_bits(&s->pb, frame, buf_size*8);
-    if((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)){
-        put_bitstream_info(avctx, s, LIBAVCODEC_IDENT);
-    }
-    start_ch = 0;
-    memset(chan_el_counter, 0, sizeof(chan_el_counter));
-    for(i = 0; i < chan_map[0]; i++){
-        FFPsyWindowInfo wi[2];
-        tag = chan_map[i+1];
-        chans = tag == TYPE_CPE ? 2 : 1;
-        cpe = &s->cpe[i];
-        samples2 = samples + start_ch;
-        la = samples2 + 1024 * avctx->channels + start_ch;
-        if(!data) la = NULL;
-        s->lambda = 5e-7f;
-        for(j = 0; j < chans; j++){
-            IndividualChannelStream *ics = &cpe->ch[j].ics;
-            int k;
-            wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]);
-            ics->window_sequence[1] = ics->window_sequence[0];
-            ics->window_sequence[0] = wi[j].window_type[0];
-            ics->use_kb_window[1]   = ics->use_kb_window[0];
-            ics->use_kb_window[0]   = wi[j].window_shape;
-            ics->num_windows        = wi[j].num_windows;
-            ics->swb_sizes          = s->psy.bands    [ics->num_windows == 8];
-            ics->num_swb            = s->psy.num_bands[ics->num_windows == 8];
-            for(k = 0; k < ics->num_windows; k++)
-                ics->group_len[k] = wi[j].grouping[k];
-
-            s->cur_channel = start_ch + j;
-            apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
-            search_for_quantizers(avctx, s, &cpe->ch[j]);
-        }
-        cpe->common_window = 0;
-        if(chans > 1
-            && wi[0].window_type[0] == wi[1].window_type[0]
-            && wi[0].window_shape   == wi[1].window_shape){
-
-            cpe->common_window = 1;
-            for(j = 0; j < wi[0].num_windows; j++){
-                if(wi[0].grouping[j] != wi[1].grouping[j]){
-                    cpe->common_window = 0;
-                    break;
-                }
-            }
-        }
-//        search_for_ms(s, cpe, s->lambda);
-        adjust_frame_information(s, cpe, chans);
-        put_bits(&s->pb, 3, tag);
-        put_bits(&s->pb, 4, chan_el_counter[tag]++);
-        if(chans == 2){
-            put_bits(&s->pb, 1, cpe->common_window);
-            if(cpe->common_window){
-                put_ics_info(s, &cpe->ch[0].ics);
-                encode_ms_info(&s->pb, cpe);
-            }
-        }
-        for(j = 0; j < chans; j++){
-            s->cur_channel = start_ch + j;
-            ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]);
-            encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window);
-        }
-        start_ch += chans;
-    }
-
-    put_bits(&s->pb, 3, TYPE_END);
-    flush_put_bits(&s->pb);
-    avctx->frame_bits = put_bits_count(&s->pb);
-
-    if(!data)
-        s->last_frame = 1;
-    memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
-    return put_bits_count(&s->pb)>>3;
-}
-
-static av_cold int aac_encode_end(AVCodecContext *avctx)
-{
-    AACEncContext *s = avctx->priv_data;
-
-    ff_mdct_end(&s->mdct1024);
-    ff_mdct_end(&s->mdct128);
-    ff_psy_end(&s->psy);
-    ff_psy_preprocess_end(s->psypp);
-    av_freep(&s->samples);
-    av_freep(&s->cpe);
-    return 0;
-}
-
-AVCodec aac_encoder = {
-    "aac",
-    CODEC_TYPE_AUDIO,
-    CODEC_ID_AAC,
-    sizeof(AACEncContext),
-    aac_encode_init,
-    aac_encode_frame,
-    aac_encode_end,
-    .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
-    .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
-    .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
+AACCoefficientsEncoder ff_aac_coders[] = {
+    {
+        search_for_quantizers_anmr,
+        encode_window_bands_info,
+        quantize_and_encode_band,
+//        search_for_ms,
+    },
+    {
+        search_for_quantizers_faac,
+        encode_window_bands_info,
+        quantize_and_encode_band,
+//        search_for_ms,
+    },
+    {
+        search_for_quantizers_twoloop,
+        encode_window_bands_info,
+        quantize_and_encode_band,
+//        search_for_ms,
+    },
+    {
+        search_for_quantizers_fast,
+        encode_window_bands_info,
+        quantize_and_encode_band,
+//        search_for_ms,
+    },
 };

Modified: aacenc/aacenc.c
==============================================================================
--- aacenc/aacenc.c	Mon Jan 26 15:00:57 2009	(r4007)
+++ aacenc/aacenc.c	Mon Jan 26 15:07:28 2009	(r4008)
@@ -38,6 +38,7 @@
 
 #include "aac.h"
 #include "aactab.h"
+#include "aacenc.h"
 
 #include "psymodel.h"
 
@@ -120,23 +121,6 @@ static const uint8_t *swb_size_128[] = {
     swb_size_128_16, swb_size_128_16, swb_size_128_8
 };
 
-/** bits needed to code codebook run value for long windows */
-static const uint8_t run_value_bits_long[64] = {
-     5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-     5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 10,
-    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
-};
-
-/** bits needed to code codebook run value for short windows */
-static const uint8_t run_value_bits_short[16] = {
-    3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
-};
-
-static const uint8_t* run_value_bits[2] = {
-    run_value_bits_long, run_value_bits_short
-};
-
 /** default channel configurations */
 static const uint8_t aac_chan_configs[6][5] = {
  {1, TYPE_SCE},                               // 1 channel  - single channel element
@@ -148,27 +132,6 @@ static const uint8_t aac_chan_configs[6]
 };
 
 /**
- * AAC encoder context
- */
-typedef struct {
-    PutBitContext pb;
-    MDCTContext mdct1024;                        ///< long (1024 samples) frame transform context
-    MDCTContext mdct128;                         ///< short (128 samples) frame transform context
-    DSPContext  dsp;
-    DECLARE_ALIGNED_16(FFTSample, output[2048]); ///< temporary buffer for MDCT input coefficients
-    int16_t* samples;                            ///< saved preprocessed input
-
-    int samplerate_index;                        ///< MPEG-4 samplerate index
-
-    ChannelElement *cpe;                         ///< channel elements
-    FFPsyContext psy;
-    struct FFPsyPreprocessContext* psypp;
-    int cur_channel;
-    int last_frame;
-    float lambda;
-} AACEncContext;
-
-/**
  * Make AAC audio config object.
  * @see 1.6.2.1 "Syntax - AudioSpecificConfig"
  */
@@ -231,6 +194,7 @@ static av_cold int aac_encode_init(AVCod
     lengths[1] = ff_aac_num_swb_128[i];
     ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
     s->psypp = ff_psy_preprocess_init(avctx);
+    s->coder = &ff_aac_coders[0];
 
 #if !CONFIG_HARDCODED_TABLES
     for (i = 0; i < 316; i++)
@@ -332,519 +296,6 @@ static void encode_ms_info(PutBitContext
 }
 
 /**
- * Quantize one coefficient.
- * @return absolute value of the quantized coefficient
- * @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
- */
-static av_always_inline int quant(float coef, const float Q)
-{
-    return av_clip((int)(pow(fabsf(coef) * Q, 0.75) + 0.4054), 0, 8191);
-}
-
-#if 1
-
-static av_always_inline int quant2(float coef, const float Q)
-{
-    return av_clip((int)(pow(fabsf(coef) * Q, 0.75)), 0, 8191);
-}
-
-static const float aac_cb_range[12] = { 0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
-static const float aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
-                                 const float lambda, const float uplim, int *bits)
-{
-    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];
-    int i, j, k;
-    float cost = 0;
-    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-    int resbits = 0;
-    const int range = aac_cb_range[cb];
-    const int maxval = aac_cb_maxval[cb];
-    int offs[4];
-
-    if(!cb){
-        for(i = 0; i < size; i++)
-            cost += in[i]*in[i]*lambda;
-        return cost;
-    }
-    offs[0] = 1;
-    for(i = 1; i < dim; i++)
-        offs[i] = offs[i-1]*range;
-    for(i = 0; i < size; i += dim){
-        float mincost;
-        int minidx = 0;
-        int minbits = 0;
-        int quants[4][2], realquants[4][2];
-        mincost = 0.0f;
-        for(j = 0; j < dim; j++){
-            realquants[j][0] = quant2(in[i+j], Q);
-            realquants[j][1] = quant (in[i+j], Q);
-            for(k = 0; k < 2; k++){
-                quants[j][k] = FFMIN(realquants[j][k], maxval);
-                if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
-                    quants[j][k] = -quants[j][k];
-            }
-            mincost += in[i+j]*in[i+j]*lambda;
-        }
-        minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-        minbits = ff_aac_spectral_bits[cb-1][minidx];
-        mincost += minbits;
-        for(j = 0; j < (1<<dim); j++){
-            float rd = 0.0f;
-            int curbits;
-            int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-            const float *vec;
-            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];
-            vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*IQ){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*IQ){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = realquants[k];
-                            di = t - c*cbrt(c)*IQ;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*IQ;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*IQ;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = j;
-                minbits = curbits;
-            }
-        }
-        cost += mincost;
-        resbits += minbits;
-        if(cost >= uplim)
-            return uplim;
-    }
-
-    if(bits)
-        *bits = resbits;
-    return cost;
-}
-
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
-                                     int scale_idx, int cb, const float lambda)
-{
-    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 int range = aac_cb_range[cb];
-    const int maxval = aac_cb_maxval[cb];
-    const int dim = (cb < FIRST_PAIR_BT) ? 4 : 2;
-    int i, j, k;
-    int offs[4];
-
-    if(!cb)
-        return;
-
-    offs[0] = 1;
-    for(i = 1; i < dim; i++)
-        offs[i] = offs[i-1]*range;
-    for(i = 0; i < size; i += dim){
-        float mincost;
-        int minidx = 0;
-        int minbits = 0;
-        int quants[4][2];
-        mincost = 0.0f;
-        for(j = 0; j < dim; j++){
-            quants[j][0] = av_clip(quant2(in[i+j], Q), -maxval, maxval);
-            quants[j][1] = av_clip(quant (in[i+j], Q), -maxval, maxval);
-            for(k = 0; k < 2; k++){
-                quants[j][k] = FFMIN(quants[j][k], maxval);
-                if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
-                    quants[j][k] = -quants[j][k];
-            }
-            mincost += in[i+j]*in[i+j]*lambda;
-        }
-        minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-        minbits = ff_aac_spectral_bits[cb-1][minidx];
-        mincost += minbits;
-        for(j = 0; j < (1<<dim); j++){
-            float rd = 0.0f;
-            int curbits;
-            int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-            const float *vec;
-            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];
-            vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*IQ){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*IQ){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = quant(t, Q);
-                            di = t - c*cbrt(c)*IQ;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*IQ;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*IQ;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = curidx;
-                minbits = curbits;
-            }
-        }
-        put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
-        if(IS_CODEBOOK_UNSIGNED(cb))
-            for(j = 0; j < dim; j++)
-                if(ff_aac_codebook_vectors[cb-1][minidx*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){
-                    int coef = quant(in[i+j], Q);
-                    int len = av_log2(coef);
-
-                    put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
-                    put_bits(pb, len, coef & ((1 << len) - 1));
-                }
-            }
-        }
-    }
-}
-
-#else
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
-                                 const float lambda, const float uplim, int *bits)
-{
-    const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
-    int i, j, k;
-    float cost = 0;
-    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-    int resbits = 0;
-
-    if(!cb){
-        for(i = 0; i < size; i++)
-            cost += in[i]*in[i]*lambda;
-        return cost;
-    }
-    for(i = 0; i < size; i += dim){
-        float mincost = INFINITY;
-        int minidx = 0;
-        int minbits = 0;
-        const float *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];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*Q){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*Q){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = quant(t, 1.0/Q);
-                            di = t - c*cbrt(c)*Q;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*Q;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*Q;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = j;
-                minbits = curbits;
-            }
-        }
-        cost += mincost;
-        resbits += minbits;
-        if(cost >= uplim)
-            return uplim;
-    }
-
-    if(bits)
-        *bits = resbits;
-    return cost;
-}
-
-/**
- * Prepare coefficients for encoding.
- *
- * @return sum of coefficient absolute values
- */
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
-                                      int scale_idx, int cb, const float lambda)
-{
-    const float Q  = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
-    const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
-    int i, j, k;
-    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-
-    if(!cb)
-        return;
-
-    for(i = 0; i < size; i += dim){
-        float mincost = INFINITY;
-        int minidx = 0;
-        int minbits = 0;
-        const float *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];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*Q){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*Q){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = quant(t, IQ);
-                            di = t - c*cbrt(c)*Q;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*Q;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*Q;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = j;
-                minbits = curbits;
-            }
-        }
-        put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
-        if(IS_CODEBOOK_UNSIGNED(cb))
-            for(j = 0; j < dim; j++)
-                if(ff_aac_codebook_vectors[cb-1][minidx*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){
-                    int coef = quant(in[i+j], IQ);
-                    int len = av_log2(coef);
-
-                    put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
-                    put_bits(pb, len, coef & ((1 << len) - 1));
-                }
-            }
-        }
-    }
-}
-
-#endif
-
-/**
- * structure used in optimal codebook search
- */
-typedef struct BandCodingPath {
-    int prev_idx; ///< pointer to the previous path point
-    int codebook; ///< codebook for coding band run
-    float cost;   ///< path cost
-    int run;
-} BandCodingPath;
-
-/**
- * Encode band info for single window group bands.
- */
-static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
-                                     int win, int group_len)
-{
-    BandCodingPath path[120][12];
-    int w, swb, cb, start, start2, 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;
-
-    start = win*128;
-    for(cb = 0; cb < 12; cb++){
-        path[0][cb].cost = 0.0f;
-        path[0][cb].prev_idx = -1;
-        path[0][cb].run = 0;
-    }
-    for(swb = 0; swb < max_sfb; swb++){
-        start2 = start;
-        size = sce->ics.swb_sizes[swb];
-        if(sce->zeroes[win*16 + swb]){
-            for(cb = 0; cb < 12; cb++){
-                path[swb+1][cb].prev_idx = cb;
-                path[swb+1][cb].cost = path[swb][cb].cost;
-                path[swb+1][cb].run = path[swb][cb].run + 1;
-            }
-        }else{
-            float minrd = INFINITY;
-            int mincb = 0;
-            for(cb = 0; cb < 12; cb++){
-                float rd = 0.0f;
-                for(w = 0; w < group_len; w++){
-                    FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
-                    rd += quantize_band_cost(sce->coeffs + start + w*128, size,
-                                             sce->sf_idx[(win+w)*16+swb], cb,
-                                             s->lambda / band->threshold, INFINITY, NULL);
-                }
-                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])
-                    rd += run_bits;
-                path[swb+1][cb].prev_idx = cb;
-                path[swb+1][cb].cost = path[swb][cb].cost + rd;
-                path[swb+1][cb].run = path[swb][cb].run + 1;
-                if(rd < minrd){
-                    minrd = rd;
-                    mincb = cb;
-                }
-            }
-            for(cb = 0; cb < 12; cb++){
-                float cost = path[swb][cb].cost + minrd + run_bits + 4;
-                if(cost < path[swb+1][cb].cost){
-                    path[swb+1][cb].prev_idx = mincb;
-                    path[swb+1][cb].cost = cost;
-                    path[swb+1][cb].run = 1;
-                }
-            }
-        }
-        start += sce->ics.swb_sizes[swb];
-    }
-
-    //convert resulting path from backward-linked list
-    stack_len = 0;
-    idx = 0;
-    for(cb = 1; cb < 12; cb++){
-        if(path[max_sfb][cb].cost < path[max_sfb][idx].cost)
-            idx = cb;
-    }
-    ppos = max_sfb;
-    while(ppos > 0){
-        cb = idx;
-        stackrun[stack_len] = path[ppos][cb].run;
-        stackcb [stack_len] = cb;
-        idx = path[ppos][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--){
-        put_bits(&s->pb, 4, stackcb[i]);
-        count = stackrun[i];
-        memset(sce->zeroes + win*16 + start, !stackcb[i], count);
-        //XXX: memset when band_type is also uint8_t
-        for(j = 0; j < count; j++){
-            sce->band_type[win*16 + start] =  stackcb[i];
-            start++;
-        }
-        while(count >= run_esc){
-            put_bits(&s->pb, run_bits, run_esc);
-            count -= run_esc;
-        }
-        put_bits(&s->pb, run_bits, count);
-    }
-}
-
-/**
  * Produce integer coefficients from scalefactors provided by the model.
  */
 static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
@@ -903,546 +354,6 @@ static void adjust_frame_information(AAC
     }
 }
 
-typedef struct TrellisPath {
-    float cost;
-    int prev;
-    int min_val;
-    int max_val;
-} TrellisPath;
-
-static void search_for_quantizers_anmr(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
-    int q, w, w2, g, start = 0;
-    int i;
-    int idx;
-    TrellisPath paths[256*121];
-    int bandaddr[121];
-    int minq;
-    float mincost;
-
-    for(i = 0; i < 256; i++){
-        paths[i].cost = 0.0f;
-        paths[i].prev = -1;
-        paths[i].min_val = i;
-        paths[i].max_val = i;
-    }
-    for(i = 256; i < 256*121; i++){
-        paths[i].cost = INFINITY;
-        paths[i].prev = -2;
-        paths[i].min_val = INT_MAX;
-        paths[i].max_val = 0;
-    }
-    idx = 256;
-    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;
-            float qmin, qmax;
-            int nz = 0;
-
-            bandaddr[idx >> 8] = w*16+g;
-            qmin = INT_MAX;
-            qmax = 0.0f;
-            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];
-                if(band->energy <= band->threshold || band->threshold == 0.0f){
-                    sce->zeroes[(w+w2)*16+g] = 1;
-                    continue;
-                }
-                sce->zeroes[(w+w2)*16+g] = 0;
-                nz = 1;
-                for(i = 0; i < sce->ics.swb_sizes[g]; i++){
-                    float t = fabsf(coefs[w2*128+i]);
-                    if(t > 0.0f) qmin = fminf(qmin, t);
-                    qmax = fmaxf(qmax, t);
-                }
-            }
-            if(nz){
-                int minscale, maxscale;
-                float minrd = INFINITY;
-                //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);
-                //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);
-                for(q = minscale; q < maxscale; q++){
-                    float dists[12], dist;
-                    memset(dists, 0, sizeof(dists));
-                    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];
-                        int cb;
-                        for(cb = 0; cb <= ESC_BT; cb++){
-                            dists[cb] += quantize_band_cost(coefs + w2*128, sce->ics.swb_sizes[g],
-                                                            q, cb, s->lambda / band->threshold, INFINITY, NULL);
-                        }
-                    }
-                    dist = dists[0];
-                    for(i = 1; i <= ESC_BT; i++)
-                        dist = fminf(dist, dists[i]);
-                    minrd = fminf(minrd, dist);
-
-                    for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
-                        float cost;
-                        int minv, maxv;
-                        if(isinf(paths[idx - 256 + i].cost))
-                            continue;
-                        cost = paths[idx - 256 + i].cost + dist
-                               + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
-                        minv = FFMIN(paths[idx - 256 + i].min_val, q);
-                        maxv = FFMAX(paths[idx - 256 + i].max_val, q);
-                        if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
-                            paths[idx + q].cost = cost;
-                            paths[idx + q].prev = idx - 256 + i;
-                            paths[idx + q].min_val = minv;
-                            paths[idx + q].max_val = maxv;
-                        }
-                    }
-                }
-            }else{
-                for(q = 0; q < 256; q++){
-                    if(!isinf(paths[idx - 256 + q].cost)){
-                        paths[idx + q].cost = paths[idx - 256 + q].cost + 1;
-                        paths[idx + q].prev = idx - 256 + q;
-                        paths[idx + q].min_val = FFMIN(paths[idx - 256 + q].min_val, q);
-                        paths[idx + q].max_val = FFMAX(paths[idx - 256 + q].max_val, q);
-                        continue;
-                    }
-                    for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
-                        float cost;
-                        int minv, maxv;
-                        if(isinf(paths[idx - 256 + i].cost))
-                            continue;
-                        cost = paths[idx - 256 + i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
-                        minv = FFMIN(paths[idx - 256 + i].min_val, q);
-                        maxv = FFMAX(paths[idx - 256 + i].max_val, q);
-                        if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
-                            paths[idx + q].cost = cost;
-                            paths[idx + q].prev = idx - 256 + i;
-                            paths[idx + q].min_val = minv;
-                            paths[idx + q].max_val = maxv;
-                        }
-                    }
-                }
-            }
-            sce->zeroes[w*16+g] = !nz;
-            start += sce->ics.swb_sizes[g];
-            idx += 256;
-        }
-    }
-    idx -= 256;
-    mincost = paths[idx].cost;
-    minq = idx;
-    for(i = 1; i < 256; i++){
-        if(paths[idx + i].cost < mincost){
-            mincost = paths[idx + i].cost;
-            minq = idx + i;
-        }
-    }
-    while(minq >= 256){
-        sce->sf_idx[bandaddr[minq>>8]] = minq & 0xFF;
-        minq = paths[minq].prev;
-    }
-    //set the same quantizers inside window groups
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
-        for(g = 0;  g < sce->ics.num_swb; g++)
-            for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
-                sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-/**
- * two-loop quantizers search taken from ISO 13818-7 Appendix C
- */
-static void search_for_quantizers_twoloop(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;
-    float dists[128], uplims[128];
-    int fflag, minscaler;
-    int its = 0;
-    int allz = 0;
-    float minthr = INFINITY;
-
-    //XXX: some heuristic to determine initial quantizers will reduce search time
-    memset(dists, 0, sizeof(dists));
-    //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;
-            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];
-                uplim += band->threshold;
-                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 = fminf(minthr, uplim);
-            allz = FFMAX(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 + fminf(log2(uplims[w*16+g]/minthr)*4,59);
-        }
-    }
-
-    if(!allz)
-        return;
-    //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;
-            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;
-                    int bits = 0;
-                    int cb;
-                    float mindist = INFINITY;
-                    int minbits = 0;
-
-                    if(sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218)
-                        continue;
-                    minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
-                    for(cb = 0; cb <= ESC_BT; cb++){
-                        float dist = 0.0f;
-                        int bb = 0;
-                        for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
-                            int b;
-                            dist += quantize_band_cost(coefs + w2*128,
-                                                       sce->ics.swb_sizes[g],
-                                                       sce->sf_idx[w*16+g],
-                                                       ESC_BT,
-                                                       1.0,
-                                                       INFINITY,
-                                                       &b);
-                            bb += b;
-                        }
-                        if(dist < mindist){
-                            mindist = dist;
-                            minbits = bb;
-                        }
-                    }
-                    dists[w*16+g] = mindist - minbits;
-                    bits = minbits;
-                    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)
-                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)
-                    sce->sf_idx[w*16+g]--;
-                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;
-            }
-        }
-        its++;
-    }while(fflag && its < 10);
-}
-
-static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
-    int start = 0, i, w, w2, g;
-    float uplim[128], maxq[128];
-    int minq;
-#if 0
-    float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
-    int last = 0, lastband = 0, curband = 0;
-    float avg_energy = 0.0;
-    if(sce->ics.num_windows == 1){
-        start = 0;
-        for(i = 0; i < 1024; i++){
-            if(i - start >= sce->ics.swb_sizes[curband]){
-                start += sce->ics.swb_sizes[curband];
-                curband++;
-            }
-            if(sce->coeffs[i]){
-                avg_energy += sce->coeffs[i] * sce->coeffs[i];
-                last = i;
-                lastband = curband;
-            }
-        }
-    }else{
-        for(w = 0; w < 8; w++){
-            const float *coeffs = sce->coeffs + w*128;
-            start = 0;
-            for(i = 0; i < 128; i++){
-                if(i - start >= sce->ics.swb_sizes[curband]){
-                    start += sce->ics.swb_sizes[curband];
-                    curband++;
-                }
-                if(coeffs[i]){
-                    avg_energy += coeffs[i] * coeffs[i];
-                    last = FFMAX(last, i);
-                    lastband = FFMAX(lastband, curband);
-                }
-            }
-        }
-    }
-    last++;
-    avg_energy /= last;
-    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++){
-            float *coefs = sce->coeffs + start;
-            const int size = sce->ics.swb_sizes[g];
-            int start2 = start, end2 = start + size, peakpos = start;
-            float maxval = -1, thr = 0.0f, t;
-            maxq[w*16+g] = 0.0f;
-            if(g > lastband){
-                maxq[w*16+g] = 0.0f;
-                start += size;
-                for(w2 = 0; w2 < sce->ics.group_len[w]; w2++)
-                    memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
-                continue;
-            }
-            for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
-                for(i = 0; i < size; i++){
-                    float t = coefs[w2*128+i]*coefs[w2*128+i];
-                    maxq[w*16+g] = fmaxf(maxq[w*16+g], coefs[w2*128 + i]);
-                    thr += t;
-                    if(sce->ics.num_windows == 1 && maxval < t){
-                        maxval = t;
-                        peakpos = start+i;
-                    }
-                }
-            }
-            if(sce->ics.num_windows == 1){
-                start2 = FFMAX(peakpos - 2, start2);
-                end2   = FFMIN(peakpos + 3, end2);
-            }
-            start += size;
-            thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
-            t = 1.0 - (1.0 * start2 / last);
-            uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
-        }
-    }
-#else
-    memset(maxq, 0, sizeof(maxq));
-    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++){
-            float *coefs = sce->coeffs + start;
-            const int size = sce->ics.swb_sizes[g];
-            float thr = 0.0f;
-            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];
-                thr += band->threshold;
-                for(i = 0; i < size; i++){
-                    maxq[w*16+g] = fmaxf(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
-                }
-            }
-            uplim[w*16+g] = thr / lambda;
-            start += size;
-        }
-    }
-#endif
-    memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
-    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 int size = sce->ics.swb_sizes[g];
-            int scf, prev_scf, step;
-            if(maxq[w*16+g] < 21.544){
-                sce->zeroes[w*16+g] = 1;
-                continue;
-            }
-            sce->zeroes[w*16+g] = 0;
-            scf = prev_scf = av_clip(SCALE_ONE_POS + log2(1/maxq[w*16+g])*16/3, 60, 218);
-            step = 16;
-            for(;;){
-                float dist = 0.0f, t;
-                int quant_max;
-
-                for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
-                    int b;
-                    dist += quantize_band_cost(coefs + w2*128,
-                                               sce->ics.swb_sizes[g],
-                                               scf,
-                                               ESC_BT,
-                                               1.0,
-                                               INFINITY,
-                                               &b);
-                    dist -= b;
-                }
-                quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS]);
-                if(quant_max >= 8191){ // too much, return to the previous quantizer
-                    sce->sf_idx[w*16+g] = prev_scf;
-                    break;
-                }
-                prev_scf = scf;
-                t = pow(dist / size, -2.0/3.0);
-                if(FFABS(step) > 4){
-                    int newstep = 4*log(t / maxq[w*16+g])/log(2) - 2;
-                    step = av_clip(-newstep, -4, 4);
-                }
-                if(FFABS(step) >= 4){
-                    step = 1 - step;
-                    scf += step;
-                }else if(t >= uplim[w*16+g]){
-                    scf -= FFABS(step);
-                }else{
-                    sce->sf_idx[w*16+g] = scf;
-                    break;
-                }
-            }
-            start += size;
-        }
-    }
-    minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
-    for(i = 1; i < 128; i++){
-        if(!sce->sf_idx[i])
-            sce->sf_idx[i] = sce->sf_idx[i-1];
-        else
-            minq = FFMIN(minq, sce->sf_idx[i]);
-    }
-    if(minq == INT_MAX) minq = 0;
-    for(i = 126; i >= 0; i--){
-        if(!sce->sf_idx[i])
-            sce->sf_idx[i] = sce->sf_idx[i+1];
-        sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF);
-    }
-}
-
-static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
-{
-    int start = 0, i, w, w2, g;
-    int minq = 255;
-
-    memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
-    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++){
-            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];
-                if(band->energy <= band->threshold){
-                    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->zeroes[(w+w2)*16+g] = 0;
-                }
-                minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);
-            }
-        }
-    }
-    for(i = 0; i < 128; i++){
-        sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
-    }
-    //set the same quantizers inside window groups
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
-        for(g = 0;  g < sce->ics.num_swb; g++)
-            for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
-                sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
-                                  SingleChannelElement *sce)
-{
-    search_for_quantizers_anmr(s, sce, s->lambda);
-//    search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
-//    search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
-//    search_for_quantizers_fast(s, sce);
-}
-
-static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
-{
-    int start = 0, i, w, w2, g;
-    float M[128], S[128];
-    SingleChannelElement *sce0 = &cpe->ch[0];
-    SingleChannelElement *sce1 = &cpe->ch[1];
-    if(!cpe->common_window)
-        return;
-    for(w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]){
-        for(g = 0;  g < sce0->ics.num_swb; g++){
-            if(!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]){
-                float dist1 = 0.0f, dist2 = 0.0f;
-                for(w2 = 0; w2 < sce0->ics.group_len[w]; w2++){
-                    FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g];
-                    FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g];
-                    float minthr = fminf(band0->threshold, band1->threshold);
-                    float maxthr = fmaxf(band0->threshold, band1->threshold);
-                    for(i = 0; i < sce0->ics.swb_sizes[g]; i++){
-                        M[i] = (sce0->coeffs[start+w2*128+i]
-                              + sce1->coeffs[start+w2*128+i])*0.5;
-                        S[i] =  sce0->coeffs[start+w2*128+i]
-                              - sce1->coeffs[start+w2*128+i];
-                    }
-                    dist1 += quantize_band_cost(sce0->coeffs + start + w2*128,
-                                                sce0->ics.swb_sizes[g],
-                                                sce0->sf_idx[(w+w2)*16+g],
-                                                sce0->band_type[(w+w2)*16+g],
-                                                lambda / band0->threshold, INFINITY, NULL);
-                    dist1 += quantize_band_cost(sce1->coeffs + start + w2*128,
-                                                sce1->ics.swb_sizes[g],
-                                                sce1->sf_idx[(w+w2)*16+g],
-                                                sce1->band_type[(w+w2)*16+g],
-                                                lambda / band1->threshold, INFINITY, NULL);
-                    dist2 += quantize_band_cost(M,
-                                                sce0->ics.swb_sizes[g],
-                                                sce0->sf_idx[(w+w2)*16+g],
-                                                sce0->band_type[(w+w2)*16+g],
-                                                lambda / maxthr, INFINITY, NULL);
-                    dist2 += quantize_band_cost(S,
-                                                sce1->ics.swb_sizes[g],
-                                                sce1->sf_idx[(w+w2)*16+g],
-                                                sce1->band_type[(w+w2)*16+g],
-                                                lambda / minthr, INFINITY, NULL);
-                }
-                cpe->ms_mask[w*16+g] = dist2 < dist1;
-            }
-            start += sce0->ics.swb_sizes[g];
-        }
-    }
-}
-
 /**
  * Encode scalefactor band coding type.
  */
@@ -1451,7 +362,7 @@ static void encode_band_info(AACEncConte
     int w;
 
     for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
+        s->coder->encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
     }
 }
 
@@ -1508,7 +419,7 @@ static void encode_spectral_coeffs(AACEn
                 continue;
             }
             for(w2 = w; w2 < w + sce->ics.group_len[w]; w2++){
-                quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
+                s->coder->quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
                                          sce->ics.swb_sizes[i],
                                          sce->sf_idx[w*16 + i],
                                          sce->band_type[w*16 + i],
@@ -1617,7 +528,7 @@ static int aac_encode_frame(AVCodecConte
 
             s->cur_channel = start_ch + j;
             apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
-            search_for_quantizers(avctx, s, &cpe->ch[j]);
+            s->coder->search_for_quantizers(avctx, s, &cpe->ch[j], s->lambda);
         }
         cpe->common_window = 0;
         if(chans > 1
@@ -1632,7 +543,8 @@ static int aac_encode_frame(AVCodecConte
                 }
             }
         }
-//        search_for_ms(s, cpe, s->lambda);
+        if(cpe->common_window && s->coder->search_for_ms)
+            s->coder->search_for_ms(s, cpe, s->lambda);
         adjust_frame_information(s, cpe, chans);
         put_bits(&s->pb, 3, tag);
         put_bits(&s->pb, 4, chan_el_counter[tag]++);

Copied and modified: aacenc/aacenc.h (from r4006, aacenc/aacenc.c)
==============================================================================
--- aacenc/aacenc.c	Mon Jan 26 14:37:36 2009	(r4006, copy source)
+++ aacenc/aacenc.h	Mon Jan 26 15:07:28 2009	(r4008)
@@ -19,138 +19,35 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/**
- * @file aacenc.c
- * AAC encoder
- */
-
-/***********************************
- *              TODOs:
- * speedup quantizer selection
- * add sane pulse detection
- * add temporal noise shaping
- ***********************************/
+#ifndef AVCODEC_AACENC_H
+#define AVCODEC_AACENC_H
 
 #include "avcodec.h"
 #include "bitstream.h"
 #include "dsputil.h"
-#include "mpeg4audio.h"
 
 #include "aac.h"
-#include "aactab.h"
 
 #include "psymodel.h"
 
-static const uint8_t swb_size_1024_96[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-};
-
-static const uint8_t swb_size_1024_64[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
-    12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36,
-    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40
-};
-
-static const uint8_t swb_size_1024_48[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    96
-};
-
-static const uint8_t swb_size_1024_32[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
-};
-
-static const uint8_t swb_size_1024_24[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28,
-    32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
-};
-
-static const uint8_t swb_size_1024_16[] = {
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-    12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28,
-    32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64
-};
-
-static const uint8_t swb_size_1024_8[] = {
-    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-    16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28,
-    32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80
-};
-
-static const uint8_t *swb_size_1024[] = {
-    swb_size_1024_96, swb_size_1024_96, swb_size_1024_64,
-    swb_size_1024_48, swb_size_1024_48, swb_size_1024_32,
-    swb_size_1024_24, swb_size_1024_24, swb_size_1024_16,
-    swb_size_1024_16, swb_size_1024_16, swb_size_1024_8
-};
-
-static const uint8_t swb_size_128_96[] = {
-    4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
-};
-
-static const uint8_t swb_size_128_48[] = {
-    4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16
-};
-
-static const uint8_t swb_size_128_24[] = {
-    4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20
-};
-
-static const uint8_t swb_size_128_16[] = {
-    4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20
-};
-
-static const uint8_t swb_size_128_8[] = {
-    4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20
-};
-
-static const uint8_t *swb_size_128[] = {
-    /* the last entry on the following row is swb_size_128_64 but is a
-       duplicate of swb_size_128_96 */
-    swb_size_128_96, swb_size_128_96, swb_size_128_96,
-    swb_size_128_48, swb_size_128_48, swb_size_128_48,
-    swb_size_128_24, swb_size_128_24, swb_size_128_16,
-    swb_size_128_16, swb_size_128_16, swb_size_128_8
-};
-
-/** bits needed to code codebook run value for long windows */
-static const uint8_t run_value_bits_long[64] = {
-     5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-     5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 10,
-    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
-};
-
-/** bits needed to code codebook run value for short windows */
-static const uint8_t run_value_bits_short[16] = {
-    3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
-};
+struct AACEncContext;
 
-static const uint8_t* run_value_bits[2] = {
-    run_value_bits_long, run_value_bits_short
-};
+typedef struct AACCoefficientsEncoder{
+    void (*search_for_quantizers)(AVCodecContext *avctx, struct AACEncContext *s,
+                                  SingleChannelElement *sce, const float lambda);
+    void (*encode_window_bands_info)(struct AACEncContext *s, SingleChannelElement *sce,
+                                     int win, int group_len);
+    void (*quantize_and_encode_band)(PutBitContext *pb, const float *in, int size,
+                                     int scale_idx, int cb, const float lambda);
+    void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda);
+}AACCoefficientsEncoder;
 
-/** default channel configurations */
-static const uint8_t aac_chan_configs[6][5] = {
- {1, TYPE_SCE},                               // 1 channel  - single channel element
- {1, TYPE_CPE},                               // 2 channels - channel pair
- {2, TYPE_SCE, TYPE_CPE},                     // 3 channels - center + stereo
- {3, TYPE_SCE, TYPE_CPE, TYPE_SCE},           // 4 channels - front center + stereo + back center
- {3, TYPE_SCE, TYPE_CPE, TYPE_CPE},           // 5 channels - front center + stereo + back stereo
- {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
-};
+extern AACCoefficientsEncoder ff_aac_coders[];
 
 /**
  * AAC encoder context
  */
-typedef struct {
+typedef struct AACEncContext {
     PutBitContext pb;
     MDCTContext mdct1024;                        ///< long (1024 samples) frame transform context
     MDCTContext mdct128;                         ///< short (128 samples) frame transform context
@@ -163,1526 +60,10 @@ typedef struct {
     ChannelElement *cpe;                         ///< channel elements
     FFPsyContext psy;
     struct FFPsyPreprocessContext* psypp;
+    AACCoefficientsEncoder *coder;
     int cur_channel;
     int last_frame;
     float lambda;
 } AACEncContext;
 
-/**
- * Make AAC audio config object.
- * @see 1.6.2.1 "Syntax - AudioSpecificConfig"
- */
-static void put_audio_specific_config(AVCodecContext *avctx)
-{
-    PutBitContext pb;
-    AACEncContext *s = avctx->priv_data;
-
-    init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8);
-    put_bits(&pb, 5, 2); //object type - AAC-LC
-    put_bits(&pb, 4, s->samplerate_index); //sample rate index
-    put_bits(&pb, 4, avctx->channels);
-    //GASpecificConfig
-    put_bits(&pb, 1, 0); //frame length - 1024 samples
-    put_bits(&pb, 1, 0); //does not depend on core coder
-    put_bits(&pb, 1, 0); //is not extension
-    flush_put_bits(&pb);
-}
-
-static av_cold int aac_encode_init(AVCodecContext *avctx)
-{
-    AACEncContext *s = avctx->priv_data;
-    int i;
-    const uint8_t *sizes[2];
-    int lengths[2];
-
-    avctx->frame_size = 1024;
-
-    for(i = 0; i < 16; i++)
-        if(avctx->sample_rate == ff_mpeg4audio_sample_rates[i])
-            break;
-    if(i == 16){
-        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);
-        return -1;
-    }
-    if(avctx->channels > 6){
-        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels);
-        return -1;
-    }
-    s->samplerate_index = i;
-
-    dsputil_init(&s->dsp, avctx);
-    ff_mdct_init(&s->mdct1024, 11, 0);
-    ff_mdct_init(&s->mdct128,   8, 0);
-    // window init
-    ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
-    ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
-    ff_sine_window_init(ff_sine_1024, 1024);
-    ff_sine_window_init(ff_sine_128, 128);
-
-    s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));
-    s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]);
-    avctx->extradata = av_malloc(2);
-    avctx->extradata_size = 2;
-    put_audio_specific_config(avctx);
-
-    sizes[0] = swb_size_1024[i];
-    sizes[1] = swb_size_128[i];
-    lengths[0] = ff_aac_num_swb_1024[i];
-    lengths[1] = ff_aac_num_swb_128[i];
-    ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
-    s->psypp = ff_psy_preprocess_init(avctx);
-
-#if !CONFIG_HARDCODED_TABLES
-    for (i = 0; i < 316; i++)
-        ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.);
-#endif /* CONFIG_HARDCODED_TABLES */
-
-    return 0;
-}
-
-static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s,
-                                  SingleChannelElement *sce, short *audio, int channel)
-{
-    int i, j, k;
-    const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
-    const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
-    const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
-
-    if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
-        memcpy(s->output, sce->saved, sizeof(float)*1024);
-        if(sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE){
-            memset(s->output, 0, sizeof(s->output[0]) * 448);
-            for(i = 448; i < 576; i++)
-                s->output[i] = sce->saved[i] * pwindow[i - 448];
-            for(i = 576; i < 704; i++)
-                s->output[i] = sce->saved[i];
-        }
-        if(sce->ics.window_sequence[0] != LONG_START_SEQUENCE){
-            j = channel;
-            for (i = 0; i < 1024; i++, j += avctx->channels){
-                s->output[i+1024]         = audio[j] * lwindow[1024 - i - 1];
-                sce->saved[i] = audio[j] * lwindow[i];
-            }
-        }else{
-            j = channel;
-            for(i = 0; i < 448; i++, j += avctx->channels)
-                s->output[i+1024]         = audio[j];
-            for(i = 448; i < 576; i++, j += avctx->channels)
-                s->output[i+1024]         = audio[j] * swindow[576 - i - 1];
-            memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448);
-            j = channel;
-            for(i = 0; i < 1024; i++, j += avctx->channels)
-                sce->saved[i] = audio[j];
-        }
-        ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output);
-    }else{
-        j = channel;
-        for (k = 0; k < 1024; k += 128) {
-            for(i = 448 + k; i < 448 + k + 256; i++)
-                s->output[i - 448 - k] = (i < 1024)
-                                         ? sce->saved[i]
-                                         : audio[channel + (i-1024)*avctx->channels];
-            s->dsp.vector_fmul        (s->output,     k ?  swindow : pwindow, 128);
-            s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128);
-            ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output);
-        }
-        j = channel;
-        for(i = 0; i < 1024; i++, j += avctx->channels)
-            sce->saved[i] = audio[j];
-    }
-}
-
-/**
- * Encode ics_info element.
- * @see Table 4.6 (syntax of ics_info)
- */
-static void put_ics_info(AACEncContext *s, IndividualChannelStream *info)
-{
-    int w;
-
-    put_bits(&s->pb, 1, 0);                // ics_reserved bit
-    put_bits(&s->pb, 2, info->window_sequence[0]);
-    put_bits(&s->pb, 1, info->use_kb_window[0]);
-    if(info->window_sequence[0] != EIGHT_SHORT_SEQUENCE){
-        put_bits(&s->pb, 6, info->max_sfb);
-        put_bits(&s->pb, 1, 0);            // no prediction
-    }else{
-        put_bits(&s->pb, 4, info->max_sfb);
-        for(w = 1; w < 8; w++){
-            put_bits(&s->pb, 1, !info->group_len[w]);
-        }
-    }
-}
-
-/**
- * Encode MS data.
- * @see 4.6.8.1 "Joint Coding - M/S Stereo"
- */
-static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
-{
-    int i, w;
-
-    put_bits(pb, 2, cpe->ms_mode);
-    if(cpe->ms_mode == 1){
-        for(w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w]){
-            for(i = 0; i < cpe->ch[0].ics.max_sfb; i++)
-                put_bits(pb, 1, cpe->ms_mask[w*16 + i]);
-        }
-    }
-}
-
-/**
- * Quantize one coefficient.
- * @return absolute value of the quantized coefficient
- * @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
- */
-static av_always_inline int quant(float coef, const float Q)
-{
-    return av_clip((int)(pow(fabsf(coef) * Q, 0.75) + 0.4054), 0, 8191);
-}
-
-#if 1
-
-static av_always_inline int quant2(float coef, const float Q)
-{
-    return av_clip((int)(pow(fabsf(coef) * Q, 0.75)), 0, 8191);
-}
-
-static const float aac_cb_range[12] = { 0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
-static const float aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
-                                 const float lambda, const float uplim, int *bits)
-{
-    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];
-    int i, j, k;
-    float cost = 0;
-    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-    int resbits = 0;
-    const int range = aac_cb_range[cb];
-    const int maxval = aac_cb_maxval[cb];
-    int offs[4];
-
-    if(!cb){
-        for(i = 0; i < size; i++)
-            cost += in[i]*in[i]*lambda;
-        return cost;
-    }
-    offs[0] = 1;
-    for(i = 1; i < dim; i++)
-        offs[i] = offs[i-1]*range;
-    for(i = 0; i < size; i += dim){
-        float mincost;
-        int minidx = 0;
-        int minbits = 0;
-        int quants[4][2], realquants[4][2];
-        mincost = 0.0f;
-        for(j = 0; j < dim; j++){
-            realquants[j][0] = quant2(in[i+j], Q);
-            realquants[j][1] = quant (in[i+j], Q);
-            for(k = 0; k < 2; k++){
-                quants[j][k] = FFMIN(realquants[j][k], maxval);
-                if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
-                    quants[j][k] = -quants[j][k];
-            }
-            mincost += in[i+j]*in[i+j]*lambda;
-        }
-        minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-        minbits = ff_aac_spectral_bits[cb-1][minidx];
-        mincost += minbits;
-        for(j = 0; j < (1<<dim); j++){
-            float rd = 0.0f;
-            int curbits;
-            int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-            const float *vec;
-            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];
-            vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*IQ){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*IQ){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = realquants[k];
-                            di = t - c*cbrt(c)*IQ;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*IQ;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*IQ;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = j;
-                minbits = curbits;
-            }
-        }
-        cost += mincost;
-        resbits += minbits;
-        if(cost >= uplim)
-            return uplim;
-    }
-
-    if(bits)
-        *bits = resbits;
-    return cost;
-}
-
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
-                                     int scale_idx, int cb, const float lambda)
-{
-    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 int range = aac_cb_range[cb];
-    const int maxval = aac_cb_maxval[cb];
-    const int dim = (cb < FIRST_PAIR_BT) ? 4 : 2;
-    int i, j, k;
-    int offs[4];
-
-    if(!cb)
-        return;
-
-    offs[0] = 1;
-    for(i = 1; i < dim; i++)
-        offs[i] = offs[i-1]*range;
-    for(i = 0; i < size; i += dim){
-        float mincost;
-        int minidx = 0;
-        int minbits = 0;
-        int quants[4][2];
-        mincost = 0.0f;
-        for(j = 0; j < dim; j++){
-            quants[j][0] = av_clip(quant2(in[i+j], Q), -maxval, maxval);
-            quants[j][1] = av_clip(quant (in[i+j], Q), -maxval, maxval);
-            for(k = 0; k < 2; k++){
-                quants[j][k] = FFMIN(quants[j][k], maxval);
-                if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
-                    quants[j][k] = -quants[j][k];
-            }
-            mincost += in[i+j]*in[i+j]*lambda;
-        }
-        minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-        minbits = ff_aac_spectral_bits[cb-1][minidx];
-        mincost += minbits;
-        for(j = 0; j < (1<<dim); j++){
-            float rd = 0.0f;
-            int curbits;
-            int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
-            const float *vec;
-            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];
-            vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*IQ){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*IQ){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = quant(t, Q);
-                            di = t - c*cbrt(c)*IQ;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*IQ;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*IQ;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = curidx;
-                minbits = curbits;
-            }
-        }
-        put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
-        if(IS_CODEBOOK_UNSIGNED(cb))
-            for(j = 0; j < dim; j++)
-                if(ff_aac_codebook_vectors[cb-1][minidx*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){
-                    int coef = quant(in[i+j], Q);
-                    int len = av_log2(coef);
-
-                    put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
-                    put_bits(pb, len, coef & ((1 << len) - 1));
-                }
-            }
-        }
-    }
-}
-
-#else
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
-                                 const float lambda, const float uplim, int *bits)
-{
-    const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
-    int i, j, k;
-    float cost = 0;
-    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-    int resbits = 0;
-
-    if(!cb){
-        for(i = 0; i < size; i++)
-            cost += in[i]*in[i]*lambda;
-        return cost;
-    }
-    for(i = 0; i < size; i += dim){
-        float mincost = INFINITY;
-        int minidx = 0;
-        int minbits = 0;
-        const float *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];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*Q){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*Q){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = quant(t, 1.0/Q);
-                            di = t - c*cbrt(c)*Q;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*Q;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*Q;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = j;
-                minbits = curbits;
-            }
-        }
-        cost += mincost;
-        resbits += minbits;
-        if(cost >= uplim)
-            return uplim;
-    }
-
-    if(bits)
-        *bits = resbits;
-    return cost;
-}
-
-/**
- * Prepare coefficients for encoding.
- *
- * @return sum of coefficient absolute values
- */
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
-                                      int scale_idx, int cb, const float lambda)
-{
-    const float Q  = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
-    const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
-    int i, j, k;
-    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-
-    if(!cb)
-        return;
-
-    for(i = 0; i < size; i += dim){
-        float mincost = INFINITY;
-        int minidx = 0;
-        int minbits = 0;
-        const float *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];
-            if(IS_CODEBOOK_UNSIGNED(cb)){
-                for(k = 0; k < dim; k++){
-                    float t = fabsf(in[i+k]);
-                    float di;
-                    //do not code with escape sequence small values
-                    if(vec[k] == 64.0f && t < 39.0f*Q){
-                        rd = INFINITY;
-                        break;
-                    }
-                    if(vec[k] == 64.0f){//FIXME: slow
-                        if(t >= 165140.0f*Q){ // clipped value
-                            di = t - 165140.0f;
-                            curbits += 21;
-                        }else{
-                            int c = quant(t, IQ);
-                            di = t - c*cbrt(c)*Q;
-                            curbits += av_log2(c)*2 - 4 + 1;
-                        }
-                    }else{
-                        di = t - vec[k]*Q;
-                    }
-                    if(vec[k] != 0.0f)
-                        curbits++;
-                    rd += di*di*lambda;
-                }
-            }else{
-                for(k = 0; k < dim; k++){
-                    float di = in[i+k] - vec[k]*Q;
-                    rd += di*di*lambda;
-                }
-            }
-            rd += curbits;
-            if(rd < mincost){
-                mincost = rd;
-                minidx = j;
-                minbits = curbits;
-            }
-        }
-        put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
-        if(IS_CODEBOOK_UNSIGNED(cb))
-            for(j = 0; j < dim; j++)
-                if(ff_aac_codebook_vectors[cb-1][minidx*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){
-                    int coef = quant(in[i+j], IQ);
-                    int len = av_log2(coef);
-
-                    put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
-                    put_bits(pb, len, coef & ((1 << len) - 1));
-                }
-            }
-        }
-    }
-}
-
-#endif
-
-/**
- * structure used in optimal codebook search
- */
-typedef struct BandCodingPath {
-    int prev_idx; ///< pointer to the previous path point
-    int codebook; ///< codebook for coding band run
-    float cost;   ///< path cost
-    int run;
-} BandCodingPath;
-
-/**
- * Encode band info for single window group bands.
- */
-static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
-                                     int win, int group_len)
-{
-    BandCodingPath path[120][12];
-    int w, swb, cb, start, start2, 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;
-
-    start = win*128;
-    for(cb = 0; cb < 12; cb++){
-        path[0][cb].cost = 0.0f;
-        path[0][cb].prev_idx = -1;
-        path[0][cb].run = 0;
-    }
-    for(swb = 0; swb < max_sfb; swb++){
-        start2 = start;
-        size = sce->ics.swb_sizes[swb];
-        if(sce->zeroes[win*16 + swb]){
-            for(cb = 0; cb < 12; cb++){
-                path[swb+1][cb].prev_idx = cb;
-                path[swb+1][cb].cost = path[swb][cb].cost;
-                path[swb+1][cb].run = path[swb][cb].run + 1;
-            }
-        }else{
-            float minrd = INFINITY;
-            int mincb = 0;
-            for(cb = 0; cb < 12; cb++){
-                float rd = 0.0f;
-                for(w = 0; w < group_len; w++){
-                    FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
-                    rd += quantize_band_cost(sce->coeffs + start + w*128, size,
-                                             sce->sf_idx[(win+w)*16+swb], cb,
-                                             s->lambda / band->threshold, INFINITY, NULL);
-                }
-                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])
-                    rd += run_bits;
-                path[swb+1][cb].prev_idx = cb;
-                path[swb+1][cb].cost = path[swb][cb].cost + rd;
-                path[swb+1][cb].run = path[swb][cb].run + 1;
-                if(rd < minrd){
-                    minrd = rd;
-                    mincb = cb;
-                }
-            }
-            for(cb = 0; cb < 12; cb++){
-                float cost = path[swb][cb].cost + minrd + run_bits + 4;
-                if(cost < path[swb+1][cb].cost){
-                    path[swb+1][cb].prev_idx = mincb;
-                    path[swb+1][cb].cost = cost;
-                    path[swb+1][cb].run = 1;
-                }
-            }
-        }
-        start += sce->ics.swb_sizes[swb];
-    }
-
-    //convert resulting path from backward-linked list
-    stack_len = 0;
-    idx = 0;
-    for(cb = 1; cb < 12; cb++){
-        if(path[max_sfb][cb].cost < path[max_sfb][idx].cost)
-            idx = cb;
-    }
-    ppos = max_sfb;
-    while(ppos > 0){
-        cb = idx;
-        stackrun[stack_len] = path[ppos][cb].run;
-        stackcb [stack_len] = cb;
-        idx = path[ppos][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--){
-        put_bits(&s->pb, 4, stackcb[i]);
-        count = stackrun[i];
-        memset(sce->zeroes + win*16 + start, !stackcb[i], count);
-        //XXX: memset when band_type is also uint8_t
-        for(j = 0; j < count; j++){
-            sce->band_type[win*16 + start] =  stackcb[i];
-            start++;
-        }
-        while(count >= run_esc){
-            put_bits(&s->pb, run_bits, run_esc);
-            count -= run_esc;
-        }
-        put_bits(&s->pb, run_bits, count);
-    }
-}
-
-/**
- * Produce integer coefficients from scalefactors provided by the model.
- */
-static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
-{
-    int i, w, w2, g, ch;
-    int start, sum, maxsfb, cmaxsfb;
-
-    for(ch = 0; ch < chans; ch++){
-        IndividualChannelStream *ics = &cpe->ch[ch].ics;
-        start = 0;
-        maxsfb = 0;
-        cpe->ch[ch].pulse.num_pulse = 0;
-        for(w = 0; w < ics->num_windows*16; w += 16){
-            for(g = 0; g < ics->num_swb; g++){
-                sum = 0;
-                //apply M/S
-                if(!ch && cpe->ms_mask[w + g]){
-                    for(i = 0; i < ics->swb_sizes[g]; i++){
-                        cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
-                        cpe->ch[1].coeffs[start+i] =  cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i];
-                    }
-                }
-                start += ics->swb_sizes[g];
-            }
-            for(cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w+cmaxsfb-1]; cmaxsfb--);
-            maxsfb = FFMAX(maxsfb, cmaxsfb);
-        }
-        ics->max_sfb = maxsfb;
-
-        //adjust zero bands for window groups
-        for(w = 0; w < ics->num_windows; w += ics->group_len[w]){
-            for(g = 0; g < ics->max_sfb; g++){
-                i = 1;
-                for(w2 = w; w2 < w + ics->group_len[w]; w2++){
-                    if(!cpe->ch[ch].zeroes[w2*16 + g]){
-                        i = 0;
-                        break;
-                    }
-                }
-                cpe->ch[ch].zeroes[w*16 + g] = i;
-            }
-        }
-    }
-
-    if(chans > 1 && cpe->common_window){
-        IndividualChannelStream *ics0 = &cpe->ch[0].ics;
-        IndividualChannelStream *ics1 = &cpe->ch[1].ics;
-        int msc = 0;
-        ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb);
-        ics1->max_sfb = ics0->max_sfb;
-        for(w = 0; w < ics0->num_windows*16; w += 16)
-            for(i = 0; i < ics0->max_sfb; i++)
-                if(cpe->ms_mask[w+i]) msc++;
-        if(msc == 0 || ics0->max_sfb == 0) cpe->ms_mode = 0;
-        else cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
-    }
-}
-
-typedef struct TrellisPath {
-    float cost;
-    int prev;
-    int min_val;
-    int max_val;
-} TrellisPath;
-
-static void search_for_quantizers_anmr(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
-    int q, w, w2, g, start = 0;
-    int i;
-    int idx;
-    TrellisPath paths[256*121];
-    int bandaddr[121];
-    int minq;
-    float mincost;
-
-    for(i = 0; i < 256; i++){
-        paths[i].cost = 0.0f;
-        paths[i].prev = -1;
-        paths[i].min_val = i;
-        paths[i].max_val = i;
-    }
-    for(i = 256; i < 256*121; i++){
-        paths[i].cost = INFINITY;
-        paths[i].prev = -2;
-        paths[i].min_val = INT_MAX;
-        paths[i].max_val = 0;
-    }
-    idx = 256;
-    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;
-            float qmin, qmax;
-            int nz = 0;
-
-            bandaddr[idx >> 8] = w*16+g;
-            qmin = INT_MAX;
-            qmax = 0.0f;
-            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];
-                if(band->energy <= band->threshold || band->threshold == 0.0f){
-                    sce->zeroes[(w+w2)*16+g] = 1;
-                    continue;
-                }
-                sce->zeroes[(w+w2)*16+g] = 0;
-                nz = 1;
-                for(i = 0; i < sce->ics.swb_sizes[g]; i++){
-                    float t = fabsf(coefs[w2*128+i]);
-                    if(t > 0.0f) qmin = fminf(qmin, t);
-                    qmax = fmaxf(qmax, t);
-                }
-            }
-            if(nz){
-                int minscale, maxscale;
-                float minrd = INFINITY;
-                //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);
-                //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);
-                for(q = minscale; q < maxscale; q++){
-                    float dists[12], dist;
-                    memset(dists, 0, sizeof(dists));
-                    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];
-                        int cb;
-                        for(cb = 0; cb <= ESC_BT; cb++){
-                            dists[cb] += quantize_band_cost(coefs + w2*128, sce->ics.swb_sizes[g],
-                                                            q, cb, s->lambda / band->threshold, INFINITY, NULL);
-                        }
-                    }
-                    dist = dists[0];
-                    for(i = 1; i <= ESC_BT; i++)
-                        dist = fminf(dist, dists[i]);
-                    minrd = fminf(minrd, dist);
-
-                    for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
-                        float cost;
-                        int minv, maxv;
-                        if(isinf(paths[idx - 256 + i].cost))
-                            continue;
-                        cost = paths[idx - 256 + i].cost + dist
-                               + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
-                        minv = FFMIN(paths[idx - 256 + i].min_val, q);
-                        maxv = FFMAX(paths[idx - 256 + i].max_val, q);
-                        if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
-                            paths[idx + q].cost = cost;
-                            paths[idx + q].prev = idx - 256 + i;
-                            paths[idx + q].min_val = minv;
-                            paths[idx + q].max_val = maxv;
-                        }
-                    }
-                }
-            }else{
-                for(q = 0; q < 256; q++){
-                    if(!isinf(paths[idx - 256 + q].cost)){
-                        paths[idx + q].cost = paths[idx - 256 + q].cost + 1;
-                        paths[idx + q].prev = idx - 256 + q;
-                        paths[idx + q].min_val = FFMIN(paths[idx - 256 + q].min_val, q);
-                        paths[idx + q].max_val = FFMAX(paths[idx - 256 + q].max_val, q);
-                        continue;
-                    }
-                    for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
-                        float cost;
-                        int minv, maxv;
-                        if(isinf(paths[idx - 256 + i].cost))
-                            continue;
-                        cost = paths[idx - 256 + i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
-                        minv = FFMIN(paths[idx - 256 + i].min_val, q);
-                        maxv = FFMAX(paths[idx - 256 + i].max_val, q);
-                        if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
-                            paths[idx + q].cost = cost;
-                            paths[idx + q].prev = idx - 256 + i;
-                            paths[idx + q].min_val = minv;
-                            paths[idx + q].max_val = maxv;
-                        }
-                    }
-                }
-            }
-            sce->zeroes[w*16+g] = !nz;
-            start += sce->ics.swb_sizes[g];
-            idx += 256;
-        }
-    }
-    idx -= 256;
-    mincost = paths[idx].cost;
-    minq = idx;
-    for(i = 1; i < 256; i++){
-        if(paths[idx + i].cost < mincost){
-            mincost = paths[idx + i].cost;
-            minq = idx + i;
-        }
-    }
-    while(minq >= 256){
-        sce->sf_idx[bandaddr[minq>>8]] = minq & 0xFF;
-        minq = paths[minq].prev;
-    }
-    //set the same quantizers inside window groups
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
-        for(g = 0;  g < sce->ics.num_swb; g++)
-            for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
-                sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-/**
- * two-loop quantizers search taken from ISO 13818-7 Appendix C
- */
-static void search_for_quantizers_twoloop(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;
-    float dists[128], uplims[128];
-    int fflag, minscaler;
-    int its = 0;
-    int allz = 0;
-    float minthr = INFINITY;
-
-    //XXX: some heuristic to determine initial quantizers will reduce search time
-    memset(dists, 0, sizeof(dists));
-    //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;
-            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];
-                uplim += band->threshold;
-                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 = fminf(minthr, uplim);
-            allz = FFMAX(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 + fminf(log2(uplims[w*16+g]/minthr)*4,59);
-        }
-    }
-
-    if(!allz)
-        return;
-    //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;
-            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;
-                    int bits = 0;
-                    int cb;
-                    float mindist = INFINITY;
-                    int minbits = 0;
-
-                    if(sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218)
-                        continue;
-                    minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
-                    for(cb = 0; cb <= ESC_BT; cb++){
-                        float dist = 0.0f;
-                        int bb = 0;
-                        for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
-                            int b;
-                            dist += quantize_band_cost(coefs + w2*128,
-                                                       sce->ics.swb_sizes[g],
-                                                       sce->sf_idx[w*16+g],
-                                                       ESC_BT,
-                                                       1.0,
-                                                       INFINITY,
-                                                       &b);
-                            bb += b;
-                        }
-                        if(dist < mindist){
-                            mindist = dist;
-                            minbits = bb;
-                        }
-                    }
-                    dists[w*16+g] = mindist - minbits;
-                    bits = minbits;
-                    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)
-                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)
-                    sce->sf_idx[w*16+g]--;
-                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;
-            }
-        }
-        its++;
-    }while(fflag && its < 10);
-}
-
-static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
-    int start = 0, i, w, w2, g;
-    float uplim[128], maxq[128];
-    int minq;
-#if 0
-    float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
-    int last = 0, lastband = 0, curband = 0;
-    float avg_energy = 0.0;
-    if(sce->ics.num_windows == 1){
-        start = 0;
-        for(i = 0; i < 1024; i++){
-            if(i - start >= sce->ics.swb_sizes[curband]){
-                start += sce->ics.swb_sizes[curband];
-                curband++;
-            }
-            if(sce->coeffs[i]){
-                avg_energy += sce->coeffs[i] * sce->coeffs[i];
-                last = i;
-                lastband = curband;
-            }
-        }
-    }else{
-        for(w = 0; w < 8; w++){
-            const float *coeffs = sce->coeffs + w*128;
-            start = 0;
-            for(i = 0; i < 128; i++){
-                if(i - start >= sce->ics.swb_sizes[curband]){
-                    start += sce->ics.swb_sizes[curband];
-                    curband++;
-                }
-                if(coeffs[i]){
-                    avg_energy += coeffs[i] * coeffs[i];
-                    last = FFMAX(last, i);
-                    lastband = FFMAX(lastband, curband);
-                }
-            }
-        }
-    }
-    last++;
-    avg_energy /= last;
-    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++){
-            float *coefs = sce->coeffs + start;
-            const int size = sce->ics.swb_sizes[g];
-            int start2 = start, end2 = start + size, peakpos = start;
-            float maxval = -1, thr = 0.0f, t;
-            maxq[w*16+g] = 0.0f;
-            if(g > lastband){
-                maxq[w*16+g] = 0.0f;
-                start += size;
-                for(w2 = 0; w2 < sce->ics.group_len[w]; w2++)
-                    memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
-                continue;
-            }
-            for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
-                for(i = 0; i < size; i++){
-                    float t = coefs[w2*128+i]*coefs[w2*128+i];
-                    maxq[w*16+g] = fmaxf(maxq[w*16+g], coefs[w2*128 + i]);
-                    thr += t;
-                    if(sce->ics.num_windows == 1 && maxval < t){
-                        maxval = t;
-                        peakpos = start+i;
-                    }
-                }
-            }
-            if(sce->ics.num_windows == 1){
-                start2 = FFMAX(peakpos - 2, start2);
-                end2   = FFMIN(peakpos + 3, end2);
-            }
-            start += size;
-            thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
-            t = 1.0 - (1.0 * start2 / last);
-            uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
-        }
-    }
-#else
-    memset(maxq, 0, sizeof(maxq));
-    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++){
-            float *coefs = sce->coeffs + start;
-            const int size = sce->ics.swb_sizes[g];
-            float thr = 0.0f;
-            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];
-                thr += band->threshold;
-                for(i = 0; i < size; i++){
-                    maxq[w*16+g] = fmaxf(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
-                }
-            }
-            uplim[w*16+g] = thr / lambda;
-            start += size;
-        }
-    }
-#endif
-    memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
-    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 int size = sce->ics.swb_sizes[g];
-            int scf, prev_scf, step;
-            if(maxq[w*16+g] < 21.544){
-                sce->zeroes[w*16+g] = 1;
-                continue;
-            }
-            sce->zeroes[w*16+g] = 0;
-            scf = prev_scf = av_clip(SCALE_ONE_POS + log2(1/maxq[w*16+g])*16/3, 60, 218);
-            step = 16;
-            for(;;){
-                float dist = 0.0f, t;
-                int quant_max;
-
-                for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
-                    int b;
-                    dist += quantize_band_cost(coefs + w2*128,
-                                               sce->ics.swb_sizes[g],
-                                               scf,
-                                               ESC_BT,
-                                               1.0,
-                                               INFINITY,
-                                               &b);
-                    dist -= b;
-                }
-                quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS]);
-                if(quant_max >= 8191){ // too much, return to the previous quantizer
-                    sce->sf_idx[w*16+g] = prev_scf;
-                    break;
-                }
-                prev_scf = scf;
-                t = pow(dist / size, -2.0/3.0);
-                if(FFABS(step) > 4){
-                    int newstep = 4*log(t / maxq[w*16+g])/log(2) - 2;
-                    step = av_clip(-newstep, -4, 4);
-                }
-                if(FFABS(step) >= 4){
-                    step = 1 - step;
-                    scf += step;
-                }else if(t >= uplim[w*16+g]){
-                    scf -= FFABS(step);
-                }else{
-                    sce->sf_idx[w*16+g] = scf;
-                    break;
-                }
-            }
-            start += size;
-        }
-    }
-    minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
-    for(i = 1; i < 128; i++){
-        if(!sce->sf_idx[i])
-            sce->sf_idx[i] = sce->sf_idx[i-1];
-        else
-            minq = FFMIN(minq, sce->sf_idx[i]);
-    }
-    if(minq == INT_MAX) minq = 0;
-    for(i = 126; i >= 0; i--){
-        if(!sce->sf_idx[i])
-            sce->sf_idx[i] = sce->sf_idx[i+1];
-        sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF);
-    }
-}
-
-static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
-{
-    int start = 0, i, w, w2, g;
-    int minq = 255;
-
-    memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
-    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++){
-            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];
-                if(band->energy <= band->threshold){
-                    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->zeroes[(w+w2)*16+g] = 0;
-                }
-                minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);
-            }
-        }
-    }
-    for(i = 0; i < 128; i++){
-        sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
-    }
-    //set the same quantizers inside window groups
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
-        for(g = 0;  g < sce->ics.num_swb; g++)
-            for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
-                sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
-                                  SingleChannelElement *sce)
-{
-    search_for_quantizers_anmr(s, sce, s->lambda);
-//    search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
-//    search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
-//    search_for_quantizers_fast(s, sce);
-}
-
-static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
-{
-    int start = 0, i, w, w2, g;
-    float M[128], S[128];
-    SingleChannelElement *sce0 = &cpe->ch[0];
-    SingleChannelElement *sce1 = &cpe->ch[1];
-    if(!cpe->common_window)
-        return;
-    for(w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]){
-        for(g = 0;  g < sce0->ics.num_swb; g++){
-            if(!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]){
-                float dist1 = 0.0f, dist2 = 0.0f;
-                for(w2 = 0; w2 < sce0->ics.group_len[w]; w2++){
-                    FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g];
-                    FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g];
-                    float minthr = fminf(band0->threshold, band1->threshold);
-                    float maxthr = fmaxf(band0->threshold, band1->threshold);
-                    for(i = 0; i < sce0->ics.swb_sizes[g]; i++){
-                        M[i] = (sce0->coeffs[start+w2*128+i]
-                              + sce1->coeffs[start+w2*128+i])*0.5;
-                        S[i] =  sce0->coeffs[start+w2*128+i]
-                              - sce1->coeffs[start+w2*128+i];
-                    }
-                    dist1 += quantize_band_cost(sce0->coeffs + start + w2*128,
-                                                sce0->ics.swb_sizes[g],
-                                                sce0->sf_idx[(w+w2)*16+g],
-                                                sce0->band_type[(w+w2)*16+g],
-                                                lambda / band0->threshold, INFINITY, NULL);
-                    dist1 += quantize_band_cost(sce1->coeffs + start + w2*128,
-                                                sce1->ics.swb_sizes[g],
-                                                sce1->sf_idx[(w+w2)*16+g],
-                                                sce1->band_type[(w+w2)*16+g],
-                                                lambda / band1->threshold, INFINITY, NULL);
-                    dist2 += quantize_band_cost(M,
-                                                sce0->ics.swb_sizes[g],
-                                                sce0->sf_idx[(w+w2)*16+g],
-                                                sce0->band_type[(w+w2)*16+g],
-                                                lambda / maxthr, INFINITY, NULL);
-                    dist2 += quantize_band_cost(S,
-                                                sce1->ics.swb_sizes[g],
-                                                sce1->sf_idx[(w+w2)*16+g],
-                                                sce1->band_type[(w+w2)*16+g],
-                                                lambda / minthr, INFINITY, NULL);
-                }
-                cpe->ms_mask[w*16+g] = dist2 < dist1;
-            }
-            start += sce0->ics.swb_sizes[g];
-        }
-    }
-}
-
-/**
- * Encode scalefactor band coding type.
- */
-static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
-{
-    int w;
-
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
-    }
-}
-
-/**
- * Encode scalefactors.
- */
-static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce)
-{
-    int off = sce->sf_idx[0], diff;
-    int i, w;
-
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        for(i = 0; i < sce->ics.max_sfb; i++){
-            if(!sce->zeroes[w*16 + i]){
-                diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO;
-                if(diff < 0 || diff > 120) av_log(avctx, AV_LOG_ERROR, "Scalefactor difference is too big to be coded\n");
-                off = sce->sf_idx[w*16 + i];
-                put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]);
-            }
-        }
-    }
-}
-
-/**
- * Encode pulse data.
- */
-static void encode_pulses(AACEncContext *s, Pulse *pulse)
-{
-    int i;
-
-    put_bits(&s->pb, 1, !!pulse->num_pulse);
-    if(!pulse->num_pulse) return;
-
-    put_bits(&s->pb, 2, pulse->num_pulse - 1);
-    put_bits(&s->pb, 6, pulse->start);
-    for(i = 0; i < pulse->num_pulse; i++){
-        put_bits(&s->pb, 5, pulse->pos[i]);
-        put_bits(&s->pb, 4, pulse->amp[i]);
-    }
-}
-
-/**
- * Encode spectral coefficients processed by psychoacoustic model.
- */
-static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
-{
-    int start, i, w, w2;
-
-    for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
-        start = 0;
-        for(i = 0; i < sce->ics.max_sfb; i++){
-            if(sce->zeroes[w*16 + i]){
-                start += sce->ics.swb_sizes[i];
-                continue;
-            }
-            for(w2 = w; w2 < w + sce->ics.group_len[w]; w2++){
-                quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
-                                         sce->ics.swb_sizes[i],
-                                         sce->sf_idx[w*16 + i],
-                                         sce->band_type[w*16 + i],
-                                         s->lambda);
-            }
-            start += sce->ics.swb_sizes[i];
-        }
-    }
-}
-
-/**
- * Encode one channel of audio data.
- */
-static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce, int common_window)
-{
-    put_bits(&s->pb, 8, sce->sf_idx[0]);
-    if(!common_window) put_ics_info(s, &sce->ics);
-    encode_band_info(s, sce);
-    encode_scale_factors(avctx, s, sce);
-    encode_pulses(s, &sce->pulse);
-    put_bits(&s->pb, 1, 0); //tns
-    put_bits(&s->pb, 1, 0); //ssr
-    encode_spectral_coeffs(s, sce);
-    return 0;
-}
-
-/**
- * Write some auxiliary information about the created AAC file.
- */
-static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, const char *name)
-{
-    int i, namelen, padbits;
-
-    namelen = strlen(name) + 2;
-    put_bits(&s->pb, 3, TYPE_FIL);
-    put_bits(&s->pb, 4, FFMIN(namelen, 15));
-    if(namelen >= 15)
-        put_bits(&s->pb, 8, namelen - 16);
-    put_bits(&s->pb, 4, 0); //extension type - filler
-    padbits = 8 - (put_bits_count(&s->pb) & 7);
-    align_put_bits(&s->pb);
-    for(i = 0; i < namelen - 2; i++)
-        put_bits(&s->pb, 8, name[i]);
-    put_bits(&s->pb, 12 - padbits, 0);
-}
-
-static int aac_encode_frame(AVCodecContext *avctx,
-                            uint8_t *frame, int buf_size, void *data)
-{
-    AACEncContext *s = avctx->priv_data;
-    int16_t *samples = s->samples, *samples2, *la;
-    ChannelElement *cpe;
-    int i, j, chans, tag, start_ch;
-    const uint8_t *chan_map = aac_chan_configs[avctx->channels-1];
-    int chan_el_counter[4];
-
-    if(s->last_frame)
-        return 0;
-    if(data){
-        if(!s->psypp){
-            memcpy(s->samples + 1024 * avctx->channels, data, 1024 * avctx->channels * sizeof(s->samples[0]));
-        }else{
-            start_ch = 0;
-            samples2 = s->samples + 1024 * avctx->channels;
-            for(i = 0; i < chan_map[0]; i++){
-                tag = chan_map[i+1];
-                chans = tag == TYPE_CPE ? 2 : 1;
-                ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch, samples2 + start_ch, start_ch + i, chans);
-                start_ch += chans;
-            }
-        }
-    }
-    if(!avctx->frame_number){
-        memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
-        return 0;
-    }
-
-    init_put_bits(&s->pb, frame, buf_size*8);
-    if((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)){
-        put_bitstream_info(avctx, s, LIBAVCODEC_IDENT);
-    }
-    start_ch = 0;
-    memset(chan_el_counter, 0, sizeof(chan_el_counter));
-    for(i = 0; i < chan_map[0]; i++){
-        FFPsyWindowInfo wi[2];
-        tag = chan_map[i+1];
-        chans = tag == TYPE_CPE ? 2 : 1;
-        cpe = &s->cpe[i];
-        samples2 = samples + start_ch;
-        la = samples2 + 1024 * avctx->channels + start_ch;
-        if(!data) la = NULL;
-        s->lambda = 5e-7f;
-        for(j = 0; j < chans; j++){
-            IndividualChannelStream *ics = &cpe->ch[j].ics;
-            int k;
-            wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]);
-            ics->window_sequence[1] = ics->window_sequence[0];
-            ics->window_sequence[0] = wi[j].window_type[0];
-            ics->use_kb_window[1]   = ics->use_kb_window[0];
-            ics->use_kb_window[0]   = wi[j].window_shape;
-            ics->num_windows        = wi[j].num_windows;
-            ics->swb_sizes          = s->psy.bands    [ics->num_windows == 8];
-            ics->num_swb            = s->psy.num_bands[ics->num_windows == 8];
-            for(k = 0; k < ics->num_windows; k++)
-                ics->group_len[k] = wi[j].grouping[k];
-
-            s->cur_channel = start_ch + j;
-            apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
-            search_for_quantizers(avctx, s, &cpe->ch[j]);
-        }
-        cpe->common_window = 0;
-        if(chans > 1
-            && wi[0].window_type[0] == wi[1].window_type[0]
-            && wi[0].window_shape   == wi[1].window_shape){
-
-            cpe->common_window = 1;
-            for(j = 0; j < wi[0].num_windows; j++){
-                if(wi[0].grouping[j] != wi[1].grouping[j]){
-                    cpe->common_window = 0;
-                    break;
-                }
-            }
-        }
-//        search_for_ms(s, cpe, s->lambda);
-        adjust_frame_information(s, cpe, chans);
-        put_bits(&s->pb, 3, tag);
-        put_bits(&s->pb, 4, chan_el_counter[tag]++);
-        if(chans == 2){
-            put_bits(&s->pb, 1, cpe->common_window);
-            if(cpe->common_window){
-                put_ics_info(s, &cpe->ch[0].ics);
-                encode_ms_info(&s->pb, cpe);
-            }
-        }
-        for(j = 0; j < chans; j++){
-            s->cur_channel = start_ch + j;
-            ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]);
-            encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window);
-        }
-        start_ch += chans;
-    }
-
-    put_bits(&s->pb, 3, TYPE_END);
-    flush_put_bits(&s->pb);
-    avctx->frame_bits = put_bits_count(&s->pb);
-
-    if(!data)
-        s->last_frame = 1;
-    memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
-    return put_bits_count(&s->pb)>>3;
-}
-
-static av_cold int aac_encode_end(AVCodecContext *avctx)
-{
-    AACEncContext *s = avctx->priv_data;
-
-    ff_mdct_end(&s->mdct1024);
-    ff_mdct_end(&s->mdct128);
-    ff_psy_end(&s->psy);
-    ff_psy_preprocess_end(s->psypp);
-    av_freep(&s->samples);
-    av_freep(&s->cpe);
-    return 0;
-}
-
-AVCodec aac_encoder = {
-    "aac",
-    CODEC_TYPE_AUDIO,
-    CODEC_ID_AAC,
-    sizeof(AACEncContext),
-    aac_encode_init,
-    aac_encode_frame,
-    aac_encode_end,
-    .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
-    .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
-    .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
-};
+#endif /* AVCODEC_AACENC_H */



More information about the FFmpeg-soc mailing list