# HG changeset patch # User faust3 # Date 1244822426 0 # Node ID eb591652706410ce7a6b02371cdab1ef9973354e # Parent 893b2776869266d952f07223d684e7dfc7ecdef3 Move run level decode functionality to ff_wma_run_level_decode so that it can be reused for wmapro diff -r 893b27768692 -r eb5916527064 wma.c --- a/wma.c Fri Jun 12 15:48:41 2009 +0000 +++ b/wma.c Fri Jun 12 16:00:26 2009 +0000 @@ -424,3 +424,64 @@ return 0; } + +/** + * Decode run level compressed coefficients. + * @param avctx codec context + * @param gb bitstream reader context + * @param vlc vlc table for get_vlc2 + * @param level_table level codes + * @param run_table run codes + * @param version 0 for wma1,2 1 for wmapro + * @param ptr output buffer + * @param offset offset in the output buffer + * @param num_coefs number of input coefficents + * @param block_len input buffer length (2^n) + * @param frame_len_bits number of bits for escaped run codes + * @param coef_nb_bits number of bits for escaped level codes + * @return 0 on success, -1 otherwise + */ +int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, + VLC *vlc, + const uint16_t *level_table, const uint16_t *run_table, + int version, int16_t *ptr, int offset, + int num_coefs, int block_len, int frame_len_bits, + int coef_nb_bits) +{ + int code, run, level, sign; + int16_t* eptr = ptr + num_coefs; + for(;;) { + code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); + if (code < 0) + return -1; + if (code == 1) { + /* EOB */ + break; + } else if (code == 0) { + /* escape */ + level = get_bits(gb, coef_nb_bits); + /* NOTE: this is rather suboptimal. reading + block_len_bits would be better */ + run = get_bits(gb, frame_len_bits); + } else { + /* normal code */ + run = run_table[code]; + level = level_table[code]; + } + sign = get_bits1(gb); + if (!sign) + level = -level; + ptr += run; + if (ptr >= eptr) + { + av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); + break; + } + *ptr++ = level; + /* NOTE: EOB can be omitted */ + if (ptr >= eptr) + break; + } + return 0; +} + diff -r 893b27768692 -r eb5916527064 wma.h --- a/wma.h Fri Jun 12 15:48:41 2009 +0000 +++ b/wma.h Fri Jun 12 16:00:26 2009 +0000 @@ -148,5 +148,11 @@ int ff_wma_init(AVCodecContext * avctx, int flags2); int ff_wma_total_gain_to_bits(int total_gain); int ff_wma_end(AVCodecContext *avctx); +int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, + VLC *vlc, + const uint16_t *level_table, const uint16_t *run_table, + int version, int16_t *ptr, int offset, + int num_coefs, int block_len, int frame_len_bits, + int coef_nb_bits); #endif /* AVCODEC_WMA_H */ diff -r 893b27768692 -r eb5916527064 wmadec.c --- a/wmadec.c Fri Jun 12 15:48:41 2009 +0000 +++ b/wmadec.c Fri Jun 12 16:00:26 2009 +0000 @@ -349,7 +349,7 @@ */ static int wma_decode_block(WMACodecContext *s) { - int n, v, a, ch, code, bsize; + int n, v, a, ch, bsize; int coef_nb_bits, total_gain; int nb_coefs[MAX_CHANNELS]; float mdct_norm; @@ -485,53 +485,17 @@ /* parse spectral coefficients : just RLE encoding */ for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { - VLC *coef_vlc; - int level, run, sign, tindex; - int16_t *ptr, *eptr; - const uint16_t *level_table, *run_table; + int tindex; + int16_t* ptr = &s->coefs1[ch][0]; /* special VLC tables are used for ms stereo because there is potentially less energy there */ tindex = (ch == 1 && s->ms_stereo); - coef_vlc = &s->coef_vlc[tindex]; - run_table = s->run_table[tindex]; - level_table = s->level_table[tindex]; - /* XXX: optimize */ - ptr = &s->coefs1[ch][0]; - eptr = ptr + nb_coefs[ch]; memset(ptr, 0, s->block_len * sizeof(int16_t)); - for(;;) { - code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX); - if (code < 0) - return -1; - if (code == 1) { - /* EOB */ - break; - } else if (code == 0) { - /* escape */ - level = get_bits(&s->gb, coef_nb_bits); - /* NOTE: this is rather suboptimal. reading - block_len_bits would be better */ - run = get_bits(&s->gb, s->frame_len_bits); - } else { - /* normal code */ - run = run_table[code]; - level = level_table[code]; - } - sign = get_bits1(&s->gb); - if (!sign) - level = -level; - ptr += run; - if (ptr >= eptr) - { - av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); - break; - } - *ptr++ = level; - /* NOTE: EOB can be omitted */ - if (ptr >= eptr) - break; - } + ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], + s->level_table[tindex], s->run_table[tindex], + 0, ptr, 0, nb_coefs[ch], + s->block_len, s->frame_len_bits, coef_nb_bits); } if (s->version == 1 && s->nb_channels >= 2) { align_get_bits(&s->gb);