yading@10: /* yading@10: * WMA compatible codec yading@10: * Copyright (c) 2002-2007 The FFmpeg Project yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: #include "avcodec.h" yading@10: #include "sinewin.h" yading@10: #include "wma.h" yading@10: #include "wma_common.h" yading@10: #include "wmadata.h" yading@10: yading@10: #undef NDEBUG yading@10: #include yading@10: yading@10: /* XXX: use same run/length optimization as mpeg decoders */ yading@10: //FIXME maybe split decode / encode or pass flag yading@10: static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, yading@10: float **plevel_table, uint16_t **pint_table, yading@10: const CoefVLCTable *vlc_table) yading@10: { yading@10: int n = vlc_table->n; yading@10: const uint8_t *table_bits = vlc_table->huffbits; yading@10: const uint32_t *table_codes = vlc_table->huffcodes; yading@10: const uint16_t *levels_table = vlc_table->levels; yading@10: uint16_t *run_table, *level_table, *int_table; yading@10: float *flevel_table; yading@10: int i, l, j, k, level; yading@10: yading@10: init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); yading@10: yading@10: run_table = av_malloc(n * sizeof(uint16_t)); yading@10: level_table = av_malloc(n * sizeof(uint16_t)); yading@10: flevel_table= av_malloc(n * sizeof(*flevel_table)); yading@10: int_table = av_malloc(n * sizeof(uint16_t)); yading@10: i = 2; yading@10: level = 1; yading@10: k = 0; yading@10: while (i < n) { yading@10: int_table[k] = i; yading@10: l = levels_table[k++]; yading@10: for (j = 0; j < l; j++) { yading@10: run_table[i] = j; yading@10: level_table[i] = level; yading@10: flevel_table[i]= level; yading@10: i++; yading@10: } yading@10: level++; yading@10: } yading@10: *prun_table = run_table; yading@10: *plevel_table = flevel_table; yading@10: *pint_table = int_table; yading@10: av_free(level_table); yading@10: } yading@10: yading@10: int ff_wma_init(AVCodecContext *avctx, int flags2) yading@10: { yading@10: WMACodecContext *s = avctx->priv_data; yading@10: int i; yading@10: float bps1, high_freq; yading@10: volatile float bps; yading@10: int sample_rate1; yading@10: int coef_vlc_table; yading@10: yading@10: if ( avctx->sample_rate <= 0 || avctx->sample_rate > 50000 yading@10: || avctx->channels <= 0 || avctx->channels > 2 yading@10: || avctx->bit_rate <= 0) yading@10: return -1; yading@10: yading@10: ff_fmt_convert_init(&s->fmt_conv, avctx); yading@10: avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); yading@10: yading@10: if (avctx->codec->id == AV_CODEC_ID_WMAV1) { yading@10: s->version = 1; yading@10: } else { yading@10: s->version = 2; yading@10: } yading@10: yading@10: /* compute MDCT block size */ yading@10: s->frame_len_bits = ff_wma_get_frame_len_bits(avctx->sample_rate, yading@10: s->version, 0); yading@10: s->next_block_len_bits = s->frame_len_bits; yading@10: s->prev_block_len_bits = s->frame_len_bits; yading@10: s->block_len_bits = s->frame_len_bits; yading@10: yading@10: s->frame_len = 1 << s->frame_len_bits; yading@10: if (s->use_variable_block_len) { yading@10: int nb_max, nb; yading@10: nb = ((flags2 >> 3) & 3) + 1; yading@10: if ((avctx->bit_rate / avctx->channels) >= 32000) yading@10: nb += 2; yading@10: nb_max = s->frame_len_bits - BLOCK_MIN_BITS; yading@10: if (nb > nb_max) yading@10: nb = nb_max; yading@10: s->nb_block_sizes = nb + 1; yading@10: } else { yading@10: s->nb_block_sizes = 1; yading@10: } yading@10: yading@10: /* init rate dependent parameters */ yading@10: s->use_noise_coding = 1; yading@10: high_freq = avctx->sample_rate * 0.5; yading@10: yading@10: /* if version 2, then the rates are normalized */ yading@10: sample_rate1 = avctx->sample_rate; yading@10: if (s->version == 2) { yading@10: if (sample_rate1 >= 44100) { yading@10: sample_rate1 = 44100; yading@10: } else if (sample_rate1 >= 22050) { yading@10: sample_rate1 = 22050; yading@10: } else if (sample_rate1 >= 16000) { yading@10: sample_rate1 = 16000; yading@10: } else if (sample_rate1 >= 11025) { yading@10: sample_rate1 = 11025; yading@10: } else if (sample_rate1 >= 8000) { yading@10: sample_rate1 = 8000; yading@10: } yading@10: } yading@10: yading@10: bps = (float)avctx->bit_rate / (float)(avctx->channels * avctx->sample_rate); yading@10: s->byte_offset_bits = av_log2((int)(bps * s->frame_len / 8.0 + 0.5)) + 2; yading@10: if (s->byte_offset_bits + 3 > MIN_CACHE_BITS) { yading@10: av_log(avctx, AV_LOG_ERROR, "byte_offset_bits %d is too large\n", s->byte_offset_bits); yading@10: return AVERROR_PATCHWELCOME; yading@10: } yading@10: yading@10: /* compute high frequency value and choose if noise coding should yading@10: be activated */ yading@10: bps1 = bps; yading@10: if (avctx->channels == 2) yading@10: bps1 = bps * 1.6; yading@10: if (sample_rate1 == 44100) { yading@10: if (bps1 >= 0.61) { yading@10: s->use_noise_coding = 0; yading@10: } else { yading@10: high_freq = high_freq * 0.4; yading@10: } yading@10: } else if (sample_rate1 == 22050) { yading@10: if (bps1 >= 1.16) { yading@10: s->use_noise_coding = 0; yading@10: } else if (bps1 >= 0.72) { yading@10: high_freq = high_freq * 0.7; yading@10: } else { yading@10: high_freq = high_freq * 0.6; yading@10: } yading@10: } else if (sample_rate1 == 16000) { yading@10: if (bps > 0.5) { yading@10: high_freq = high_freq * 0.5; yading@10: } else { yading@10: high_freq = high_freq * 0.3; yading@10: } yading@10: } else if (sample_rate1 == 11025) { yading@10: high_freq = high_freq * 0.7; yading@10: } else if (sample_rate1 == 8000) { yading@10: if (bps <= 0.625) { yading@10: high_freq = high_freq * 0.5; yading@10: } else if (bps > 0.75) { yading@10: s->use_noise_coding = 0; yading@10: } else { yading@10: high_freq = high_freq * 0.65; yading@10: } yading@10: } else { yading@10: if (bps >= 0.8) { yading@10: high_freq = high_freq * 0.75; yading@10: } else if (bps >= 0.6) { yading@10: high_freq = high_freq * 0.6; yading@10: } else { yading@10: high_freq = high_freq * 0.5; yading@10: } yading@10: } yading@10: av_dlog(s->avctx, "flags2=0x%x\n", flags2); yading@10: av_dlog(s->avctx, "version=%d channels=%d sample_rate=%d bitrate=%d block_align=%d\n", yading@10: s->version, avctx->channels, avctx->sample_rate, avctx->bit_rate, yading@10: avctx->block_align); yading@10: av_dlog(s->avctx, "bps=%f bps1=%f high_freq=%f bitoffset=%d\n", yading@10: bps, bps1, high_freq, s->byte_offset_bits); yading@10: av_dlog(s->avctx, "use_noise_coding=%d use_exp_vlc=%d nb_block_sizes=%d\n", yading@10: s->use_noise_coding, s->use_exp_vlc, s->nb_block_sizes); yading@10: yading@10: /* compute the scale factor band sizes for each MDCT block size */ yading@10: { yading@10: int a, b, pos, lpos, k, block_len, i, j, n; yading@10: const uint8_t *table; yading@10: yading@10: if (s->version == 1) { yading@10: s->coefs_start = 3; yading@10: } else { yading@10: s->coefs_start = 0; yading@10: } yading@10: for (k = 0; k < s->nb_block_sizes; k++) { yading@10: block_len = s->frame_len >> k; yading@10: yading@10: if (s->version == 1) { yading@10: lpos = 0; yading@10: for (i = 0; i < 25; i++) { yading@10: a = ff_wma_critical_freqs[i]; yading@10: b = avctx->sample_rate; yading@10: pos = ((block_len * 2 * a) + (b >> 1)) / b; yading@10: if (pos > block_len) yading@10: pos = block_len; yading@10: s->exponent_bands[0][i] = pos - lpos; yading@10: if (pos >= block_len) { yading@10: i++; yading@10: break; yading@10: } yading@10: lpos = pos; yading@10: } yading@10: s->exponent_sizes[0] = i; yading@10: } else { yading@10: /* hardcoded tables */ yading@10: table = NULL; yading@10: a = s->frame_len_bits - BLOCK_MIN_BITS - k; yading@10: if (a < 3) { yading@10: if (avctx->sample_rate >= 44100) { yading@10: table = exponent_band_44100[a]; yading@10: } else if (avctx->sample_rate >= 32000) { yading@10: table = exponent_band_32000[a]; yading@10: } else if (avctx->sample_rate >= 22050) { yading@10: table = exponent_band_22050[a]; yading@10: } yading@10: } yading@10: if (table) { yading@10: n = *table++; yading@10: for (i = 0; i < n; i++) yading@10: s->exponent_bands[k][i] = table[i]; yading@10: s->exponent_sizes[k] = n; yading@10: } else { yading@10: j = 0; yading@10: lpos = 0; yading@10: for (i = 0; i < 25; i++) { yading@10: a = ff_wma_critical_freqs[i]; yading@10: b = avctx->sample_rate; yading@10: pos = ((block_len * 2 * a) + (b << 1)) / (4 * b); yading@10: pos <<= 2; yading@10: if (pos > block_len) yading@10: pos = block_len; yading@10: if (pos > lpos) yading@10: s->exponent_bands[k][j++] = pos - lpos; yading@10: if (pos >= block_len) yading@10: break; yading@10: lpos = pos; yading@10: } yading@10: s->exponent_sizes[k] = j; yading@10: } yading@10: } yading@10: yading@10: /* max number of coefs */ yading@10: s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; yading@10: /* high freq computation */ yading@10: s->high_band_start[k] = (int)((block_len * 2 * high_freq) / yading@10: avctx->sample_rate + 0.5); yading@10: n = s->exponent_sizes[k]; yading@10: j = 0; yading@10: pos = 0; yading@10: for (i = 0; i < n; i++) { yading@10: int start, end; yading@10: start = pos; yading@10: pos += s->exponent_bands[k][i]; yading@10: end = pos; yading@10: if (start < s->high_band_start[k]) yading@10: start = s->high_band_start[k]; yading@10: if (end > s->coefs_end[k]) yading@10: end = s->coefs_end[k]; yading@10: if (end > start) yading@10: s->exponent_high_bands[k][j++] = end - start; yading@10: } yading@10: s->exponent_high_sizes[k] = j; yading@10: #if 0 yading@10: tprintf(s->avctx, "%5d: coefs_end=%d high_band_start=%d nb_high_bands=%d: ", yading@10: s->frame_len >> k, yading@10: s->coefs_end[k], yading@10: s->high_band_start[k], yading@10: s->exponent_high_sizes[k]); yading@10: for (j = 0; j < s->exponent_high_sizes[k]; j++) yading@10: tprintf(s->avctx, " %d", s->exponent_high_bands[k][j]); yading@10: tprintf(s->avctx, "\n"); yading@10: #endif yading@10: } yading@10: } yading@10: yading@10: #ifdef TRACE yading@10: { yading@10: int i, j; yading@10: for (i = 0; i < s->nb_block_sizes; i++) { yading@10: tprintf(s->avctx, "%5d: n=%2d:", yading@10: s->frame_len >> i, yading@10: s->exponent_sizes[i]); yading@10: for (j = 0; j < s->exponent_sizes[i]; j++) yading@10: tprintf(s->avctx, " %d", s->exponent_bands[i][j]); yading@10: tprintf(s->avctx, "\n"); yading@10: } yading@10: } yading@10: #endif yading@10: yading@10: /* init MDCT windows : simple sinus window */ yading@10: for (i = 0; i < s->nb_block_sizes; i++) { yading@10: ff_init_ff_sine_windows(s->frame_len_bits - i); yading@10: s->windows[i] = ff_sine_windows[s->frame_len_bits - i]; yading@10: } yading@10: yading@10: s->reset_block_lengths = 1; yading@10: yading@10: if (s->use_noise_coding) { yading@10: yading@10: /* init the noise generator */ yading@10: if (s->use_exp_vlc) { yading@10: s->noise_mult = 0.02; yading@10: } else { yading@10: s->noise_mult = 0.04; yading@10: } yading@10: yading@10: #ifdef TRACE yading@10: for (i = 0; i < NOISE_TAB_SIZE; i++) yading@10: s->noise_table[i] = 1.0 * s->noise_mult; yading@10: #else yading@10: { yading@10: unsigned int seed; yading@10: float norm; yading@10: seed = 1; yading@10: norm = (1.0 / (float)(1LL << 31)) * sqrt(3) * s->noise_mult; yading@10: for (i = 0; i < NOISE_TAB_SIZE; i++) { yading@10: seed = seed * 314159 + 1; yading@10: s->noise_table[i] = (float)((int)seed) * norm; yading@10: } yading@10: } yading@10: #endif yading@10: } yading@10: yading@10: /* choose the VLC tables for the coefficients */ yading@10: coef_vlc_table = 2; yading@10: if (avctx->sample_rate >= 32000) { yading@10: if (bps1 < 0.72) { yading@10: coef_vlc_table = 0; yading@10: } else if (bps1 < 1.16) { yading@10: coef_vlc_table = 1; yading@10: } yading@10: } yading@10: s->coef_vlcs[0]= &coef_vlcs[coef_vlc_table * 2 ]; yading@10: s->coef_vlcs[1]= &coef_vlcs[coef_vlc_table * 2 + 1]; yading@10: init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0], &s->int_table[0], yading@10: s->coef_vlcs[0]); yading@10: init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], &s->int_table[1], yading@10: s->coef_vlcs[1]); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: int ff_wma_total_gain_to_bits(int total_gain) yading@10: { yading@10: if (total_gain < 15) return 13; yading@10: else if (total_gain < 32) return 12; yading@10: else if (total_gain < 40) return 11; yading@10: else if (total_gain < 45) return 10; yading@10: else return 9; yading@10: } yading@10: yading@10: int ff_wma_end(AVCodecContext *avctx) yading@10: { yading@10: WMACodecContext *s = avctx->priv_data; yading@10: int i; yading@10: yading@10: for (i = 0; i < s->nb_block_sizes; i++) yading@10: ff_mdct_end(&s->mdct_ctx[i]); yading@10: yading@10: if (s->use_exp_vlc) { yading@10: ff_free_vlc(&s->exp_vlc); yading@10: } yading@10: if (s->use_noise_coding) { yading@10: ff_free_vlc(&s->hgain_vlc); yading@10: } yading@10: for (i = 0; i < 2; i++) { yading@10: ff_free_vlc(&s->coef_vlc[i]); yading@10: av_free(s->run_table[i]); yading@10: av_free(s->level_table[i]); yading@10: av_free(s->int_table[i]); yading@10: } yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: /** yading@10: * Decode an uncompressed coefficient. yading@10: * @param gb GetBitContext yading@10: * @return the decoded coefficient yading@10: */ yading@10: unsigned int ff_wma_get_large_val(GetBitContext* gb) yading@10: { yading@10: /** consumes up to 34 bits */ yading@10: int n_bits = 8; yading@10: /** decode length */ yading@10: if (get_bits1(gb)) { yading@10: n_bits += 8; yading@10: if (get_bits1(gb)) { yading@10: n_bits += 8; yading@10: if (get_bits1(gb)) { yading@10: n_bits += 7; yading@10: } yading@10: } yading@10: } yading@10: return get_bits_long(gb, n_bits); yading@10: } yading@10: yading@10: /** yading@10: * Decode run level compressed coefficients. yading@10: * @param avctx codec context yading@10: * @param gb bitstream reader context yading@10: * @param vlc vlc table for get_vlc2 yading@10: * @param level_table level codes yading@10: * @param run_table run codes yading@10: * @param version 0 for wma1,2 1 for wmapro yading@10: * @param ptr output buffer yading@10: * @param offset offset in the output buffer yading@10: * @param num_coefs number of input coefficents yading@10: * @param block_len input buffer length (2^n) yading@10: * @param frame_len_bits number of bits for escaped run codes yading@10: * @param coef_nb_bits number of bits for escaped level codes yading@10: * @return 0 on success, -1 otherwise yading@10: */ yading@10: int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, yading@10: VLC *vlc, yading@10: const float *level_table, const uint16_t *run_table, yading@10: int version, WMACoef *ptr, int offset, yading@10: int num_coefs, int block_len, int frame_len_bits, yading@10: int coef_nb_bits) yading@10: { yading@10: int code, level, sign; yading@10: const uint32_t *ilvl = (const uint32_t*)level_table; yading@10: uint32_t *iptr = (uint32_t*)ptr; yading@10: const unsigned int coef_mask = block_len - 1; yading@10: for (; offset < num_coefs; offset++) { yading@10: code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); yading@10: if (code > 1) { yading@10: /** normal code */ yading@10: offset += run_table[code]; yading@10: sign = get_bits1(gb) - 1; yading@10: iptr[offset & coef_mask] = ilvl[code] ^ sign<<31; yading@10: } else if (code == 1) { yading@10: /** EOB */ yading@10: break; yading@10: } else { yading@10: /** escape */ yading@10: if (!version) { yading@10: level = get_bits(gb, coef_nb_bits); yading@10: /** NOTE: this is rather suboptimal. reading yading@10: block_len_bits would be better */ yading@10: offset += get_bits(gb, frame_len_bits); yading@10: } else { yading@10: level = ff_wma_get_large_val(gb); yading@10: /** escape decode */ yading@10: if (get_bits1(gb)) { yading@10: if (get_bits1(gb)) { yading@10: if (get_bits1(gb)) { yading@10: av_log(avctx,AV_LOG_ERROR, yading@10: "broken escape sequence\n"); yading@10: return -1; yading@10: } else yading@10: offset += get_bits(gb, frame_len_bits) + 4; yading@10: } else yading@10: offset += get_bits(gb, 2) + 1; yading@10: } yading@10: } yading@10: sign = get_bits1(gb) - 1; yading@10: ptr[offset & coef_mask] = (level^sign) - sign; yading@10: } yading@10: } yading@10: /** NOTE: EOB can be omitted */ yading@10: if (offset > num_coefs) { yading@10: av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); yading@10: return -1; yading@10: } yading@10: yading@10: return 0; yading@10: }