]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/atrac3plus.c
avcodec/atrac3plus: Make tables used to initialize VLCs smaller
[ffmpeg] / libavcodec / atrac3plus.c
index 3e3bba801b91fb8c9c2ff62bd9faf5897f1dfa09..c93d42ab39c8353774e49efe40f64ec5970f514a 100644 (file)
@@ -51,9 +51,7 @@ static av_cold void build_canonical_huff(const uint8_t *cb, const uint8_t *xlat,
                                          int *tab_offset, VLC *out_vlc)
 {
     int i, b;
-    uint16_t codes[256];
     uint8_t bits[256];
-    unsigned code = 0;
     int index = 0;
     int min_len = *cb++; // get shortest codeword length
     int max_len = *cb++; // get longest  codeword length
@@ -62,17 +60,15 @@ static av_cold void build_canonical_huff(const uint8_t *cb, const uint8_t *xlat,
         for (i = *cb++; i > 0; i--) {
             av_assert0(index < 256);
             bits[index]  = b;
-            codes[index] = code++;
             index++;
         }
-        code <<= 1;
     }
 
     out_vlc->table = &tables_data[*tab_offset];
     out_vlc->table_allocated = 1 << max_len;
 
-    ff_init_vlc_sparse(out_vlc, max_len, index, bits, 1, 1, codes, 2, 2,
-                       xlat, 1, 1, INIT_VLC_USE_NEW_STATIC);
+    ff_init_vlc_from_lengths(out_vlc, max_len, index, bits, 1,
+                             xlat, 1, 1, 0, INIT_VLC_USE_NEW_STATIC, NULL);
 
     *tab_offset += 1 << max_len;
 }
@@ -81,49 +77,26 @@ av_cold void ff_atrac3p_init_vlcs(void)
 {
     int i, wl_vlc_offs, ct_vlc_offs, sf_vlc_offs, tab_offset;
 
-    static const int wl_nb_bits[4]  = { 2, 3, 5, 5 };
-    static const int wl_nb_codes[4] = { 3, 5, 8, 8 };
-    static const uint8_t * const wl_bits[4] = {
-        atrac3p_wl_huff_bits1, atrac3p_wl_huff_bits2,
-        atrac3p_wl_huff_bits3, atrac3p_wl_huff_bits4
-    };
-    static const uint8_t * const wl_codes[4] = {
-        atrac3p_wl_huff_code1, atrac3p_wl_huff_code2,
-        atrac3p_wl_huff_code3, atrac3p_wl_huff_code4
-    };
-    static const uint8_t * const wl_xlats[4] = {
-        atrac3p_wl_huff_xlat1, atrac3p_wl_huff_xlat2, NULL, NULL
+    static const uint8_t wl_nb_bits[4]  = { 2, 3, 5, 5 };
+    static const uint8_t wl_nb_codes[4] = { 3, 5, 8, 8 };
+    static const uint8_t (*const wl_huffs[4])[2] = {
+        atrac3p_wl_huff1, atrac3p_wl_huff2,
+        atrac3p_wl_huff3, atrac3p_wl_huff4
     };
 
-    static const int ct_nb_bits[4]  = { 3, 4, 4, 4 };
-    static const int ct_nb_codes[4] = { 4, 8, 8, 8 };
-    static const uint8_t * const ct_bits[4]  = {
-        atrac3p_ct_huff_bits1, atrac3p_ct_huff_bits2,
-        atrac3p_ct_huff_bits2, atrac3p_ct_huff_bits3
-    };
-    static const uint8_t * const ct_codes[4] = {
-        atrac3p_ct_huff_code1, atrac3p_ct_huff_code2,
-        atrac3p_ct_huff_code2, atrac3p_ct_huff_code3
-    };
-    static const uint8_t * const ct_xlats[4] = {
-        NULL, NULL, atrac3p_ct_huff_xlat1, NULL
+    static const uint8_t ct_nb_bits[4]  = { 3, 4, 4, 4 };
+    static const uint8_t ct_nb_codes[4] = { 4, 8, 8, 8 };
+    static const uint8_t (*const ct_huffs[4])[2]  = {
+        atrac3p_ct_huff1, atrac3p_ct_huff2,
+        atrac3p_ct_huff3, atrac3p_ct_huff4
     };
 
-    static const int sf_nb_bits[8]  = {  9,  9,  9,  9,  6,  6,  7,  7 };
-    static const int sf_nb_codes[8] = { 64, 64, 64, 64, 16, 16, 16, 16 };
-    static const uint8_t  * const sf_bits[8]  = {
-        atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits2,
-        atrac3p_sf_huff_bits3, atrac3p_sf_huff_bits4, atrac3p_sf_huff_bits4,
-        atrac3p_sf_huff_bits5, atrac3p_sf_huff_bits6
-    };
-    static const uint16_t * const sf_codes[8] = {
-        atrac3p_sf_huff_code1, atrac3p_sf_huff_code1, atrac3p_sf_huff_code2,
-        atrac3p_sf_huff_code3, atrac3p_sf_huff_code4, atrac3p_sf_huff_code4,
-        atrac3p_sf_huff_code5, atrac3p_sf_huff_code6
-    };
-    static const uint8_t  * const sf_xlats[8] = {
-        atrac3p_sf_huff_xlat1, atrac3p_sf_huff_xlat2, NULL, NULL,
-        atrac3p_sf_huff_xlat4, atrac3p_sf_huff_xlat5, NULL, NULL
+    static const uint8_t sf_nb_bits[8]  = {  9,  9,  9,  9,  6,  6,  7,  7 };
+    static const uint8_t sf_nb_codes[8] = { 64, 64, 64, 64, 15, 15, 15, 15 };
+    static const uint8_t  (*const sf_huffs[8])[2]  = {
+        atrac3p_sf_huff1, atrac3p_sf_huff2, atrac3p_sf_huff3,
+        atrac3p_sf_huff4, atrac3p_sf_huff5, atrac3p_sf_huff6,
+        atrac3p_sf_huff7, atrac3p_sf_huff8
     };
 
     static const uint8_t * const gain_cbs[11] = {
@@ -160,17 +133,15 @@ av_cold void ff_atrac3p_init_vlcs(void)
         ct_vlc_tabs[i].table = &tables_data[ct_vlc_offs];
         ct_vlc_tabs[i].table_allocated = 1 << ct_nb_bits[i];
 
-        ff_init_vlc_sparse(&wl_vlc_tabs[i], wl_nb_bits[i], wl_nb_codes[i],
-                           wl_bits[i],  1, 1,
-                           wl_codes[i], 1, 1,
-                           wl_xlats[i], 1, 1,
-                           INIT_VLC_USE_NEW_STATIC);
+        ff_init_vlc_from_lengths(&wl_vlc_tabs[i], wl_nb_bits[i], wl_nb_codes[i],
+                                 &wl_huffs[i][0][1], 2,
+                                 &wl_huffs[i][0][0], 2, 1,
+                                 0, INIT_VLC_USE_NEW_STATIC, NULL);
 
-        ff_init_vlc_sparse(&ct_vlc_tabs[i], ct_nb_bits[i], ct_nb_codes[i],
-                           ct_bits[i],  1, 1,
-                           ct_codes[i], 1, 1,
-                           ct_xlats[i], 1, 1,
-                           INIT_VLC_USE_NEW_STATIC);
+        ff_init_vlc_from_lengths(&ct_vlc_tabs[i], ct_nb_bits[i], ct_nb_codes[i],
+                                 &ct_huffs[i][0][1], 2,
+                                 &ct_huffs[i][0][0], 2, 1,
+                                 0, INIT_VLC_USE_NEW_STATIC, NULL);
 
         wl_vlc_offs += wl_vlc_tabs[i].table_allocated;
         ct_vlc_offs += ct_vlc_tabs[i].table_allocated;
@@ -180,11 +151,10 @@ av_cold void ff_atrac3p_init_vlcs(void)
         sf_vlc_tabs[i].table = &tables_data[sf_vlc_offs];
         sf_vlc_tabs[i].table_allocated = 1 << sf_nb_bits[i];
 
-        ff_init_vlc_sparse(&sf_vlc_tabs[i], sf_nb_bits[i], sf_nb_codes[i],
-                           sf_bits[i],  1, 1,
-                           sf_codes[i], 2, 2,
-                           sf_xlats[i], 1, 1,
-                           INIT_VLC_USE_NEW_STATIC);
+        ff_init_vlc_from_lengths(&sf_vlc_tabs[i], sf_nb_bits[i], sf_nb_codes[i],
+                                 &sf_huffs[i][0][1], 2,
+                                 &sf_huffs[i][0][0], 2, 1,
+                                 0, INIT_VLC_USE_NEW_STATIC, NULL);
         sf_vlc_offs += sf_vlc_tabs[i].table_allocated;
     }
 
@@ -192,12 +162,12 @@ av_cold void ff_atrac3p_init_vlcs(void)
 
     /* build huffman tables for spectrum decoding */
     for (i = 0; i < 112; i++) {
-        if (atrac3p_spectra_tabs[i].cb)
+        if (atrac3p_spectra_tabs[i].redirect < 0)
             build_canonical_huff(atrac3p_spectra_tabs[i].cb,
                                  atrac3p_spectra_tabs[i].xlat,
                                  &tab_offset, &spec_vlc_tabs[i]);
-        else
-            spec_vlc_tabs[i].table = 0;
+        else /* Reuse already initialized VLC table */
+            spec_vlc_tabs[i] = spec_vlc_tabs[atrac3p_spectra_tabs[i].redirect];
     }
 
     /* build huffman tables for gain data decoding */
@@ -456,6 +426,10 @@ static int decode_channel_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx,
     } else if (chan->fill_mode == 3) {
         pos = ch_num ? chan->num_coded_vals + chan->split_point
                      : ctx->num_quant_units - chan->split_point;
+        if (pos > FF_ARRAY_ELEMS(chan->qu_wordlen)) {
+            av_log(avctx, AV_LOG_ERROR, "Split point beyond array\n");
+            pos = FF_ARRAY_ELEMS(chan->qu_wordlen);
+        }
         for (i = chan->num_coded_vals; i < pos; i++)
             chan->qu_wordlen[i] = 1;
     }
@@ -876,10 +850,6 @@ static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx,
                 tab_index = (chan->table_type * 8 + codetab) * 7 + wordlen - 1;
                 tab       = &atrac3p_spectra_tabs[tab_index];
 
-                /* this allows reusing VLC tables */
-                if (tab->redirect >= 0)
-                    tab_index = tab->redirect;
-
                 decode_qu_spectra(gb, tab, &spec_vlc_tabs[tab_index],
                                   &chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]],
                                   num_specs);