]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/aac.c
Export H264 profile and level in AVCodecContext.
[ffmpeg] / libavcodec / aac.c
index 235cce53941a9b93840af109d49b36b9e17a622a..0fbab7736735f689a4f432425ba117c76a12df0b 100644 (file)
 #include <math.h>
 #include <string.h>
 
+#if ARCH_ARM
+#   include "arm/aac.h"
+#endif
+
 union float754 {
     float f;
     uint32_t i;
@@ -101,10 +105,10 @@ union float754 {
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
 
+static uint32_t cbrt_tab[1<<13];
 
 static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
 {
-    static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0 };
     if (ac->tag_che_map[type][elem_id]) {
         return ac->tag_che_map[type][elem_id];
     }
@@ -153,6 +157,37 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
     }
 }
 
+/**
+ * Check for the channel element in the current channel position configuration.
+ * If it exists, make sure the appropriate element is allocated and map the
+ * channel order to match the internal FFmpeg channel layout.
+ *
+ * @param   che_pos current channel position configuration
+ * @param   type channel element type
+ * @param   id channel element id
+ * @param   channels count of the number of channels in the configuration
+ *
+ * @return  Returns error status. 0 - OK, !0 - error
+ */
+static int che_configure(AACContext *ac,
+                         enum ChannelPosition che_pos[4][MAX_ELEM_ID],
+                         int type, int id,
+                         int *channels)
+{
+    if (che_pos[type][id]) {
+        if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
+            return AVERROR(ENOMEM);
+        if (type != TYPE_CCE) {
+            ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret;
+            if (type == TYPE_CPE) {
+                ac->output_data[(*channels)++] = ac->che[type][id]->ch[1].ret;
+            }
+        }
+    } else
+        av_freep(&ac->che[type][id]);
+    return 0;
+}
+
 /**
  * Configure output channel order based on the current program configuration element.
  *
@@ -164,49 +199,52 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
 static int output_configure(AACContext *ac,
                             enum ChannelPosition che_pos[4][MAX_ELEM_ID],
                             enum ChannelPosition new_che_pos[4][MAX_ELEM_ID],
-                            int channel_config)
+                            int channel_config, enum OCStatus oc_type)
 {
     AVCodecContext *avctx = ac->avccontext;
-    int i, type, channels = 0;
+    int i, type, channels = 0, ret;
 
     memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
 
-    /* Allocate or free elements depending on if they are in the
-     * current program configuration.
-     *
-     * Set up default 1:1 output mapping.
-     *
-     * For a 5.1 stream the output order will be:
-     *    [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ]
-     */
-
-    for (i = 0; i < MAX_ELEM_ID; i++) {
-        for (type = 0; type < 4; type++) {
-            if (che_pos[type][i]) {
-                if (!ac->che[type][i] && !(ac->che[type][i] = av_mallocz(sizeof(ChannelElement))))
-                    return AVERROR(ENOMEM);
-                if (type != TYPE_CCE) {
-                    ac->output_data[channels++] = ac->che[type][i]->ch[0].ret;
-                    if (type == TYPE_CPE) {
-                        ac->output_data[channels++] = ac->che[type][i]->ch[1].ret;
-                    }
-                }
-            } else
-                av_freep(&ac->che[type][i]);
+    if (channel_config) {
+        for (i = 0; i < tags_per_config[channel_config]; i++) {
+            if ((ret = che_configure(ac, che_pos,
+                                     aac_channel_layout_map[channel_config - 1][i][0],
+                                     aac_channel_layout_map[channel_config - 1][i][1],
+                                     &channels)))
+                return ret;
         }
-    }
 
-    if (channel_config) {
         memset(ac->tag_che_map, 0,       4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
         ac->tags_mapped = 0;
+
+        avctx->channel_layout = aac_channel_layout[channel_config - 1];
     } else {
+        /* Allocate or free elements depending on if they are in the
+         * current program configuration.
+         *
+         * Set up default 1:1 output mapping.
+         *
+         * For a 5.1 stream the output order will be:
+         *    [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ]
+         */
+
+        for (i = 0; i < MAX_ELEM_ID; i++) {
+            for (type = 0; type < 4; type++) {
+                if ((ret = che_configure(ac, che_pos, type, i, &channels)))
+                    return ret;
+            }
+        }
+
         memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
         ac->tags_mapped = 4 * MAX_ELEM_ID;
+
+        avctx->channel_layout = 0;
     }
 
     avctx->channels = channels;
 
-    ac->output_configured = 1;
+    ac->output_configured = oc_type;
 
     return 0;
 }
@@ -357,7 +395,7 @@ static int decode_ga_specific_config(AACContext *ac, GetBitContext *gb,
         if ((ret = set_default_channel_config(ac, new_che_pos, channel_config)))
             return ret;
     }
-    if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config)))
+    if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config, OC_GLOBAL_HDR)))
         return ret;
 
     if (extension_flag) {
@@ -474,17 +512,17 @@ static av_cold int aac_decode_init(AVCodecContext *avccontext)
     avccontext->sample_fmt = SAMPLE_FMT_S16;
     avccontext->frame_size = 1024;
 
-    AAC_INIT_VLC_STATIC( 0, 144);
-    AAC_INIT_VLC_STATIC( 1, 114);
-    AAC_INIT_VLC_STATIC( 2, 188);
-    AAC_INIT_VLC_STATIC( 3, 180);
-    AAC_INIT_VLC_STATIC( 4, 172);
-    AAC_INIT_VLC_STATIC( 5, 140);
-    AAC_INIT_VLC_STATIC( 6, 168);
-    AAC_INIT_VLC_STATIC( 7, 114);
-    AAC_INIT_VLC_STATIC( 8, 262);
-    AAC_INIT_VLC_STATIC( 9, 248);
-    AAC_INIT_VLC_STATIC(10, 384);
+    AAC_INIT_VLC_STATIC( 0, 304);
+    AAC_INIT_VLC_STATIC( 1, 270);
+    AAC_INIT_VLC_STATIC( 2, 550);
+    AAC_INIT_VLC_STATIC( 3, 300);
+    AAC_INIT_VLC_STATIC( 4, 328);
+    AAC_INIT_VLC_STATIC( 5, 294);
+    AAC_INIT_VLC_STATIC( 6, 306);
+    AAC_INIT_VLC_STATIC( 7, 268);
+    AAC_INIT_VLC_STATIC( 8, 510);
+    AAC_INIT_VLC_STATIC( 9, 366);
+    AAC_INIT_VLC_STATIC(10, 462);
 
     dsputil_init(&ac->dsp, avccontext);
 
@@ -494,7 +532,7 @@ static av_cold int aac_decode_init(AVCodecContext *avccontext)
     // 32768 - Required to scale values to the correct range for the bias method
     //         for float to int16 conversion.
 
-    if (ac->dsp.float_to_int16 == ff_float_to_int16_c) {
+    if (ac->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
         ac->add_bias  = 385.0f;
         ac->sf_scale  = 1. / (-1024. * 32768.);
         ac->sf_offset = 0;
@@ -519,8 +557,16 @@ static av_cold int aac_decode_init(AVCodecContext *avccontext)
     // window initialization
     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);
+    ff_init_ff_sine_windows(10);
+    ff_init_ff_sine_windows( 7);
+
+    if (!cbrt_tab[(1<<13) - 1]) {
+        for (i = 0; i < 1<<13; i++) {
+            union float754 f;
+            f.f = cbrtf(i) * i;
+            cbrt_tab[i] = f.i;
+        }
+    }
 
     return 0;
 }
@@ -645,7 +691,7 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120],
     for (g = 0; g < ics->num_window_groups; g++) {
         int k = 0;
         while (k < ics->max_sfb) {
-            uint8_t sect_len = k;
+            uint8_t sect_end = k;
             int sect_len_incr;
             int sect_band_type = get_bits(gb, 4);
             if (sect_band_type == 12) {
@@ -653,17 +699,17 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120],
                 return -1;
             }
             while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1)
-                sect_len += sect_len_incr;
-            sect_len += sect_len_incr;
-            if (sect_len > ics->max_sfb) {
+                sect_end += sect_len_incr;
+            sect_end += sect_len_incr;
+            if (sect_end > ics->max_sfb) {
                 av_log(ac->avccontext, AV_LOG_ERROR,
                        "Number of bands (%d) exceeds limit (%d).\n",
-                       sect_len, ics->max_sfb);
+                       sect_end, ics->max_sfb);
                 return -1;
             }
-            for (; k < sect_len; k++) {
+            for (; k < sect_end; k++) {
                 band_type        [idx]   = sect_band_type;
-                band_type_run_end[idx++] = sect_len;
+                band_type_run_end[idx++] = sect_end;
             }
         }
     }
@@ -820,6 +866,74 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
     }
 }
 
+#ifndef VMUL2
+static inline float *VMUL2(float *dst, const float *v, unsigned idx,
+                           const float *scale)
+{
+    float s = *scale;
+    *dst++ = v[idx    & 15] * s;
+    *dst++ = v[idx>>4 & 15] * s;
+    return dst;
+}
+#endif
+
+#ifndef VMUL4
+static inline float *VMUL4(float *dst, const float *v, unsigned idx,
+                           const float *scale)
+{
+    float s = *scale;
+    *dst++ = v[idx    & 3] * s;
+    *dst++ = v[idx>>2 & 3] * s;
+    *dst++ = v[idx>>4 & 3] * s;
+    *dst++ = v[idx>>6 & 3] * s;
+    return dst;
+}
+#endif
+
+#ifndef VMUL2S
+static inline float *VMUL2S(float *dst, const float *v, unsigned idx,
+                            unsigned sign, const float *scale)
+{
+    union float754 s0, s1;
+
+    s0.f = s1.f = *scale;
+    s0.i ^= sign >> 1 << 31;
+    s1.i ^= sign      << 31;
+
+    *dst++ = v[idx    & 15] * s0.f;
+    *dst++ = v[idx>>4 & 15] * s1.f;
+
+    return dst;
+}
+#endif
+
+#ifndef VMUL4S
+static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
+                            unsigned sign, const float *scale)
+{
+    unsigned nz = idx >> 12;
+    union float754 s = { .f = *scale };
+    union float754 t;
+
+    t.i = s.i ^ (sign & 1<<31);
+    *dst++ = v[idx    & 3] * t.f;
+
+    sign <<= nz & 1; nz >>= 1;
+    t.i = s.i ^ (sign & 1<<31);
+    *dst++ = v[idx>>2 & 3] * t.f;
+
+    sign <<= nz & 1; nz >>= 1;
+    t.i = s.i ^ (sign & 1<<31);
+    *dst++ = v[idx>>4 & 3] * t.f;
+
+    sign <<= nz & 1; nz >>= 1;
+    t.i = s.i ^ (sign & 1<<31);
+    *dst++ = v[idx>>6 & 3] * t.f;
+
+    return dst;
+}
+#endif
+
 /**
  * Decode spectral data; reference: table 4.50.
  * Dequantize and scale spectral data; reference: 4.6.3.3.
@@ -833,7 +947,7 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
  * @return  Returns error status. 0 - OK, !0 - error
  */
 static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
-                                       GetBitContext *gb, float sf[120],
+                                       GetBitContext *gb, const float sf[120],
                                        int pulse_present, const Pulse *pulse,
                                        const IndividualChannelStream *ics,
                                        enum BandType band_type[120])
@@ -842,100 +956,228 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
     const int c = 1024 / ics->num_windows;
     const uint16_t *offsets = ics->swb_offset;
     float *coef_base = coef;
-    static const float sign_lookup[] = { 1.0f, -1.0f };
+    int err_idx;
 
     for (g = 0; g < ics->num_windows; g++)
         memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb]));
 
     for (g = 0; g < ics->num_window_groups; g++) {
+        unsigned g_len = ics->group_len[g];
+
         for (i = 0; i < ics->max_sfb; i++, idx++) {
-            const int cur_band_type = band_type[idx];
-            const int dim = cur_band_type >= FIRST_PAIR_BT ? 2 : 4;
-            const int is_cb_unsigned = IS_CODEBOOK_UNSIGNED(cur_band_type);
+            const unsigned cbt_m1 = band_type[idx] - 1;
+            float *cfo = coef + offsets[i];
+            int off_len = offsets[i + 1] - offsets[i];
             int group;
-            if (cur_band_type == ZERO_BT || cur_band_type == INTENSITY_BT2 || cur_band_type == INTENSITY_BT) {
-                for (group = 0; group < ics->group_len[g]; group++) {
-                    memset(coef + group * 128 + offsets[i], 0, (offsets[i + 1] - offsets[i]) * sizeof(float));
+
+            if (cbt_m1 >= INTENSITY_BT2 - 1) {
+                for (group = 0; group < g_len; group++, cfo+=128) {
+                    memset(cfo, 0, off_len * sizeof(float));
                 }
-            } else if (cur_band_type == NOISE_BT) {
-                for (group = 0; group < ics->group_len[g]; group++) {
+            } else if (cbt_m1 == NOISE_BT - 1) {
+                for (group = 0; group < g_len; group++, cfo+=128) {
                     float scale;
                     float band_energy;
-                    float *cf = coef + group * 128 + offsets[i];
-                    int len = offsets[i+1] - offsets[i];
 
-                    for (k = 0; k < len; k++) {
+                    for (k = 0; k < off_len; k++) {
                         ac->random_state  = lcg_random(ac->random_state);
-                        cf[k] = ac->random_state;
+                        cfo[k] = ac->random_state;
                     }
 
-                    band_energy = ac->dsp.scalarproduct_float(cf, cf, len);
+                    band_energy = ac->dsp.scalarproduct_float(cfo, cfo, off_len);
                     scale = sf[idx] / sqrtf(band_energy);
-                    ac->dsp.vector_fmul_scalar(cf, cf, scale, len);
+                    ac->dsp.vector_fmul_scalar(cfo, cfo, scale, off_len);
                 }
             } else {
-                for (group = 0; group < ics->group_len[g]; group++) {
-                    const float *vq[96];
-                    const float **vqp = vq;
-                    float *cf = coef + (group << 7) + offsets[i];
-                    int len = offsets[i + 1] - offsets[i];
-
-                    for (k = offsets[i]; k < offsets[i + 1]; k += dim) {
-                        const int index = get_vlc2(gb, vlc_spectral[cur_band_type - 1].table, 6, 3);
-                        const int coef_tmp_idx = (group << 7) + k;
-                        const float *vq_ptr;
-                        int j;
-                        if (index >= ff_aac_spectral_sizes[cur_band_type - 1]) {
-                            av_log(ac->avccontext, AV_LOG_ERROR,
-                                   "Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d\n",
-                                   cur_band_type - 1, index, ff_aac_spectral_sizes[cur_band_type - 1]);
-                            return -1;
-                        }
-                        vq_ptr = &ff_aac_codebook_vectors[cur_band_type - 1][index * dim];
-                        *vqp++ = vq_ptr;
-                        if (is_cb_unsigned) {
-                            if (vq_ptr[0])
-                                coef[coef_tmp_idx    ] = sign_lookup[get_bits1(gb)];
-                            if (vq_ptr[1])
-                                coef[coef_tmp_idx + 1] = sign_lookup[get_bits1(gb)];
-                            if (dim == 4) {
-                                if (vq_ptr[2])
-                                    coef[coef_tmp_idx + 2] = sign_lookup[get_bits1(gb)];
-                                if (vq_ptr[3])
-                                    coef[coef_tmp_idx + 3] = sign_lookup[get_bits1(gb)];
+                const float *vq = ff_aac_codebook_vector_vals[cbt_m1];
+                const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cbt_m1];
+                VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table;
+                const int cb_size = ff_aac_spectral_sizes[cbt_m1];
+                OPEN_READER(re, gb);
+
+                switch (cbt_m1 >> 1) {
+                case 0:
+                    for (group = 0; group < g_len; group++, cfo+=128) {
+                        float *cf = cfo;
+                        int len = off_len;
+
+                        do {
+                            int code;
+                            unsigned cb_idx;
+
+                            UPDATE_CACHE(re, gb);
+                            GET_VLC(code, re, gb, vlc_tab, 8, 2);
+
+                            if (code >= cb_size) {
+                                err_idx = code;
+                                goto err_cb_overflow;
                             }
-                            if (cur_band_type == ESC_BT) {
-                                for (j = 0; j < 2; j++) {
-                                    if (vq_ptr[j] == 64.0f) {
-                                        int n = 4;
-                                        /* The total length of escape_sequence must be < 22 bits according
-                                           to the specification (i.e. max is 11111111110xxxxxxxxxx). */
-                                        while (get_bits1(gb) && n < 15) n++;
-                                        if (n == 15) {
-                                            av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
-                                            return -1;
-                                        }
-                                        n = (1 << n) + get_bits(gb, n);
-                                        coef[coef_tmp_idx + j] *= cbrtf(n) * n;
-                                    } else
-                                        coef[coef_tmp_idx + j] *= vq_ptr[j];
-                                }
+
+                            cb_idx = cb_vector_idx[code];
+                            cf = VMUL4(cf, vq, cb_idx, sf + idx);
+                        } while (len -= 4);
+                    }
+                    break;
+
+                case 1:
+                    for (group = 0; group < g_len; group++, cfo+=128) {
+                        float *cf = cfo;
+                        int len = off_len;
+
+                        do {
+                            int code;
+                            unsigned nnz;
+                            unsigned cb_idx;
+                            uint32_t bits;
+
+                            UPDATE_CACHE(re, gb);
+                            GET_VLC(code, re, gb, vlc_tab, 8, 2);
+
+                            if (code >= cb_size) {
+                                err_idx = code;
+                                goto err_cb_overflow;
                             }
-                        }
+
+#if MIN_CACHE_BITS < 20
+                            UPDATE_CACHE(re, gb);
+#endif
+                            cb_idx = cb_vector_idx[code];
+                            nnz = cb_idx >> 8 & 15;
+                            bits = SHOW_UBITS(re, gb, nnz) << (32-nnz);
+                            LAST_SKIP_BITS(re, gb, nnz);
+                            cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx);
+                        } while (len -= 4);
                     }
+                    break;
+
+                case 2:
+                    for (group = 0; group < g_len; group++, cfo+=128) {
+                        float *cf = cfo;
+                        int len = off_len;
 
-                    if (is_cb_unsigned && cur_band_type != ESC_BT) {
-                        ac->dsp.vector_fmul_sv_scalar[dim>>2](
-                            cf, cf, vq, sf[idx], len);
-                    } else if (cur_band_type == ESC_BT) {
-                        ac->dsp.vector_fmul_scalar(cf, cf, sf[idx], len);
-                    } else {    /* !is_cb_unsigned */
-                        ac->dsp.sv_fmul_scalar[dim>>2](cf, vq, sf[idx], len);
+                        do {
+                            int code;
+                            unsigned cb_idx;
+
+                            UPDATE_CACHE(re, gb);
+                            GET_VLC(code, re, gb, vlc_tab, 8, 2);
+
+                            if (code >= cb_size) {
+                                err_idx = code;
+                                goto err_cb_overflow;
+                            }
+
+                            cb_idx = cb_vector_idx[code];
+                            cf = VMUL2(cf, vq, cb_idx, sf + idx);
+                        } while (len -= 2);
+                    }
+                    break;
+
+                case 3:
+                case 4:
+                    for (group = 0; group < g_len; group++, cfo+=128) {
+                        float *cf = cfo;
+                        int len = off_len;
+
+                        do {
+                            int code;
+                            unsigned nnz;
+                            unsigned cb_idx;
+                            unsigned sign;
+
+                            UPDATE_CACHE(re, gb);
+                            GET_VLC(code, re, gb, vlc_tab, 8, 2);
+
+                            if (code >= cb_size) {
+                                err_idx = code;
+                                goto err_cb_overflow;
+                            }
+
+                            cb_idx = cb_vector_idx[code];
+                            nnz = cb_idx >> 8 & 15;
+                            sign = SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12);
+                            LAST_SKIP_BITS(re, gb, nnz);
+                            cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx);
+                        } while (len -= 2);
+                    }
+                    break;
+
+                default:
+                    for (group = 0; group < g_len; group++, cfo+=128) {
+                        float *cf = cfo;
+                        uint32_t *icf = (uint32_t *) cf;
+                        int len = off_len;
+
+                        do {
+                            int code;
+                            unsigned nzt, nnz;
+                            unsigned cb_idx;
+                            uint32_t bits;
+                            int j;
+
+                            UPDATE_CACHE(re, gb);
+                            GET_VLC(code, re, gb, vlc_tab, 8, 2);
+
+                            if (!code) {
+                                *icf++ = 0;
+                                *icf++ = 0;
+                                continue;
+                            }
+
+                            if (code >= cb_size) {
+                                err_idx = code;
+                                goto err_cb_overflow;
+                            }
+
+                            cb_idx = cb_vector_idx[code];
+                            nnz = cb_idx >> 12;
+                            nzt = cb_idx >> 8;
+                            bits = SHOW_UBITS(re, gb, nnz) << (32-nnz);
+                            LAST_SKIP_BITS(re, gb, nnz);
+
+                            for (j = 0; j < 2; j++) {
+                                if (nzt & 1<<j) {
+                                    uint32_t b;
+                                    int n;
+                                    /* The total length of escape_sequence must be < 22 bits according
+                                       to the specification (i.e. max is 111111110xxxxxxxxxxxx). */
+                                    UPDATE_CACHE(re, gb);
+                                    b = GET_CACHE(re, gb);
+                                    b = 31 - av_log2(~b);
+
+                                    if (b > 8) {
+                                        av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
+                                        return -1;
+                                    }
+
+#if MIN_CACHE_BITS < 21
+                                    LAST_SKIP_BITS(re, gb, b + 1);
+                                    UPDATE_CACHE(re, gb);
+#else
+                                    SKIP_BITS(re, gb, b + 1);
+#endif
+                                    b += 4;
+                                    n = (1 << b) + SHOW_UBITS(re, gb, b);
+                                    LAST_SKIP_BITS(re, gb, b);
+                                    *icf++ = cbrt_tab[n] | (bits & 1<<31);
+                                    bits <<= 1;
+                                } else {
+                                    unsigned v = ((const uint32_t*)vq)[cb_idx & 15];
+                                    *icf++ = (bits & 1<<31) | v;
+                                    bits <<= !!v;
+                                }
+                                cb_idx >>= 4;
+                            }
+                        } while (len -= 2);
+
+                        ac->dsp.vector_fmul_scalar(cfo, cfo, sf[idx], off_len);
                     }
                 }
+
+                CLOSE_READER(re, gb);
             }
         }
-        coef += ics->group_len[g] << 7;
+        coef += g_len << 7;
     }
 
     if (pulse_present) {
@@ -955,6 +1197,12 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
         }
     }
     return 0;
+
+err_cb_overflow:
+    av_log(ac->avccontext, AV_LOG_ERROR,
+           "Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d\n",
+           band_type[idx], err_idx, ff_aac_spectral_sizes[band_type[idx]]);
+    return -1;
 }
 
 static av_always_inline float flt16_round(float pf)
@@ -1643,18 +1891,24 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
 
     size = ff_aac_parse_header(gb, &hdr_info);
     if (size > 0) {
-        if (!ac->output_configured && hdr_info.chan_config) {
+        if (ac->output_configured != OC_LOCKED && hdr_info.chan_config) {
             enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
             memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
             ac->m4ac.chan_config = hdr_info.chan_config;
             if (set_default_channel_config(ac, new_che_pos, hdr_info.chan_config))
                 return -7;
-            if (output_configure(ac, ac->che_pos, new_che_pos, 1))
+            if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME))
                 return -7;
+        } else if (ac->output_configured != OC_LOCKED) {
+            ac->output_configured = OC_NONE;
         }
+        if (ac->output_configured != OC_LOCKED)
+            ac->m4ac.sbr = -1;
         ac->m4ac.sample_rate     = hdr_info.sample_rate;
         ac->m4ac.sampling_index  = hdr_info.sampling_index;
         ac->m4ac.object_type     = hdr_info.object_type;
+        if (!ac->avccontext->sample_rate)
+            ac->avccontext->sample_rate = hdr_info.sample_rate;
         if (hdr_info.num_aac_frames == 1) {
             if (!hdr_info.crc_absent)
                 skip_bits(gb, 16);
@@ -1727,11 +1981,11 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
             memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
             if ((err = decode_pce(ac, new_che_pos, &gb)))
                 break;
-            if (ac->output_configured)
+            if (ac->output_configured > OC_TRIAL_PCE)
                 av_log(avccontext, AV_LOG_ERROR,
                        "Not evaluating a further program_config_element as this construct is dubious at best.\n");
             else
-                err = output_configure(ac, ac->che_pos, new_che_pos, 0);
+                err = output_configure(ac, ac->che_pos, new_che_pos, 0, OC_TRIAL_PCE);
             break;
         }
 
@@ -1771,6 +2025,9 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
 
     ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, 1024, avccontext->channels);
 
+    if (ac->output_configured)
+        ac->output_configured = OC_LOCKED;
+
     return buf_size;
 }
 
@@ -1802,4 +2059,5 @@ AVCodec aac_decoder = {
     .sample_fmts = (const enum SampleFormat[]) {
         SAMPLE_FMT_S16,SAMPLE_FMT_NONE
     },
+    .channel_layouts = aac_channel_layout,
 };