Mercurial > libavcodec.hg
changeset 10097:9b608d9428ae libavcodec
add decode_coeffs()
author | faust3 |
---|---|
date | Wed, 26 Aug 2009 21:23:21 +0000 |
parents | 071d6d272a77 |
children | fef90da31453 |
files | wmaprodec.c |
diffstat | 1 files changed, 88 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/wmaprodec.c Wed Aug 26 21:18:54 2009 +0000 +++ b/wmaprodec.c Wed Aug 26 21:23:21 2009 +0000 @@ -153,6 +153,94 @@ } /** + *@brief Extract the coefficients from the bitstream. + *@param s codec context + *@param c current channel number + *@return 0 on success, < 0 in case of bitstream errors + */ +static int decode_coeffs(WMA3DecodeContext *s, int c) +{ + int vlctable; + VLC* vlc; + WMA3ChannelCtx* ci = &s->channel[c]; + int rl_mode = 0; + int cur_coeff = 0; + int num_zeros = 0; + const uint16_t* run; + const uint16_t* level; + + dprintf(s->avctx, "decode coefficients for channel %i\n", c); + + vlctable = get_bits1(&s->gb); + vlc = &coef_vlc[vlctable]; + + if (vlctable) { + run = coef1_run; + level = coef1_level; + } else { + run = coef0_run; + level = coef0_level; + } + + /** decode vector coefficients (consumes up to 167 bits per iteration for + 4 vector coded large values) */ + while (!rl_mode && cur_coeff + 3 < s->subframe_len) { + int vals[4]; + int i; + unsigned int idx; + + idx = get_vlc2(&s->gb, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH); + + if ( idx == HUFF_VEC4_SIZE - 1 ) { + for (i = 0; i < 4; i += 2) { + idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); + if ( idx == HUFF_VEC2_SIZE - 1 ) { + vals[i] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); + if (vals[i] == HUFF_VEC1_SIZE - 1) + vals[i] += ff_wma_get_large_val(&s->gb); + vals[i+1] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); + if (vals[i+1] == HUFF_VEC1_SIZE - 1) + vals[i+1] += ff_wma_get_large_val(&s->gb); + } else { + vals[i] = symbol_to_vec2[idx] >> 4; + vals[i+1] = symbol_to_vec2[idx] & 0xF; + } + } + } else { + vals[0] = symbol_to_vec4[idx] >> 12; + vals[1] = (symbol_to_vec4[idx] >> 8) & 0xF; + vals[2] = (symbol_to_vec4[idx] >> 4) & 0xF; + vals[3] = symbol_to_vec4[idx] & 0xF; + } + + /** decode sign */ + for (i = 0; i < 4; i++) { + if (vals[i]) { + int sign = get_bits1(&s->gb) - 1; + ci->coeffs[cur_coeff] = (vals[i]^sign) - sign; + num_zeros = 0; + } else { + /** switch to run level mode when subframe_len / 128 zeros + were found in a row */ + rl_mode |= (++num_zeros > s->subframe_len>>8); + } + ++cur_coeff; + } + } + + /** decode run level coded coefficients */ + if (rl_mode) { + if(ff_wma_run_level_decode(s->avctx, &s->gb, vlc, + level, run, 1, ci->coeffs, + cur_coeff, s->subframe_len, s->subframe_len, + s->esc_len, 0)) + return AVERROR_INVALIDDATA; + } + + return 0; +} + +/** *@brief Reconstruct the individual channel data. *@param s codec context */