]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - wmadec_filter.c
Don't try to init the decoder if less than WMA_FRAME_SKIP bytes are available.
[paraslash.git] / wmadec_filter.c
index c0d770d763dee327313270909c180e793983f22b..35e2703c1f796c390ce8386d764adb4a9395bff5 100644 (file)
@@ -83,7 +83,6 @@ struct private_wmadec_data {
        struct vlc coef_vlc[2];
        uint16_t *run_table[2];
        uint16_t *level_table[2];
-       uint16_t *int_table[2];
        const struct coef_vlc_table *coef_vlcs[2];
        /* frame info */
        int frame_len;          ///< frame length in samples
@@ -166,33 +165,27 @@ static void wmadec_cleanup(struct private_wmadec_data *pwd)
                free_vlc(&pwd->coef_vlc[i]);
                free(pwd->run_table[i]);
                free(pwd->level_table[i]);
-               free(pwd->int_table[i]);
        }
 }
 
-/* XXX: use same run/length optimization as mpeg decoders */
-//FIXME maybe split decode / encode or pass flag
 static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table,
-               uint16_t **plevel_table, uint16_t **pint_table,
-               const struct coef_vlc_table *vlc_table)
+               uint16_t **plevel_table, const struct coef_vlc_table *vlc_table)
 {
        int n = vlc_table->n;
        const uint8_t *table_bits = vlc_table->huffbits;
        const uint32_t *table_codes = vlc_table->huffcodes;
        const uint16_t *levels_table = vlc_table->levels;
-       uint16_t *run_table, *level_table, *int_table;
+       uint16_t *run_table, *level_table;
        int i, l, j, k, level;
 
-       init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4);
+       init_vlc(vlc, VLCBITS, n, table_bits, table_codes, 4);
 
        run_table = para_malloc(n * sizeof(uint16_t));
        level_table = para_malloc(n * sizeof(uint16_t));
-       int_table = para_malloc(n * sizeof(uint16_t));
        i = 2;
        level = 1;
        k = 0;
        while (i < n) {
-               int_table[k] = i;
                l = levels_table[k++];
                for (j = 0; j < l; j++) {
                        run_table[i] = j;
@@ -203,7 +196,6 @@ static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table,
        }
        *prun_table = run_table;
        *plevel_table = level_table;
-       *pint_table = int_table;
 }
 
 /* compute the scale factor band sizes for each MDCT block size */
@@ -426,9 +418,9 @@ static int wma_init(struct private_wmadec_data *pwd)
        pwd->coef_vlcs[0] = &coef_vlcs[coef_vlc_table * 2];
        pwd->coef_vlcs[1] = &coef_vlcs[coef_vlc_table * 2 + 1];
        init_coef_vlc(&pwd->coef_vlc[0], &pwd->run_table[0], &pwd->level_table[0],
-               &pwd->int_table[0], pwd->coef_vlcs[0]);
+               pwd->coef_vlcs[0]);
        init_coef_vlc(&pwd->coef_vlc[1], &pwd->run_table[1], &pwd->level_table[1],
-               &pwd->int_table[1], pwd->coef_vlcs[1]);
+               pwd->coef_vlcs[1]);
        return 0;
 }
 
@@ -489,14 +481,14 @@ static int wma_decode_init(char *initial_buf, int len, struct private_wmadec_dat
                PARA_INFO_LOG("using noise coding\n");
                init_vlc(&pwd->hgain_vlc, HGAINVLCBITS,
                        sizeof(ff_wma_hgain_huffbits), ff_wma_hgain_huffbits,
-                       1, 1, ff_wma_hgain_huffcodes, 2, 2);
+                       ff_wma_hgain_huffcodes, 2);
        }
 
        if (pwd->use_exp_vlc) {
                PARA_INFO_LOG("using exp_vlc\n");
                init_vlc(&pwd->exp_vlc, EXPVLCBITS,
                sizeof(ff_wma_scale_huffbits), ff_wma_scale_huffbits,
-               1, 1, ff_wma_scale_huffcodes, 4, 4);
+               ff_wma_scale_huffcodes, 4);
        } else {
                PARA_INFO_LOG("using curve\n");
                wma_lsp_to_curve_init(pwd, pwd->frame_len);
@@ -574,27 +566,6 @@ static void decode_exp_lsp(struct private_wmadec_data *pwd, int ch)
                pwd->block_len, lsp_coefs);
 }
 
-/*
- * Parse a vlc code, faster then get_vlc().
- *
- * \param bits The number of bits which will be read at once, must be
- * identical to nb_bits in init_vlc()
- *
- * \param max_depth The number of times bits bits must be read to completely
- * read the longest vlc code = (max_vlc_length + bits - 1) / bits.
- */
-static int get_vlc2(struct getbit_context *s, VLC_TYPE(*table)[2],
-               int bits, int max_depth)
-{
-       int code;
-
-       OPEN_READER(re, s)
-       UPDATE_CACHE(re, s)
-       GET_VLC(code, re, s, table, bits, max_depth)
-       CLOSE_READER(re, s)
-       return code;
-}
-
 /* Decode exponents coded with VLC codes. */
 static int decode_exp_vlc(struct private_wmadec_data *pwd, int ch)
 {
@@ -610,7 +581,7 @@ static int decode_exp_vlc(struct private_wmadec_data *pwd, int ch)
        last_exp = 36;
 
        while (q < q_end) {
-               code = get_vlc2(&pwd->gb, pwd->exp_vlc.table, EXPVLCBITS, EXPMAX);
+               code = get_vlc(&pwd->gb, pwd->exp_vlc.table, EXPVLCBITS, EXPMAX);
                if (code < 0)
                        return -1;
                /* NOTE: this offset is the same as MPEG4 AAC ! */
@@ -752,10 +723,10 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                return -E_INCOHERENT_BLOCK_LEN;
 
        if (pwd->ahi.channels == 2)
-               pwd->ms_stereo = get_bits1(&pwd->gb);
+               pwd->ms_stereo = get_bit(&pwd->gb);
        v = 0;
        for (ch = 0; ch < pwd->ahi.channels; ch++) {
-               int a = get_bits1(&pwd->gb);
+               int a = get_bit(&pwd->gb);
                pwd->channel_coded[ch] = a;
                v |= a;
        }
@@ -791,7 +762,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                                int i, m, a;
                                m = pwd->exponent_high_sizes[bsize];
                                for (i = 0; i < m; i++) {
-                                       a = get_bits1(&pwd->gb);
+                                       a = get_bit(&pwd->gb);
                                        pwd->high_band_coded[ch][i] = a;
                                        /* if noise coding, the coefficients are not transmitted */
                                        if (a)
@@ -816,7 +787,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                                                                     7) - 19;
                                                } else {
                                                        code =
-                                                           get_vlc2(&pwd->gb,
+                                                           get_vlc(&pwd->gb,
                                                                     pwd->
                                                                     hgain_vlc.
                                                                     table,
@@ -835,7 +806,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
        }
 
        /* exponents can be reused in short blocks. */
-       if ((pwd->block_len_bits == pwd->frame_len_bits) || get_bits1(&pwd->gb)) {
+       if ((pwd->block_len_bits == pwd->frame_len_bits) || get_bit(&pwd->gb)) {
                for (ch = 0; ch < pwd->ahi.channels; ch++) {
                        if (pwd->channel_coded[ch]) {
                                if (pwd->use_exp_vlc) {
@@ -851,56 +822,50 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
 
        /* parse spectral coefficients : just RLE encoding */
        for (ch = 0; ch < pwd->ahi.channels; ch++) {
-               if (pwd->channel_coded[ch]) {
-                       struct vlc *coef_vlc;
-                       int level, run, sign, tindex;
-                       int16_t *ptr, *eptr;
-                       const uint16_t *level_table, *run_table;
-
-                       /* special VLC tables are used for ms stereo because
-                          there is potentially less energy there */
-                       tindex = (ch == 1 && pwd->ms_stereo);
-                       coef_vlc = &pwd->coef_vlc[tindex];
-                       run_table = pwd->run_table[tindex];
-                       level_table = pwd->level_table[tindex];
-                       /* XXX: optimize */
-                       ptr = &pwd->coefs1[ch][0];
-                       eptr = ptr + nb_coefs[ch];
-                       memset(ptr, 0, pwd->block_len * sizeof(int16_t));
-                       for (;;) {
-                               code =
-                                   get_vlc2(&pwd->gb, coef_vlc->table, VLCBITS,
-                                            VLCMAX);
-                               if (code < 0)
-                                       return -1;
-                               if (code == 1) {
-                                       /* EOB */
-                                       break;
-                               } else if (code == 0) {
-                                       /* escape */
-                                       level = get_bits(&pwd->gb, coef_nb_bits);
-                                       /* NOTE: this is rather suboptimal. reading
-                                          block_len_bits would be better */
-                                       run =
-                                           get_bits(&pwd->gb, pwd->frame_len_bits);
-                               } else {
-                                       /* normal code */
-                                       run = run_table[code];
-                                       level = level_table[code];
-                               }
-                               sign = get_bits1(&pwd->gb);
-                               if (!sign)
-                                       level = -level;
-                               ptr += run;
-                               if (ptr >= eptr) {
-                                       PARA_ERROR_LOG("overflow in spectral RLE, ignoring\n");
-                                       break;
-                               }
-                               *ptr++ = level;
-                               /* NOTE: EOB can be omitted */
-                               if (ptr >= eptr)
-                                       break;
+               struct vlc *coef_vlc;
+               int level, run, tindex;
+               int16_t *ptr, *eptr;
+               const uint16_t *level_table, *run_table;
+
+               if (!pwd->channel_coded[ch])
+                       continue;
+               /*
+                * special VLC tables are used for ms stereo because there is
+                * potentially less energy there
+                */
+               tindex = (ch == 1 && pwd->ms_stereo);
+               coef_vlc = &pwd->coef_vlc[tindex];
+               run_table = pwd->run_table[tindex];
+               level_table = pwd->level_table[tindex];
+               /* XXX: optimize */
+               ptr = &pwd->coefs1[ch][0];
+               eptr = ptr + nb_coefs[ch];
+               memset(ptr, 0, pwd->block_len * sizeof(int16_t));
+               for (;;) {
+                       code = get_vlc(&pwd->gb, coef_vlc->table,
+                               VLCBITS, VLCMAX);
+                       if (code < 0)
+                               return -1;
+                       if (code == 1) /* EOB */
+                               break;
+                       if (code == 0) { /* escape */
+                               level = get_bits(&pwd->gb, coef_nb_bits);
+                               /* reading block_len_bits would be better */
+                               run = get_bits(&pwd->gb, pwd->frame_len_bits);
+                       } else { /* normal code */
+                               run = run_table[code];
+                               level = level_table[code];
+                       }
+                       if (!get_bit(&pwd->gb))
+                               level = -level;
+                       ptr += run;
+                       if (ptr >= eptr) {
+                               PARA_ERROR_LOG("overflow in spectral RLE, ignoring\n");
+                               break;
                        }
+                       *ptr++ = level;
+                       if (ptr >= eptr) /* EOB can be omitted */
+                               break;
                }
        }
 
@@ -1165,8 +1130,7 @@ static int wma_decode_frame(struct private_wmadec_data *pwd, int16_t *samples)
 static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
                int *data_size, const uint8_t *buf, int buf_size)
 {
-       int ret, nb_frames, bit_offset, i, pos, len;
-       uint8_t *q;
+       int ret;
        int16_t *samples;
        static int frame_count;
 
@@ -1178,8 +1142,11 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
                return 0;
        buf_size = pwd->ahi.block_align;
        samples = data;
-       init_get_bits(&pwd->gb, buf, buf_size * 8);
+       init_get_bits(&pwd->gb, buf, buf_size);
        if (pwd->use_bit_reservoir) {
+               int i, nb_frames, bit_offset, pos, len;
+               uint8_t *q;
+
                /* read super frame header */
                skip_bits(&pwd->gb, 4); /* super frame index */
                nb_frames = get_bits(&pwd->gb, 4) - 1;
@@ -1208,7 +1175,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
 
                        /* XXX: bit_offset bits into last frame */
                        init_get_bits(&pwd->gb, pwd->last_superframe,
-                               MAX_CODED_SUPERFRAME_SIZE * 8);
+                               MAX_CODED_SUPERFRAME_SIZE);
                        /* skip unused bits */
                        if (pwd->last_bitoffset > 0)
                                skip_bits(&pwd->gb, pwd->last_bitoffset);
@@ -1226,7 +1193,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
                /* read each frame starting from bit_offset */
                pos = bit_offset + 4 + 4 + pwd->byte_offset_bits + 3;
                init_get_bits(&pwd->gb, buf + (pos >> 3),
-                       (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3)) * 8);
+                       (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3)));
                len = pos & 7;
                if (len > 0)
                        skip_bits(&pwd->gb, len);
@@ -1283,6 +1250,8 @@ static ssize_t wmadec_convert(char *inbuffer, size_t len,
 
        if (out_size < 128 * 1024)
                return 0;
+       if (len <= WMA_FRAME_SKIP)
+               return 0;
        if (!pwd) {
                ret = wma_decode_init(inbuffer, len, &pwd);
                if (ret <= 0)