From ec4ee483181d01d14444e4431159282ecd92a2c5 Mon Sep 17 00:00:00 2001 From: Mohamed Tarek Date: Mon, 12 Jul 2010 15:41:10 +0000 Subject: Complete the conversion of WMA Pro to fixed point. Floating point code is still there for better history and to have a returning point in svn should something go wrong. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27402 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libwmapro/wma.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'apps/codecs/libwmapro/wma.c') diff --git a/apps/codecs/libwmapro/wma.c b/apps/codecs/libwmapro/wma.c index 4b36c84aad..b1b1268eea 100644 --- a/apps/codecs/libwmapro/wma.c +++ b/apps/codecs/libwmapro/wma.c @@ -523,3 +523,58 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, return 0; } +int ff_wma_fix_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, + VLC *vlc, + const int32_t *level_table, const uint16_t *run_table, + int version, int32_t *ptr, int offset, + int num_coefs, int block_len, int frame_len_bits, + int coef_nb_bits) +{ + int32_t code, level, sign; + 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]; + sign = !get_bits1(gb); + ptr[offset & coef_mask] = sign ? -level_table[code] : level_table[code]; + ptr[offset & coef_mask] <<= 16; + } else if (code == 1) { + /** EOB */ + break; + } else { + /** escape */ + if (!version) { + level = get_bits(gb, coef_nb_bits); + /** NOTE: this is rather suboptimal. reading + block_len_bits would be better */ + offset += get_bits(gb, frame_len_bits); + } else { + level = ff_wma_get_large_val(gb); + /** escape decode */ + if (get_bits1(gb)) { + if (get_bits1(gb)) { + if (get_bits1(gb)) { + av_log(avctx,AV_LOG_ERROR, + "broken escape sequence\n"); + return -1; + } else + offset += get_bits(gb, frame_len_bits) + 4; + } else + offset += get_bits(gb, 2) + 1; + } + } + sign = !get_bits1(gb); + ptr[offset & coef_mask] = sign ? -level : level; + ptr[offset & coef_mask] <<=16; + } + } + /** NOTE: EOB can be omitted */ + if (offset > num_coefs) { + av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); + return -1; + } + + return 0; +} -- cgit v1.2.3