diff options
author | Måns Rullgård <mans@mansr.com> | 2009-09-29 10:38:34 +0000 |
---|---|---|
committer | Måns Rullgård <mans@mansr.com> | 2009-09-29 10:38:34 +0000 |
commit | 076a9dea1ee01e54abf4a18f4aa73fad02f200a7 (patch) | |
tree | 3287271b4874d8a22b53ccb6655506aa57f677d8 | |
parent | ff00b94e9d4f66922abe1830da2954a024bf87e5 (diff) | |
download | ffmpeg-076a9dea1ee01e54abf4a18f4aa73fad02f200a7.tar.gz |
WMA: store level_table as floats, use type punning for sign flip in decode
Originally committed as revision 20078 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/wma.c | 19 | ||||
-rw-r--r-- | libavcodec/wma.h | 4 | ||||
-rw-r--r-- | libavcodec/wmaprodata.h | 4 | ||||
-rw-r--r-- | libavcodec/wmaprodec.c | 2 |
4 files changed, 18 insertions, 11 deletions
diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 7f8b3b4ac2..9b2588f530 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -29,7 +29,7 @@ /* XXX: use same run/length optimization as mpeg decoders */ //FIXME maybe split decode / encode or pass flag static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, - uint16_t **plevel_table, uint16_t **pint_table, + float **plevel_table, uint16_t **pint_table, const CoefVLCTable *vlc_table) { int n = vlc_table->n; @@ -37,12 +37,14 @@ static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, const uint32_t *table_codes = vlc_table->huffcodes; const uint16_t *levels_table = vlc_table->levels; uint16_t *run_table, *level_table, *int_table; + float *flevel_table; int i, l, j, k, level; init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); run_table = av_malloc(n * sizeof(uint16_t)); level_table = av_malloc(n * sizeof(uint16_t)); + flevel_table= av_malloc(n * sizeof(*flevel_table)); int_table = av_malloc(n * sizeof(uint16_t)); i = 2; level = 1; @@ -53,13 +55,15 @@ static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, for (j = 0; j < l; j++) { run_table[i] = j; level_table[i] = level; + flevel_table[i]= level; i++; } level++; } *prun_table = run_table; - *plevel_table = level_table; + *plevel_table = flevel_table; *pint_table = int_table; + av_free(level_table); } /** @@ -465,19 +469,22 @@ unsigned int ff_wma_get_large_val(GetBitContext* gb) */ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, VLC *vlc, - const uint16_t *level_table, const uint16_t *run_table, + const float *level_table, const uint16_t *run_table, int version, WMACoef *ptr, int offset, int num_coefs, int block_len, int frame_len_bits, int coef_nb_bits) { int code, level, sign; + const uint32_t *ilvl = (const uint32_t*)level_table; + uint32_t *iptr = (uint32_t*)ptr; const unsigned int coef_mask = block_len - 1; for (; offset < num_coefs; offset++) { code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); if (code > 1) { /** normal code */ offset += run_table[code]; - level = level_table[code]; + sign = get_bits1(gb) - 1; + iptr[offset & coef_mask] = ilvl[code] ^ sign<<31; } else if (code == 1) { /** EOB */ break; @@ -503,9 +510,9 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, offset += get_bits(gb, 2) + 1; } } + sign = get_bits1(gb) - 1; + ptr[offset & coef_mask] = (level^sign) - sign; } - sign = get_bits1(gb) - 1; - ptr[offset & coef_mask] = (level^sign) - sign; } /** NOTE: EOB can be omitted */ if (offset > num_coefs) { diff --git a/libavcodec/wma.h b/libavcodec/wma.h index 6db60fafdb..b6c29433bb 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -93,7 +93,7 @@ typedef struct WMACodecContext { //FIXME the following 3 tables should be shared between decoders VLC coef_vlc[2]; uint16_t *run_table[2]; - uint16_t *level_table[2]; + float *level_table[2]; uint16_t *int_table[2]; const CoefVLCTable *coef_vlcs[2]; /* frame info */ @@ -153,7 +153,7 @@ int ff_wma_end(AVCodecContext *avctx); unsigned int ff_wma_get_large_val(GetBitContext* gb); int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, VLC *vlc, - const uint16_t *level_table, const uint16_t *run_table, + const float *level_table, const uint16_t *run_table, int version, WMACoef *ptr, int offset, int num_coefs, int block_len, int frame_len_bits, int coef_nb_bits); diff --git a/libavcodec/wmaprodata.h b/libavcodec/wmaprodata.h index a910c1914a..a1d186e0c2 100644 --- a/libavcodec/wmaprodata.h +++ b/libavcodec/wmaprodata.h @@ -352,7 +352,7 @@ static const uint16_t coef0_run[HUFF_COEF0_SIZE] = { 1, 0, 1, 0, 1, 0, }; -static const uint16_t coef0_level[HUFF_COEF0_SIZE] = { +static const float coef0_level[HUFF_COEF0_SIZE] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -393,7 +393,7 @@ static const uint16_t coef1_run[HUFF_COEF1_SIZE] = { 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, }; -static const uint16_t coef1_level[HUFF_COEF1_SIZE] = { +static const float coef1_level[HUFF_COEF1_SIZE] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index a4fcab7d27..a489047956 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -769,7 +769,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) int cur_coeff = 0; int num_zeros = 0; const uint16_t* run; - const uint16_t* level; + const float* level; dprintf(s->avctx, "decode coefficients for channel %i\n", c); |