so that it can be reused for wmapro Originally committed as revision 19171 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.6
| @@ -424,3 +424,64 @@ int ff_wma_end(AVCodecContext *avctx) | |||
| 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; | |||
| } | |||
| @@ -148,5 +148,11 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version, | |||
| 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 */ | |||
| @@ -349,7 +349,7 @@ static void wma_window(WMACodecContext *s, float *out) | |||
| */ | |||
| 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 @@ static int wma_decode_block(WMACodecContext *s) | |||
| /* 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); | |||