Browse code

AAC: Compress codebook tables and optimise sign bit handling

The codebooks each consist of small number of values repeated in
groups of 2 or 4. Storing the codebooks as a packed list of 2- or
4-bit indexes into a table reduces their size substantially (from 7.5k
to 1.5k), resulting in less cache pressure.

For the band types with sign bits in the bitstream, storing the number
and position of non-zero codebook values using a few bits avoids
multiple get_bits() calls and floating-point comparisons which gcc
handles miserably.

Some float/int type punning also avoids gcc brain damage.

Overall speedup 20-35% on Cortex-A8, 20% on Core i7.

Originally committed as revision 21188 to svn://svn.ffmpeg.org/ffmpeg/trunk

Måns Rullgård authored on 2010/01/14 01:46:28
Showing 3 changed files
... ...
@@ -101,7 +101,7 @@ union float754 {
101 101
 static VLC vlc_scalefactors;
102 102
 static VLC vlc_spectral[11];
103 103
 
104
-static float cbrt_tab[1<<13];
104
+static uint32_t cbrt_tab[1<<13];
105 105
 
106 106
 static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
107 107
 {
... ...
@@ -556,9 +556,13 @@ static av_cold int aac_decode_init(AVCodecContext *avccontext)
556 556
     ff_init_ff_sine_windows(10);
557 557
     ff_init_ff_sine_windows( 7);
558 558
 
559
-    if (!cbrt_tab[(1<<13) - 1])
560
-        for (i = 0; i < 1<<13; i++)
561
-            cbrt_tab[i] = cbrtf(i) * i;
559
+    if (!cbrt_tab[(1<<13) - 1]) {
560
+        for (i = 0; i < 1<<13; i++) {
561
+            union float754 f;
562
+            f.f = cbrtf(i) * i;
563
+            cbrt_tab[i] = f.i;
564
+        }
565
+    }
562 566
 
563 567
     return 0;
564 568
 }
... ...
@@ -858,6 +862,66 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
858 858
     }
859 859
 }
860 860
 
861
+static inline float *VMUL2(float *dst, const float *v, unsigned idx,
862
+                           const float *scale)
863
+{
864
+    float s = *scale;
865
+    *dst++ = v[idx    & 15] * s;
866
+    *dst++ = v[idx>>4 & 15] * s;
867
+    return dst;
868
+}
869
+
870
+static inline float *VMUL4(float *dst, const float *v, unsigned idx,
871
+                           const float *scale)
872
+{
873
+    float s = *scale;
874
+    *dst++ = v[idx    & 3] * s;
875
+    *dst++ = v[idx>>2 & 3] * s;
876
+    *dst++ = v[idx>>4 & 3] * s;
877
+    *dst++ = v[idx>>6 & 3] * s;
878
+    return dst;
879
+}
880
+
881
+static inline float *VMUL2S(float *dst, const float *v, unsigned idx,
882
+                            unsigned sign, const float *scale)
883
+{
884
+    union float754 s0, s1;
885
+
886
+    s0.f = s1.f = *scale;
887
+    s0.i ^= sign >> 1 << 31;
888
+    s1.i ^= sign      << 31;
889
+
890
+    *dst++ = v[idx    & 15] * s0.f;
891
+    *dst++ = v[idx>>4 & 15] * s1.f;
892
+
893
+    return dst;
894
+}
895
+
896
+static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
897
+                            unsigned sign, const float *scale)
898
+{
899
+    unsigned nz = idx >> 12;
900
+    union float754 s = { .f = *scale };
901
+    union float754 t;
902
+
903
+    t.i = s.i ^ (sign & 1<<31);
904
+    *dst++ = v[idx    & 3] * t.f;
905
+
906
+    sign <<= nz & 1; nz >>= 1;
907
+    t.i = s.i ^ (sign & 1<<31);
908
+    *dst++ = v[idx>>2 & 3] * t.f;
909
+
910
+    sign <<= nz & 1; nz >>= 1;
911
+    t.i = s.i ^ (sign & 1<<31);
912
+    *dst++ = v[idx>>4 & 3] * t.f;
913
+
914
+    sign <<= nz & 1; nz >>= 1;
915
+    t.i = s.i ^ (sign & 1<<31);
916
+    *dst++ = v[idx>>6 & 3] * t.f;
917
+
918
+    return dst;
919
+}
920
+
861 921
 /**
862 922
  * Decode spectral data; reference: table 4.50.
863 923
  * Dequantize and scale spectral data; reference: 4.6.3.3.
... ...
@@ -880,7 +944,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
880 880
     const int c = 1024 / ics->num_windows;
881 881
     const uint16_t *offsets = ics->swb_offset;
882 882
     float *coef_base = coef;
883
-    static const float sign_lookup[] = { 1.0f, -1.0f };
883
+    int err_idx;
884 884
 
885 885
     for (g = 0; g < ics->num_windows; g++)
886 886
         memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb]));
... ...
@@ -888,8 +952,6 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
888 888
     for (g = 0; g < ics->num_window_groups; g++) {
889 889
         for (i = 0; i < ics->max_sfb; i++, idx++) {
890 890
             const int cur_band_type = band_type[idx];
891
-            const int dim = cur_band_type >= FIRST_PAIR_BT ? 2 : 4;
892
-            const int is_cb_unsigned = IS_CODEBOOK_UNSIGNED(cur_band_type);
893 891
             int group;
894 892
             if (cur_band_type == ZERO_BT || cur_band_type == INTENSITY_BT2 || cur_band_type == INTENSITY_BT) {
895 893
                 for (group = 0; group < ics->group_len[g]; group++) {
... ...
@@ -912,63 +974,128 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
912 912
                     ac->dsp.vector_fmul_scalar(cf, cf, scale, len);
913 913
                 }
914 914
             } else {
915
+                const float *vq = ff_aac_codebook_vector_vals[cur_band_type-1];
916
+                const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cur_band_type-1];
917
+                VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cur_band_type - 1].table;
918
+                const int cb_size = ff_aac_spectral_sizes[cur_band_type-1];
919
+
915 920
                 for (group = 0; group < ics->group_len[g]; group++) {
916
-                    const float *vq[96];
917
-                    const float **vqp = vq;
918 921
                     float *cf = coef + (group << 7) + offsets[i];
922
+                    uint32_t *icf = (uint32_t *) cf;
919 923
                     int len = offsets[i + 1] - offsets[i];
920 924
 
921
-                    for (k = offsets[i]; k < offsets[i + 1]; k += dim) {
922
-                        const int index = get_vlc2(gb, vlc_spectral[cur_band_type - 1].table, 6, 3);
923
-                        const int coef_tmp_idx = (group << 7) + k;
924
-                        const float *vq_ptr;
925
-                        int j;
926
-                        if (index >= ff_aac_spectral_sizes[cur_band_type - 1]) {
927
-                            av_log(ac->avccontext, AV_LOG_ERROR,
928
-                                   "Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d\n",
929
-                                   cur_band_type - 1, index, ff_aac_spectral_sizes[cur_band_type - 1]);
930
-                            return -1;
931
-                        }
932
-                        vq_ptr = &ff_aac_codebook_vectors[cur_band_type - 1][index * dim];
933
-                        *vqp++ = vq_ptr;
934
-                        if (is_cb_unsigned) {
935
-                            if (vq_ptr[0])
936
-                                coef[coef_tmp_idx    ] = sign_lookup[get_bits1(gb)];
937
-                            if (vq_ptr[1])
938
-                                coef[coef_tmp_idx + 1] = sign_lookup[get_bits1(gb)];
939
-                            if (dim == 4) {
940
-                                if (vq_ptr[2])
941
-                                    coef[coef_tmp_idx + 2] = sign_lookup[get_bits1(gb)];
942
-                                if (vq_ptr[3])
943
-                                    coef[coef_tmp_idx + 3] = sign_lookup[get_bits1(gb)];
925
+                    switch ((cur_band_type-1) >> 1) {
926
+                    case 0:
927
+                        do {
928
+                            const int index = get_vlc2(gb, vlc_tab, 6, 3);
929
+                            unsigned cb_idx;
930
+
931
+                            if (index >= cb_size) {
932
+                                err_idx = index;
933
+                                goto err_cb_overflow;
934
+                            }
935
+
936
+                            cb_idx = cb_vector_idx[index];
937
+                            cf = VMUL4(cf, vq, cb_idx, sf + idx);
938
+                        } while (len -= 4);
939
+                        break;
940
+                    case 1:
941
+                        do {
942
+                            const int index = get_vlc2(gb, vlc_tab, 6, 3);
943
+                            unsigned nnz;
944
+                            unsigned cb_idx;
945
+                            uint32_t bits;
946
+
947
+                            if (index >= cb_size) {
948
+                                err_idx = index;
949
+                                goto err_cb_overflow;
950
+                            }
951
+
952
+                            cb_idx = cb_vector_idx[index];
953
+                            nnz = cb_idx >> 8 & 15;
954
+                            bits = get_bits(gb, nnz) << (32-nnz);
955
+                            cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx);
956
+                        } while (len -= 4);
957
+                        break;
958
+                    case 2:
959
+                        do {
960
+                            const int index = get_vlc2(gb, vlc_tab, 6, 3);
961
+                            unsigned cb_idx;
962
+
963
+                            if (index >= cb_size) {
964
+                                err_idx = index;
965
+                                goto err_cb_overflow;
944 966
                             }
945
-                            if (cur_band_type == ESC_BT) {
946
-                                for (j = 0; j < 2; j++) {
947
-                                    if (vq_ptr[j] == 64.0f) {
948
-                                        int n = 4;
949
-                                        /* The total length of escape_sequence must be < 22 bits according
950
-                                           to the specification (i.e. max is 111111110xxxxxxxxxxxx). */
951
-                                        while (get_bits1(gb) && n < 13) n++;
952
-                                        if (n == 13) {
953
-                                            av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
954
-                                            return -1;
955
-                                        }
956
-                                        n = (1 << n) + get_bits(gb, n);
957
-                                        coef[coef_tmp_idx + j] *= cbrt_tab[n];
958
-                                    } else
959
-                                        coef[coef_tmp_idx + j] *= vq_ptr[j];
967
+
968
+                            cb_idx = cb_vector_idx[index];
969
+                            cf = VMUL2(cf, vq, cb_idx, sf + idx);
970
+                        } while (len -= 2);
971
+                        break;
972
+                    case 3:
973
+                    case 4:
974
+                        do {
975
+                            const int index = get_vlc2(gb, vlc_tab, 6, 3);
976
+                            unsigned nnz;
977
+                            unsigned cb_idx;
978
+                            unsigned sign;
979
+
980
+                            if (index >= cb_size) {
981
+                                err_idx = index;
982
+                                goto err_cb_overflow;
983
+                            }
984
+
985
+                            cb_idx = cb_vector_idx[index];
986
+                            nnz = cb_idx >> 8 & 15;
987
+                            sign = get_bits(gb, nnz) << (cb_idx >> 12);
988
+                            cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx);
989
+                        } while (len -= 2);
990
+                        break;
991
+                    default:
992
+                        for (k = 0; k < len; k += 2, icf += 2) {
993
+                            const int index = get_vlc2(gb, vlc_tab, 6, 3);
994
+                            unsigned nzt, nnz;
995
+                            unsigned cb_idx;
996
+                            uint32_t bits;
997
+                            int j;
998
+
999
+                            if (!index) {
1000
+                                icf[0] = icf[1] = 0;
1001
+                                continue;
1002
+                            }
1003
+
1004
+                            if (index >= cb_size) {
1005
+                                err_idx = index;
1006
+                                goto err_cb_overflow;
1007
+                            }
1008
+
1009
+                            cb_idx = cb_vector_idx[index];
1010
+                            nnz = cb_idx >> 12;
1011
+                            nzt = cb_idx >> 8;
1012
+                            bits = get_bits(gb, nnz) << (32-nnz);
1013
+
1014
+                            for (j = 0; j < 2; j++) {
1015
+                                if (nzt & 1<<j) {
1016
+                                    int n = 4;
1017
+                                    /* The total length of escape_sequence must be < 22 bits according
1018
+                                       to the specification (i.e. max is 111111110xxxxxxxxxxxx). */
1019
+                                    while (get_bits1(gb) && n < 13) n++;
1020
+                                    if (n == 13) {
1021
+                                        av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
1022
+                                        return -1;
1023
+                                    }
1024
+                                    n = (1 << n) + get_bits(gb, n);
1025
+                                    icf[j] = cbrt_tab[n] | (bits & 1<<31);
1026
+                                    bits <<= 1;
1027
+                                } else {
1028
+                                    unsigned v = ((const uint32_t*)vq)[cb_idx & 15];
1029
+                                    icf[j] = (bits & 1<<31) | v;
1030
+                                    bits <<= !!v;
960 1031
                                 }
1032
+                                cb_idx >>= 4;
961 1033
                             }
962 1034
                         }
963
-                    }
964 1035
 
965
-                    if (is_cb_unsigned && cur_band_type != ESC_BT) {
966
-                        ac->dsp.vector_fmul_sv_scalar[dim>>2](
967
-                            cf, cf, vq, sf[idx], len);
968
-                    } else if (cur_band_type == ESC_BT) {
969 1036
                         ac->dsp.vector_fmul_scalar(cf, cf, sf[idx], len);
970
-                    } else {    /* !is_cb_unsigned */
971
-                        ac->dsp.sv_fmul_scalar[dim>>2](cf, vq, sf[idx], len);
972 1037
                     }
973 1038
                 }
974 1039
             }
... ...
@@ -993,6 +1120,12 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
993 993
         }
994 994
     }
995 995
     return 0;
996
+
997
+err_cb_overflow:
998
+    av_log(ac->avccontext, AV_LOG_ERROR,
999
+           "Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d\n",
1000
+           band_type[idx], err_idx, ff_aac_spectral_sizes[band_type[idx]]);
1001
+    return -1;
996 1002
 }
997 1003
 
998 1004
 static av_always_inline float flt16_round(float pf)
... ...
@@ -899,6 +899,192 @@ const float * const ff_aac_codebook_vectors[] = {
899 899
     codebook_vector8, codebook_vector10,
900 900
 };
901 901
 
902
+static const float codebook_vector0_vals[] = {
903
+   -1.0000000,  0.0000000,  1.0000000
904
+};
905
+
906
+static const float codebook_vector2_vals[] = {
907
+    0.0000000,  1.0000000,  2.5198421,
908
+};
909
+
910
+/*
911
+ * bits  0:1, 2:3, 4:5, 6:7  index into _vals array
912
+ *       8:11                number of non-zero values
913
+ *      12:15                bit mask of non-zero values
914
+ */
915
+static const uint16_t codebook_vector02_idx[] = {
916
+    0x0000, 0x8140, 0x8180, 0x4110, 0xc250, 0xc290, 0x4120, 0xc260, 0xc2a0,
917
+    0x2104, 0xa244, 0xa284, 0x6214, 0xe354, 0xe394, 0x6224, 0xe364, 0xe3a4,
918
+    0x2108, 0xa248, 0xa288, 0x6218, 0xe358, 0xe398, 0x6228, 0xe368, 0xe3a8,
919
+    0x1101, 0x9241, 0x9281, 0x5211, 0xd351, 0xd391, 0x5221, 0xd361, 0xd3a1,
920
+    0x3205, 0xb345, 0xb385, 0x7315, 0xf455, 0xf495, 0x7325, 0xf465, 0xf4a5,
921
+    0x3209, 0xb349, 0xb389, 0x7319, 0xf459, 0xf499, 0x7329, 0xf469, 0xf4a9,
922
+    0x1102, 0x9242, 0x9282, 0x5212, 0xd352, 0xd392, 0x5222, 0xd362, 0xd3a2,
923
+    0x3206, 0xb346, 0xb386, 0x7316, 0xf456, 0xf496, 0x7326, 0xf466, 0xf4a6,
924
+    0x320a, 0xb34a, 0xb38a, 0x731a, 0xf45a, 0xf49a, 0x732a, 0xf46a, 0xf4aa,
925
+};
926
+
927
+static const float codebook_vector4_vals[] = {
928
+   -6.3496042, -4.3267487,
929
+   -2.5198421, -1.0000000,
930
+    0.0000000,  1.0000000,
931
+    2.5198421,  4.3267487,
932
+    6.3496042,
933
+};
934
+
935
+/*
936
+ * bits  0:3, 4:7  index into _vals array
937
+ */
938
+static const uint16_t codebook_vector4_idx[] = {
939
+    0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080,
940
+    0x0001, 0x0011, 0x0021, 0x0031, 0x0041, 0x0051, 0x0061, 0x0071, 0x0081,
941
+    0x0002, 0x0012, 0x0022, 0x0032, 0x0042, 0x0052, 0x0062, 0x0072, 0x0082,
942
+    0x0003, 0x0013, 0x0023, 0x0033, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083,
943
+    0x0004, 0x0014, 0x0024, 0x0034, 0x0044, 0x0054, 0x0064, 0x0074, 0x0084,
944
+    0x0005, 0x0015, 0x0025, 0x0035, 0x0045, 0x0055, 0x0065, 0x0075, 0x0085,
945
+    0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0076, 0x0086,
946
+    0x0007, 0x0017, 0x0027, 0x0037, 0x0047, 0x0057, 0x0067, 0x0077, 0x0087,
947
+    0x0008, 0x0018, 0x0028, 0x0038, 0x0048, 0x0058, 0x0068, 0x0078, 0x0088,
948
+};
949
+
950
+static const float codebook_vector6_vals[] = {
951
+    0.0000000,  1.0000000,  2.5198421,  4.3267487,
952
+    6.3496042,  8.5498797, 10.9027236, 13.3905183,
953
+};
954
+
955
+/*
956
+ * bits  0:3, 4:7  index into _vals array
957
+ *       8:11      number of non-zero values
958
+ *      12:15      1: only second value non-zero
959
+ *                 0: other cases
960
+ */
961
+static const uint16_t codebook_vector6_idx[] = {
962
+    0x0000, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170,
963
+    0x1101, 0x0211, 0x0221, 0x0231, 0x0241, 0x0251, 0x0261, 0x0271,
964
+    0x1102, 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262, 0x0272,
965
+    0x1103, 0x0213, 0x0223, 0x0233, 0x0243, 0x0253, 0x0263, 0x0273,
966
+    0x1104, 0x0214, 0x0224, 0x0234, 0x0244, 0x0254, 0x0264, 0x0274,
967
+    0x1105, 0x0215, 0x0225, 0x0235, 0x0245, 0x0255, 0x0265, 0x0275,
968
+    0x1106, 0x0216, 0x0226, 0x0236, 0x0246, 0x0256, 0x0266, 0x0276,
969
+    0x1107, 0x0217, 0x0227, 0x0237, 0x0247, 0x0257, 0x0267, 0x0277,
970
+};
971
+
972
+static const float codebook_vector8_vals[] = {
973
+     0.0000000,  1.0000000,
974
+     2.5198421,  4.3267487,
975
+     6.3496042,  8.5498797,
976
+    10.9027236, 13.3905183,
977
+    16.0000000, 18.7207544,
978
+    21.5443469, 24.4637810,
979
+    27.4731418,
980
+};
981
+
982
+/*
983
+ * bits  0:3, 4:7  index into _vals array
984
+ *       8:11      number of non-zero values
985
+ *      12:15      1: only second value non-zero
986
+ *                 0: other cases
987
+ */
988
+static const uint16_t codebook_vector8_idx[] = {
989
+  0x0000, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160,
990
+  0x0170, 0x0180, 0x0190, 0x01a0, 0x01b0, 0x01c0,
991
+  0x1101, 0x0211, 0x0221, 0x0231, 0x0241, 0x0251, 0x0261,
992
+  0x0271, 0x0281, 0x0291, 0x02a1, 0x02b1, 0x02c1,
993
+  0x1102, 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262,
994
+  0x0272, 0x0282, 0x0292, 0x02a2, 0x02b2, 0x02c2,
995
+  0x1103, 0x0213, 0x0223, 0x0233, 0x0243, 0x0253, 0x0263,
996
+  0x0273, 0x0283, 0x0293, 0x02a3, 0x02b3, 0x02c3,
997
+  0x1104, 0x0214, 0x0224, 0x0234, 0x0244, 0x0254, 0x0264,
998
+  0x0274, 0x0284, 0x0294, 0x02a4, 0x02b4, 0x02c4,
999
+  0x1105, 0x0215, 0x0225, 0x0235, 0x0245, 0x0255, 0x0265,
1000
+  0x0275, 0x0285, 0x0295, 0x02a5, 0x02b5, 0x02c5,
1001
+  0x1106, 0x0216, 0x0226, 0x0236, 0x0246, 0x0256, 0x0266,
1002
+  0x0276, 0x0286, 0x0296, 0x02a6, 0x02b6, 0x02c6,
1003
+  0x1107, 0x0217, 0x0227, 0x0237, 0x0247, 0x0257, 0x0267,
1004
+  0x0277, 0x0287, 0x0297, 0x02a7, 0x02b7, 0x02c7,
1005
+  0x1108, 0x0218, 0x0228, 0x0238, 0x0248, 0x0258, 0x0268,
1006
+  0x0278, 0x0288, 0x0298, 0x02a8, 0x02b8, 0x02c8,
1007
+  0x1109, 0x0219, 0x0229, 0x0239, 0x0249, 0x0259, 0x0269,
1008
+  0x0279, 0x0289, 0x0299, 0x02a9, 0x02b9, 0x02c9,
1009
+  0x110a, 0x021a, 0x022a, 0x023a, 0x024a, 0x025a, 0x026a,
1010
+  0x027a, 0x028a, 0x029a, 0x02aa, 0x02ba, 0x02ca,
1011
+  0x110b, 0x021b, 0x022b, 0x023b, 0x024b, 0x025b, 0x026b,
1012
+  0x027b, 0x028b, 0x029b, 0x02ab, 0x02bb, 0x02cb,
1013
+  0x110c, 0x021c, 0x022c, 0x023c, 0x024c, 0x025c, 0x026c,
1014
+  0x027c, 0x028c, 0x029c, 0x02ac, 0x02bc, 0x02cc,
1015
+};
1016
+
1017
+static const float codebook_vector10_vals[] = {
1018
+     0.0000000,  1.0000000,
1019
+     2.5198421,  4.3267487,
1020
+     6.3496042,  8.5498797,
1021
+    10.9027236, 13.3905183,
1022
+    16.0000000, 18.7207544,
1023
+    21.5443469, 24.4637810,
1024
+    27.4731418, 30.5673509,
1025
+    33.7419917, 36.9931811,
1026
+};
1027
+
1028
+/*
1029
+ * bits  0:3, 4:7  index into _vals array
1030
+ *       8:9       bit mask of escape-coded entries
1031
+ *      12:15      number of non-zero values
1032
+ */
1033
+static const uint16_t codebook_vector10_idx[] = {
1034
+    0x0000, 0x1010, 0x1020, 0x1030, 0x1040, 0x1050, 0x1060, 0x1070,
1035
+    0x1080, 0x1090, 0x10a0, 0x10b0, 0x10c0, 0x10d0, 0x10e0, 0x10f0, 0x1200,
1036
+    0x1001, 0x2011, 0x2021, 0x2031, 0x2041, 0x2051, 0x2061, 0x2071,
1037
+    0x2081, 0x2091, 0x20a1, 0x20b1, 0x20c1, 0x20d1, 0x20e1, 0x20f1, 0x2201,
1038
+    0x1002, 0x2012, 0x2022, 0x2032, 0x2042, 0x2052, 0x2062, 0x2072,
1039
+    0x2082, 0x2092, 0x20a2, 0x20b2, 0x20c2, 0x20d2, 0x20e2, 0x20f2, 0x2202,
1040
+    0x1003, 0x2013, 0x2023, 0x2033, 0x2043, 0x2053, 0x2063, 0x2073,
1041
+    0x2083, 0x2093, 0x20a3, 0x20b3, 0x20c3, 0x20d3, 0x20e3, 0x20f3, 0x2203,
1042
+    0x1004, 0x2014, 0x2024, 0x2034, 0x2044, 0x2054, 0x2064, 0x2074,
1043
+    0x2084, 0x2094, 0x20a4, 0x20b4, 0x20c4, 0x20d4, 0x20e4, 0x20f4, 0x2204,
1044
+    0x1005, 0x2015, 0x2025, 0x2035, 0x2045, 0x2055, 0x2065, 0x2075,
1045
+    0x2085, 0x2095, 0x20a5, 0x20b5, 0x20c5, 0x20d5, 0x20e5, 0x20f5, 0x2205,
1046
+    0x1006, 0x2016, 0x2026, 0x2036, 0x2046, 0x2056, 0x2066, 0x2076,
1047
+    0x2086, 0x2096, 0x20a6, 0x20b6, 0x20c6, 0x20d6, 0x20e6, 0x20f6, 0x2206,
1048
+    0x1007, 0x2017, 0x2027, 0x2037, 0x2047, 0x2057, 0x2067, 0x2077,
1049
+    0x2087, 0x2097, 0x20a7, 0x20b7, 0x20c7, 0x20d7, 0x20e7, 0x20f7, 0x2207,
1050
+    0x1008, 0x2018, 0x2028, 0x2038, 0x2048, 0x2058, 0x2068, 0x2078,
1051
+    0x2088, 0x2098, 0x20a8, 0x20b8, 0x20c8, 0x20d8, 0x20e8, 0x20f8, 0x2208,
1052
+    0x1009, 0x2019, 0x2029, 0x2039, 0x2049, 0x2059, 0x2069, 0x2079,
1053
+    0x2089, 0x2099, 0x20a9, 0x20b9, 0x20c9, 0x20d9, 0x20e9, 0x20f9, 0x2209,
1054
+    0x100a, 0x201a, 0x202a, 0x203a, 0x204a, 0x205a, 0x206a, 0x207a,
1055
+    0x208a, 0x209a, 0x20aa, 0x20ba, 0x20ca, 0x20da, 0x20ea, 0x20fa, 0x220a,
1056
+    0x100b, 0x201b, 0x202b, 0x203b, 0x204b, 0x205b, 0x206b, 0x207b,
1057
+    0x208b, 0x209b, 0x20ab, 0x20bb, 0x20cb, 0x20db, 0x20eb, 0x20fb, 0x220b,
1058
+    0x100c, 0x201c, 0x202c, 0x203c, 0x204c, 0x205c, 0x206c, 0x207c,
1059
+    0x208c, 0x209c, 0x20ac, 0x20bc, 0x20cc, 0x20dc, 0x20ec, 0x20fc, 0x220c,
1060
+    0x100d, 0x201d, 0x202d, 0x203d, 0x204d, 0x205d, 0x206d, 0x207d,
1061
+    0x208d, 0x209d, 0x20ad, 0x20bd, 0x20cd, 0x20dd, 0x20ed, 0x20fd, 0x220d,
1062
+    0x100e, 0x201e, 0x202e, 0x203e, 0x204e, 0x205e, 0x206e, 0x207e,
1063
+    0x208e, 0x209e, 0x20ae, 0x20be, 0x20ce, 0x20de, 0x20ee, 0x20fe, 0x220e,
1064
+    0x100f, 0x201f, 0x202f, 0x203f, 0x204f, 0x205f, 0x206f, 0x207f,
1065
+    0x208f, 0x209f, 0x20af, 0x20bf, 0x20cf, 0x20df, 0x20ef, 0x20ff, 0x220f,
1066
+    0x1100, 0x2110, 0x2120, 0x2130, 0x2140, 0x2150, 0x2160, 0x2170,
1067
+    0x2180, 0x2190, 0x21a0, 0x21b0, 0x21c0, 0x21d0, 0x21e0, 0x21f0, 0x2300,
1068
+};
1069
+
1070
+const float *const ff_aac_codebook_vector_vals[] = {
1071
+    codebook_vector0_vals, codebook_vector0_vals,
1072
+    codebook_vector2_vals, codebook_vector2_vals,
1073
+    codebook_vector4_vals, codebook_vector4_vals,
1074
+    codebook_vector6_vals, codebook_vector6_vals,
1075
+    codebook_vector8_vals, codebook_vector8_vals,
1076
+    codebook_vector10_vals,
1077
+};
1078
+
1079
+const uint16_t *const ff_aac_codebook_vector_idx[] = {
1080
+    codebook_vector02_idx, codebook_vector02_idx,
1081
+    codebook_vector02_idx, codebook_vector02_idx,
1082
+    codebook_vector4_idx,  codebook_vector4_idx,
1083
+    codebook_vector6_idx,  codebook_vector6_idx,
1084
+    codebook_vector8_idx,  codebook_vector8_idx,
1085
+    codebook_vector10_idx,
1086
+};
1087
+
902 1088
 /* @name swb_offsets
903 1089
  * Sample offset into the window indicating the beginning of a scalefactor
904 1090
  * window band
... ...
@@ -64,6 +64,8 @@ extern const uint8_t  * const ff_aac_spectral_bits [11];
64 64
 extern const uint16_t  ff_aac_spectral_sizes[11];
65 65
 
66 66
 extern const float *ff_aac_codebook_vectors[];
67
+extern const float *ff_aac_codebook_vector_vals[];
68
+extern const uint16_t *ff_aac_codebook_vector_idx[];
67 69
 
68 70
 extern const uint16_t * const ff_swb_offset_1024[13];
69 71
 extern const uint16_t * const ff_swb_offset_128 [13];