X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fwmadec.c;h=e622b238d6d6a8f3ad2cc28fe2fc7eb5ce82593f;hb=542c064d1bae296fc55c3058f3eda72df7879d4d;hp=147bb5abbbf906b3c746be07067ea24e9d76fc5b;hpb=115329f16062074e11ccf3b89ead6176606c9696;p=ffmpeg diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 147bb5abbbf..e622b238d6d 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -2,19 +2,21 @@ * WMA compatible decoder * Copyright (c) 2002 The FFmpeg Project. * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -32,527 +34,108 @@ */ #include "avcodec.h" -#include "bitstream.h" -#include "dsputil.h" - -/* size of blocks */ -#define BLOCK_MIN_BITS 7 -#define BLOCK_MAX_BITS 11 -#define BLOCK_MAX_SIZE (1 << BLOCK_MAX_BITS) - -#define BLOCK_NB_SIZES (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) - -/* XXX: find exact max size */ -#define HIGH_BAND_MAX_SIZE 16 - -#define NB_LSP_COEFS 10 - -/* XXX: is it a suitable value ? */ -#define MAX_CODED_SUPERFRAME_SIZE 16384 - -#define MAX_CHANNELS 2 - -#define NOISE_TAB_SIZE 8192 - -#define LSP_POW_BITS 7 - -typedef struct WMADecodeContext { - GetBitContext gb; - int sample_rate; - int nb_channels; - int bit_rate; - int version; /* 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2) */ - int block_align; - int use_bit_reservoir; - int use_variable_block_len; - int use_exp_vlc; /* exponent coding: 0 = lsp, 1 = vlc + delta */ - int use_noise_coding; /* true if perceptual noise is added */ - int byte_offset_bits; - VLC exp_vlc; - int exponent_sizes[BLOCK_NB_SIZES]; - uint16_t exponent_bands[BLOCK_NB_SIZES][25]; - int high_band_start[BLOCK_NB_SIZES]; /* index of first coef in high band */ - int coefs_start; /* first coded coef */ - int coefs_end[BLOCK_NB_SIZES]; /* max number of coded coefficients */ - int exponent_high_sizes[BLOCK_NB_SIZES]; - int exponent_high_bands[BLOCK_NB_SIZES][HIGH_BAND_MAX_SIZE]; - VLC hgain_vlc; - - /* coded values in high bands */ - int high_band_coded[MAX_CHANNELS][HIGH_BAND_MAX_SIZE]; - int high_band_values[MAX_CHANNELS][HIGH_BAND_MAX_SIZE]; - - /* there are two possible tables for spectral coefficients */ - VLC coef_vlc[2]; - uint16_t *run_table[2]; - uint16_t *level_table[2]; - /* frame info */ - int frame_len; /* frame length in samples */ - int frame_len_bits; /* frame_len = 1 << frame_len_bits */ - int nb_block_sizes; /* number of block sizes */ - /* block info */ - int reset_block_lengths; - int block_len_bits; /* log2 of current block length */ - int next_block_len_bits; /* log2 of next block length */ - int prev_block_len_bits; /* log2 of prev block length */ - int block_len; /* block length in samples */ - int block_num; /* block number in current frame */ - int block_pos; /* current position in frame */ - uint8_t ms_stereo; /* true if mid/side stereo mode */ - uint8_t channel_coded[MAX_CHANNELS]; /* true if channel is coded */ - float exponents[MAX_CHANNELS][BLOCK_MAX_SIZE] __attribute__((aligned(16))); - float max_exponent[MAX_CHANNELS]; - int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE]; - float coefs[MAX_CHANNELS][BLOCK_MAX_SIZE] __attribute__((aligned(16))); - MDCTContext mdct_ctx[BLOCK_NB_SIZES]; - float *windows[BLOCK_NB_SIZES]; - FFTSample mdct_tmp[BLOCK_MAX_SIZE] __attribute__((aligned(16))); /* temporary storage for imdct */ - /* output buffer for one frame and the last for IMDCT windowing */ - float frame_out[MAX_CHANNELS][BLOCK_MAX_SIZE * 2] __attribute__((aligned(16))); - /* last frame info */ - uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */ - int last_bitoffset; - int last_superframe_len; - float noise_table[NOISE_TAB_SIZE]; - int noise_index; - float noise_mult; /* XXX: suppress that and integrate it in the noise array */ - /* lsp_to_curve tables */ - float lsp_cos_table[BLOCK_MAX_SIZE]; - float lsp_pow_e_table[256]; - float lsp_pow_m_table1[(1 << LSP_POW_BITS)]; - float lsp_pow_m_table2[(1 << LSP_POW_BITS)]; +#include "wma.h" -#ifdef TRACE - int frame_count; -#endif -} WMADecodeContext; +#undef NDEBUG +#include -typedef struct CoefVLCTable { - int n; /* total number of codes */ - const uint32_t *huffcodes; /* VLC bit values */ - const uint8_t *huffbits; /* VLC bit size */ - const uint16_t *levels; /* table to build run/level tables */ -} CoefVLCTable; +#define EXPVLCBITS 8 +#define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS) -static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len); +#define HGAINVLCBITS 9 +#define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS) -#include "wmadata.h" +static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); #ifdef TRACE -static void dump_shorts(const char *name, const short *tab, int n) +static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n) { int i; - tprintf("%s[%d]:\n", name, n); + tprintf(s->avctx, "%s[%d]:\n", name, n); for(i=0;iavctx, "%4d: ", i); + tprintf(s->avctx, " %5d.0", tab[i]); if ((i & 7) == 7) - tprintf("\n"); + tprintf(s->avctx, "\n"); } } -static void dump_floats(const char *name, int prec, const float *tab, int n) +static void dump_floats(WMACodecContext *s, const char *name, int prec, const float *tab, int n) { int i; - tprintf("%s[%d]:\n", name, n); + tprintf(s->avctx, "%s[%d]:\n", name, n); for(i=0;iavctx, "%4d: ", i); + tprintf(s->avctx, " %8.*f", prec, tab[i]); if ((i & 7) == 7) - tprintf("\n"); + tprintf(s->avctx, "\n"); } if ((i & 7) != 0) - tprintf("\n"); + tprintf(s->avctx, "\n"); } #endif -/* XXX: use same run/length optimization as mpeg decoders */ -static void init_coef_vlc(VLC *vlc, - uint16_t **prun_table, uint16_t **plevel_table, - const CoefVLCTable *vlc_table) -{ - int n = vlc_table->n; - const uint8_t *table_bits = vlc_table->huffbits; - const uint32_t *table_codes = vlc_table->huffcodes; - const uint16_t *levels_table = vlc_table->levels; - uint16_t *run_table, *level_table; - const uint16_t *p; - int i, l, j, level; - - init_vlc(vlc, 9, n, table_bits, 1, 1, table_codes, 4, 4, 0); - - run_table = av_malloc(n * sizeof(uint16_t)); - level_table = av_malloc(n * sizeof(uint16_t)); - p = levels_table; - i = 2; - level = 1; - while (i < n) { - l = *p++; - for(j=0;jpriv_data; + WMACodecContext *s = avctx->priv_data; int i, flags1, flags2; - float *window; uint8_t *extradata; - float bps1, high_freq; - volatile float bps; - int sample_rate1; - int coef_vlc_table; - - s->sample_rate = avctx->sample_rate; - s->nb_channels = avctx->channels; - s->bit_rate = avctx->bit_rate; - s->block_align = avctx->block_align; - - if (avctx->codec->id == CODEC_ID_WMAV1) { - s->version = 1; - } else { - s->version = 2; - } + + s->avctx = avctx; /* extract flag infos */ flags1 = 0; flags2 = 0; extradata = avctx->extradata; - if (s->version == 1 && avctx->extradata_size >= 4) { - flags1 = extradata[0] | (extradata[1] << 8); - flags2 = extradata[2] | (extradata[3] << 8); - } else if (s->version == 2 && avctx->extradata_size >= 6) { - flags1 = extradata[0] | (extradata[1] << 8) | - (extradata[2] << 16) | (extradata[3] << 24); - flags2 = extradata[4] | (extradata[5] << 8); + if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) { + flags1 = AV_RL16(extradata); + flags2 = AV_RL16(extradata+2); + } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { + flags1 = AV_RL32(extradata); + flags2 = AV_RL16(extradata+4); } +// for(i=0; iextradata_size; i++) +// av_log(NULL, AV_LOG_ERROR, "%02X ", extradata[i]); + s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; - /* compute MDCT block size */ - if (s->sample_rate <= 16000) { - s->frame_len_bits = 9; - } else if (s->sample_rate <= 22050 || - (s->sample_rate <= 32000 && s->version == 1)) { - s->frame_len_bits = 10; - } else { - s->frame_len_bits = 11; - } - s->frame_len = 1 << s->frame_len_bits; - if (s->use_variable_block_len) { - int nb_max, nb; - nb = ((flags2 >> 3) & 3) + 1; - if ((s->bit_rate / s->nb_channels) >= 32000) - nb += 2; - nb_max = s->frame_len_bits - BLOCK_MIN_BITS; - if (nb > nb_max) - nb = nb_max; - s->nb_block_sizes = nb + 1; - } else { - s->nb_block_sizes = 1; - } - - /* init rate dependant parameters */ - s->use_noise_coding = 1; - high_freq = s->sample_rate * 0.5; - - /* if version 2, then the rates are normalized */ - sample_rate1 = s->sample_rate; - if (s->version == 2) { - if (sample_rate1 >= 44100) - sample_rate1 = 44100; - else if (sample_rate1 >= 22050) - sample_rate1 = 22050; - else if (sample_rate1 >= 16000) - sample_rate1 = 16000; - else if (sample_rate1 >= 11025) - sample_rate1 = 11025; - else if (sample_rate1 >= 8000) - sample_rate1 = 8000; - } - - bps = (float)s->bit_rate / (float)(s->nb_channels * s->sample_rate); - s->byte_offset_bits = av_log2((int)(bps * s->frame_len / 8.0)) + 2; - - /* compute high frequency value and choose if noise coding should - be activated */ - bps1 = bps; - if (s->nb_channels == 2) - bps1 = bps * 1.6; - if (sample_rate1 == 44100) { - if (bps1 >= 0.61) - s->use_noise_coding = 0; - else - high_freq = high_freq * 0.4; - } else if (sample_rate1 == 22050) { - if (bps1 >= 1.16) - s->use_noise_coding = 0; - else if (bps1 >= 0.72) - high_freq = high_freq * 0.7; - else - high_freq = high_freq * 0.6; - } else if (sample_rate1 == 16000) { - if (bps > 0.5) - high_freq = high_freq * 0.5; - else - high_freq = high_freq * 0.3; - } else if (sample_rate1 == 11025) { - high_freq = high_freq * 0.7; - } else if (sample_rate1 == 8000) { - if (bps <= 0.625) { - high_freq = high_freq * 0.5; - } else if (bps > 0.75) { - s->use_noise_coding = 0; - } else { - high_freq = high_freq * 0.65; - } - } else { - if (bps >= 0.8) { - high_freq = high_freq * 0.75; - } else if (bps >= 0.6) { - high_freq = high_freq * 0.6; - } else { - high_freq = high_freq * 0.5; - } - } - dprintf("flags1=0x%x flags2=0x%x\n", flags1, flags2); - dprintf("version=%d channels=%d sample_rate=%d bitrate=%d block_align=%d\n", - s->version, s->nb_channels, s->sample_rate, s->bit_rate, - s->block_align); - dprintf("bps=%f bps1=%f high_freq=%f bitoffset=%d\n", - bps, bps1, high_freq, s->byte_offset_bits); - dprintf("use_noise_coding=%d use_exp_vlc=%d nb_block_sizes=%d\n", - s->use_noise_coding, s->use_exp_vlc, s->nb_block_sizes); - - /* compute the scale factor band sizes for each MDCT block size */ - { - int a, b, pos, lpos, k, block_len, i, j, n; - const uint8_t *table; - - if (s->version == 1) { - s->coefs_start = 3; - } else { - s->coefs_start = 0; - } - for(k = 0; k < s->nb_block_sizes; k++) { - block_len = s->frame_len >> k; - - if (s->version == 1) { - lpos = 0; - for(i=0;i<25;i++) { - a = wma_critical_freqs[i]; - b = s->sample_rate; - pos = ((block_len * 2 * a) + (b >> 1)) / b; - if (pos > block_len) - pos = block_len; - s->exponent_bands[0][i] = pos - lpos; - if (pos >= block_len) { - i++; - break; - } - lpos = pos; - } - s->exponent_sizes[0] = i; - } else { - /* hardcoded tables */ - table = NULL; - a = s->frame_len_bits - BLOCK_MIN_BITS - k; - if (a < 3) { - if (s->sample_rate >= 44100) - table = exponent_band_44100[a]; - else if (s->sample_rate >= 32000) - table = exponent_band_32000[a]; - else if (s->sample_rate >= 22050) - table = exponent_band_22050[a]; - } - if (table) { - n = *table++; - for(i=0;iexponent_bands[k][i] = table[i]; - s->exponent_sizes[k] = n; - } else { - j = 0; - lpos = 0; - for(i=0;i<25;i++) { - a = wma_critical_freqs[i]; - b = s->sample_rate; - pos = ((block_len * 2 * a) + (b << 1)) / (4 * b); - pos <<= 2; - if (pos > block_len) - pos = block_len; - if (pos > lpos) - s->exponent_bands[k][j++] = pos - lpos; - if (pos >= block_len) - break; - lpos = pos; - } - s->exponent_sizes[k] = j; - } - } - - /* max number of coefs */ - s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; - /* high freq computation */ - s->high_band_start[k] = (int)((block_len * 2 * high_freq) / - s->sample_rate + 0.5); - n = s->exponent_sizes[k]; - j = 0; - pos = 0; - for(i=0;iexponent_bands[k][i]; - end = pos; - if (start < s->high_band_start[k]) - start = s->high_band_start[k]; - if (end > s->coefs_end[k]) - end = s->coefs_end[k]; - if (end > start) - s->exponent_high_bands[k][j++] = end - start; - } - s->exponent_high_sizes[k] = j; -#if 0 - tprintf("%5d: coefs_end=%d high_band_start=%d nb_high_bands=%d: ", - s->frame_len >> k, - s->coefs_end[k], - s->high_band_start[k], - s->exponent_high_sizes[k]); - for(j=0;jexponent_high_sizes[k];j++) - tprintf(" %d", s->exponent_high_bands[k][j]); - tprintf("\n"); -#endif - } - } - -#ifdef TRACE - { - int i, j; - for(i = 0; i < s->nb_block_sizes; i++) { - tprintf("%5d: n=%2d:", - s->frame_len >> i, - s->exponent_sizes[i]); - for(j=0;jexponent_sizes[i];j++) - tprintf(" %d", s->exponent_bands[i][j]); - tprintf("\n"); - } - } -#endif + if(ff_wma_init(avctx, flags2)<0) + return -1; /* init MDCT */ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1); - /* init MDCT windows : simple sinus window */ - for(i = 0; i < s->nb_block_sizes; i++) { - int n, j; - float alpha; - n = 1 << (s->frame_len_bits - i); - window = av_malloc(sizeof(float) * n); - alpha = M_PI / (2.0 * n); - for(j=0;jwindows[i] = window; - } - - s->reset_block_lengths = 1; - if (s->use_noise_coding) { - - /* init the noise generator */ - if (s->use_exp_vlc) - s->noise_mult = 0.02; - else - s->noise_mult = 0.04; - -#ifdef TRACE - for(i=0;inoise_table[i] = 1.0 * s->noise_mult; -#else - { - unsigned int seed; - float norm; - seed = 1; - norm = (1.0 / (float)(1LL << 31)) * sqrt(3) * s->noise_mult; - for(i=0;inoise_table[i] = (float)((int)seed) * norm; - } - } -#endif - init_vlc(&s->hgain_vlc, 9, sizeof(hgain_huffbits), - hgain_huffbits, 1, 1, - hgain_huffcodes, 2, 2, 0); + init_vlc(&s->hgain_vlc, HGAINVLCBITS, sizeof(ff_wma_hgain_huffbits), + ff_wma_hgain_huffbits, 1, 1, + ff_wma_hgain_huffcodes, 2, 2, 0); } if (s->use_exp_vlc) { - init_vlc(&s->exp_vlc, 9, sizeof(scale_huffbits), - scale_huffbits, 1, 1, - scale_huffcodes, 4, 4, 0); + init_vlc(&s->exp_vlc, EXPVLCBITS, sizeof(ff_wma_scale_huffbits), //FIXME move out of context + ff_wma_scale_huffbits, 1, 1, + ff_wma_scale_huffcodes, 4, 4, 0); } else { wma_lsp_to_curve_init(s, s->frame_len); } - /* choose the VLC tables for the coefficients */ - coef_vlc_table = 2; - if (s->sample_rate >= 32000) { - if (bps1 < 0.72) - coef_vlc_table = 0; - else if (bps1 < 1.16) - coef_vlc_table = 1; - } - - init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0], - &coef_vlcs[coef_vlc_table * 2]); - init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], - &coef_vlcs[coef_vlc_table * 2 + 1]); return 0; } -/* interpolate values for a bigger or smaller block. The block must - have multiple sizes */ -static void interpolate_array(float *scale, int old_size, int new_size) -{ - int i, j, jincr, k; - float v; - - if (new_size > old_size) { - jincr = new_size / old_size; - j = new_size; - for(i = old_size - 1; i >=0; i--) { - v = scale[i]; - k = jincr; - do { - scale[--j] = v; - } while (--k); - } - } else if (new_size < old_size) { - j = 0; - jincr = old_size / new_size; - for(i = 0; i < new_size; i++) { - scale[i] = scale[j]; - j += jincr; - } - } -} - -/* compute x^-0.25 with an exponent and mantissa table. We use linear - interpolation to reduce the mantissa table size at a small speed - expense (linear interpolation approximately doubles the number of - bits of precision). */ -static inline float pow_m1_4(WMADecodeContext *s, float x) +/** + * compute x^-0.25 with an exponent and mantissa table. We use linear + * interpolation to reduce the mantissa table size at a small speed + * expense (linear interpolation approximately doubles the number of + * bits of precision). + */ +static inline float pow_m1_4(WMACodecContext *s, float x) { union { float f; @@ -571,7 +154,7 @@ static inline float pow_m1_4(WMADecodeContext *s, float x) return s->lsp_pow_e_table[e] * (a + b * t.f); } -static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len) +static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len) { float wdel, a, b; int i, e, m; @@ -608,9 +191,11 @@ static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len) #endif } -/* NOTE: We use the same code as Vorbis here */ -/* XXX: optimize it further with SSE/3Dnow */ -static void wma_lsp_to_curve(WMADecodeContext *s, +/** + * NOTE: We use the same code as Vorbis here + * @todo optimize it further with SSE/3Dnow + */ +static void wma_lsp_to_curve(WMACodecContext *s, float *out, float *val_max_ptr, int n, float *lsp) { @@ -637,8 +222,10 @@ static void wma_lsp_to_curve(WMADecodeContext *s, *val_max_ptr = val_max; } -/* decode exponents coded with LSP coefficients (same idea as Vorbis) */ -static void decode_exp_lsp(WMADecodeContext *s, int ch) +/** + * decode exponents coded with LSP coefficients (same idea as Vorbis) + */ +static void decode_exp_lsp(WMACodecContext *s, int ch) { float lsp_coefs[NB_LSP_COEFS]; int val, i; @@ -648,15 +235,17 @@ static void decode_exp_lsp(WMADecodeContext *s, int ch) val = get_bits(&s->gb, 3); else val = get_bits(&s->gb, 4); - lsp_coefs[i] = lsp_codebook[i][val]; + lsp_coefs[i] = ff_wma_lsp_codebook[i][val]; } wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch], s->block_len, lsp_coefs); } -/* decode exponents coded with VLC codes */ -static int decode_exp_vlc(WMADecodeContext *s, int ch) +/** + * decode exponents coded with VLC codes + */ +static int decode_exp_vlc(WMACodecContext *s, int ch) { int last_exp, n, code; const uint16_t *ptr, *band_ptr; @@ -676,10 +265,11 @@ static int decode_exp_vlc(WMADecodeContext *s, int ch) do { *q++ = v; } while (--n); - } - last_exp = 36; + }else + last_exp = 36; + while (q < q_end) { - code = get_vlc(&s->gb, &s->exp_vlc); + code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); if (code < 0) return -1; /* NOTE: this offset is the same as MPEG4 AAC ! */ @@ -697,23 +287,74 @@ static int decode_exp_vlc(WMADecodeContext *s, int ch) return 0; } -/* return 0 if OK. return 1 if last block of frame. return -1 if - unrecorrable error. */ -static int wma_decode_block(WMADecodeContext *s) + +/** + * Apply MDCT window and add into output. + * + * We ensure that when the windows overlap their squared sum + * is always 1 (MDCT reconstruction rule). + */ +static void wma_window(WMACodecContext *s, float *out) +{ + float *in = s->output; + int block_len, bsize, n; + + /* left part */ + if (s->block_len_bits <= s->prev_block_len_bits) { + block_len = s->block_len; + bsize = s->frame_len_bits - s->block_len_bits; + + s->dsp.vector_fmul_add_add(out, in, s->windows[bsize], + out, 0, block_len, 1); + + } else { + block_len = 1 << s->prev_block_len_bits; + n = (s->block_len - block_len) / 2; + bsize = s->frame_len_bits - s->prev_block_len_bits; + + s->dsp.vector_fmul_add_add(out+n, in+n, s->windows[bsize], + out+n, 0, block_len, 1); + + memcpy(out+n+block_len, in+n+block_len, n*sizeof(float)); + } + + out += s->block_len; + in += s->block_len; + + /* right part */ + if (s->block_len_bits <= s->next_block_len_bits) { + block_len = s->block_len; + bsize = s->frame_len_bits - s->block_len_bits; + + s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len); + + } else { + block_len = 1 << s->next_block_len_bits; + n = (s->block_len - block_len) / 2; + bsize = s->frame_len_bits - s->next_block_len_bits; + + memcpy(out, in, n*sizeof(float)); + + s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len); + + memset(out+n+block_len, 0, n*sizeof(float)); + } +} + + +/** + * @return 0 if OK. 1 if last block of frame. return -1 if + * unrecorrable error. + */ +static int wma_decode_block(WMACodecContext *s) { int n, v, a, ch, code, bsize; - int coef_nb_bits, total_gain, parse_exponents; - float window[BLOCK_MAX_SIZE * 2]; -// XXX: FIXME!! there's a bug somewhere which makes this mandatory under altivec -#ifdef HAVE_ALTIVEC - volatile int nb_coefs[MAX_CHANNELS] __attribute__((aligned(16))); -#else + int coef_nb_bits, total_gain; int nb_coefs[MAX_CHANNELS]; -#endif float mdct_norm; #ifdef TRACE - tprintf("***decode_block: %d:%d\n", s->frame_count - 1, s->block_num); + tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num); #endif /* compute current block length */ @@ -752,11 +393,11 @@ static int wma_decode_block(WMADecodeContext *s) return -1; if (s->nb_channels == 2) { - s->ms_stereo = get_bits(&s->gb, 1); + s->ms_stereo = get_bits1(&s->gb); } v = 0; for(ch = 0; ch < s->nb_channels; ch++) { - a = get_bits(&s->gb, 1); + a = get_bits1(&s->gb); s->channel_coded[ch] = a; v |= a; } @@ -777,16 +418,7 @@ static int wma_decode_block(WMADecodeContext *s) break; } - if (total_gain < 15) - coef_nb_bits = 13; - else if (total_gain < 32) - coef_nb_bits = 12; - else if (total_gain < 40) - coef_nb_bits = 11; - else if (total_gain < 45) - coef_nb_bits = 10; - else - coef_nb_bits = 9; + coef_nb_bits= ff_wma_total_gain_to_bits(total_gain); /* compute number of coefficients */ n = s->coefs_end[bsize] - s->coefs_start; @@ -801,7 +433,7 @@ static int wma_decode_block(WMADecodeContext *s) int i, n, a; n = s->exponent_high_sizes[bsize]; for(i=0;igb, 1); + a = get_bits1(&s->gb); s->high_band_coded[ch][i] = a; /* if noise coding, the coefficients are not transmitted */ if (a) @@ -820,7 +452,7 @@ static int wma_decode_block(WMADecodeContext *s) if (val == (int)0x80000000) { val = get_bits(&s->gb, 7) - 19; } else { - code = get_vlc(&s->gb, &s->hgain_vlc); + code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX); if (code < 0) return -1; val += code - 18; @@ -832,13 +464,9 @@ static int wma_decode_block(WMADecodeContext *s) } } - /* exposant can be interpolated in short blocks. */ - parse_exponents = 1; - if (s->block_len_bits != s->frame_len_bits) { - parse_exponents = get_bits(&s->gb, 1); - } - - if (parse_exponents) { + /* exponents can be reused in short blocks. */ + if ((s->block_len_bits == s->frame_len_bits) || + get_bits1(&s->gb)) { for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { if (s->use_exp_vlc) { @@ -847,13 +475,7 @@ static int wma_decode_block(WMADecodeContext *s) } else { decode_exp_lsp(s, ch); } - } - } - } else { - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits, - s->block_len); + s->exponents_bsize[ch] = bsize; } } } @@ -864,7 +486,7 @@ static int wma_decode_block(WMADecodeContext *s) VLC *coef_vlc; int level, run, sign, tindex; int16_t *ptr, *eptr; - const int16_t *level_table, *run_table; + const uint16_t *level_table, *run_table; /* special VLC tables are used for ms stereo because there is potentially less energy there */ @@ -877,7 +499,7 @@ static int wma_decode_block(WMADecodeContext *s) eptr = ptr + nb_coefs[ch]; memset(ptr, 0, s->block_len * sizeof(int16_t)); for(;;) { - code = get_vlc(&s->gb, coef_vlc); + code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX); if (code < 0) return -1; if (code == 1) { @@ -894,12 +516,15 @@ static int wma_decode_block(WMADecodeContext *s) run = run_table[code]; level = level_table[code]; } - sign = get_bits(&s->gb, 1); + sign = get_bits1(&s->gb); if (!sign) level = -level; ptr += run; if (ptr >= eptr) - return -1; + { + av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); + break; + } *ptr++ = level; /* NOTE: EOB can be omitted */ if (ptr >= eptr) @@ -924,12 +549,13 @@ static int wma_decode_block(WMADecodeContext *s) for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { int16_t *coefs1; - float *coefs, *exponents, mult, mult1, noise, *exp_ptr; - int i, j, n, n1, last_high_band; + float *coefs, *exponents, mult, mult1, noise; + int i, j, n, n1, last_high_band, esize; float exp_power[HIGH_BAND_MAX_SIZE]; coefs1 = s->coefs1[ch]; exponents = s->exponents[ch]; + esize = s->exponents_bsize[ch]; mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; mult *= mdct_norm; coefs = s->coefs[ch]; @@ -937,16 +563,16 @@ static int wma_decode_block(WMADecodeContext *s) mult1 = mult; /* very low freqs : noise */ for(i = 0;i < s->coefs_start; i++) { - *coefs++ = s->noise_table[s->noise_index] * (*exponents++) * mult1; + *coefs++ = s->noise_table[s->noise_index] * + exponents[i<>esize] * mult1; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); } n1 = s->exponent_high_sizes[bsize]; /* compute power of high bands */ - exp_ptr = exponents + - s->high_band_start[bsize] - - s->coefs_start; + exponents = s->exponents[ch] + + (s->high_band_start[bsize]<exponent_high_bands[s->frame_len_bits - @@ -955,17 +581,18 @@ static int wma_decode_block(WMADecodeContext *s) float e2, v; e2 = 0; for(i = 0;i < n; i++) { - v = exp_ptr[i]; + v = exponents[i<>esize]; e2 += v * v; } exp_power[j] = e2 / n; last_high_band = j; - tprintf("%d: power=%f (%d)\n", j, exp_power[j], n); + tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n); } - exp_ptr += n; + exponents += n<exponents[ch] + (s->coefs_start<high_band_start[bsize] - @@ -984,21 +611,25 @@ static int wma_decode_block(WMADecodeContext *s) for(i = 0;i < n; i++) { noise = s->noise_table[s->noise_index]; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - *coefs++ = (*exponents++) * noise * mult1; + *coefs++ = noise * + exponents[i<>esize] * mult1; } + exponents += n<noise_table[s->noise_index]; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - *coefs++ = ((*coefs1++) + noise) * (*exponents++) * mult; + *coefs++ = ((*coefs1++) + noise) * + exponents[i<>esize] * mult; } + exponents += n<block_len - s->coefs_end[bsize]; - mult1 = mult * exponents[-1]; + mult1 = mult * exponents[((-1<>esize]; for(i = 0; i < n; i++) { *coefs++ = s->noise_table[s->noise_index] * mult1; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); @@ -1009,7 +640,7 @@ static int wma_decode_block(WMADecodeContext *s) *coefs++ = 0.0; n = nb_coefs[ch]; for(i = 0;i < n; i++) { - *coefs++ = coefs1[i] * exponents[i] * mult; + *coefs++ = coefs1[i] * exponents[i<>esize] * mult; } n = s->block_len - s->coefs_end[bsize]; for(i = 0;i < n; i++) @@ -1021,8 +652,8 @@ static int wma_decode_block(WMADecodeContext *s) #ifdef TRACE for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { - dump_floats("exponents", 3, s->exponents[ch], s->block_len); - dump_floats("coefs", 1, s->coefs[ch], s->block_len); + dump_floats(s, "exponents", 3, s->exponents[ch], s->block_len); + dump_floats(s, "coefs", 1, s->coefs[ch], s->block_len); } } #endif @@ -1035,7 +666,7 @@ static int wma_decode_block(WMADecodeContext *s) /* no need to optimize this case because it should almost never happen */ if (!s->channel_coded[0]) { - tprintf("rare ms-stereo case happened\n"); + tprintf(s->avctx, "rare ms-stereo case happened\n"); memset(s->coefs[0], 0, sizeof(float) * s->block_len); s->channel_coded[0] = 1; } @@ -1048,85 +679,23 @@ static int wma_decode_block(WMADecodeContext *s) } } - /* build the window : we ensure that when the windows overlap - their squared sum is always 1 (MDCT reconstruction rule) */ - /* XXX: merge with output */ - { - int i, next_block_len, block_len, prev_block_len, n; - float *wptr; - - block_len = s->block_len; - prev_block_len = 1 << s->prev_block_len_bits; - next_block_len = 1 << s->next_block_len_bits; - - /* right part */ - wptr = window + block_len; - if (block_len <= next_block_len) { - for(i=0;iwindows[bsize][i]; - } else { - /* overlap */ - n = (block_len / 2) - (next_block_len / 2); - for(i=0;iwindows[s->frame_len_bits - s->next_block_len_bits][i]; - for(i=0;iwindows[bsize][i]; - } else { - /* overlap */ - n = (block_len / 2) - (prev_block_len / 2); - for(i=0;iwindows[s->frame_len_bits - s->prev_block_len_bits][i]; - for(i=0;inb_channels; ch++) { if (s->channel_coded[ch]) { - FFTSample output[BLOCK_MAX_SIZE * 2] __attribute__((aligned(16))); - float *ptr; - int i, n4, index, n; + int n4, index, n; n = s->block_len; n4 = s->block_len / 2; - ff_imdct_calc(&s->mdct_ctx[bsize], - output, s->coefs[ch], s->mdct_tmp); - - /* XXX: optimize all that by build the window and - multipying/adding at the same time */ - /* multiply by the window */ - for(i=0;imdct_ctx[bsize].fft.imdct_calc(&s->mdct_ctx[bsize], + s->output, s->coefs[ch], s->mdct_tmp); - /* add in the frame */ + /* multiply by the window and add in the frame */ index = (s->frame_len / 2) + s->block_pos - n4; - ptr = &s->frame_out[ch][index]; - for(i=0;iframe_out[ch][index]); /* specific fast case for ms-stereo : add to second channel if it is not coded */ if (s->ms_stereo && !s->channel_coded[1]) { - ptr = &s->frame_out[1][index]; - for(i=0;iframe_out[1][index]); } } } @@ -1141,14 +710,14 @@ static int wma_decode_block(WMADecodeContext *s) } /* decode a frame of frame_len samples */ -static int wma_decode_frame(WMADecodeContext *s, int16_t *samples) +static int wma_decode_frame(WMACodecContext *s, int16_t *samples) { - int ret, i, n, a, ch, incr; + int ret, i, n, ch, incr; int16_t *ptr; float *iptr; #ifdef TRACE - tprintf("***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len); + tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len); #endif /* read each block */ @@ -1170,43 +739,38 @@ static int wma_decode_frame(WMADecodeContext *s, int16_t *samples) iptr = s->frame_out[ch]; for(i=0;i 32767) - a = 32767; - else if (a < -32768) - a = -32768; - *ptr = a; + *ptr = av_clip_int16(lrintf(*iptr++)); ptr += incr; } /* prepare for next block */ memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len], s->frame_len * sizeof(float)); - /* XXX: suppress this */ - memset(&s->frame_out[ch][s->frame_len], 0, - s->frame_len * sizeof(float)); } #ifdef TRACE - dump_shorts("samples", samples, n * s->nb_channels); + dump_shorts(s, "samples", samples, n * s->nb_channels); #endif return 0; } static int wma_decode_superframe(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - WMADecodeContext *s = avctx->priv_data; + WMACodecContext *s = avctx->priv_data; int nb_frames, bit_offset, i, pos, len; uint8_t *q; int16_t *samples; - tprintf("***decode_superframe:\n"); + tprintf(avctx, "***decode_superframe:\n"); if(buf_size==0){ s->last_superframe_len = 0; return 0; } + if (buf_size < s->block_align) + return 0; + buf_size = s->block_align; samples = data; @@ -1214,7 +778,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, if (s->use_bit_reservoir) { /* read super frame header */ - get_bits(&s->gb, 4); /* super frame index */ + skip_bits(&s->gb, 4); /* super frame index */ nb_frames = get_bits(&s->gb, 4) - 1; bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); @@ -1227,7 +791,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, goto fail; q = s->last_superframe + s->last_superframe_len; len = bit_offset; - while (len > 0) { + while (len > 7) { *q++ = (get_bits)(&s->gb, 8); len -= 8; } @@ -1277,6 +841,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, goto fail; samples += s->nb_channels * s->frame_len; } + +//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d outbytes:%d eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len, (int8_t *)samples - (int8_t *)data, s->block_align); + *data_size = (int8_t *)samples - (int8_t *)data; return s->block_align; fail: @@ -1285,41 +852,17 @@ static int wma_decode_superframe(AVCodecContext *avctx, return -1; } -static int wma_decode_end(AVCodecContext *avctx) -{ - WMADecodeContext *s = avctx->priv_data; - int i; - - for(i = 0; i < s->nb_block_sizes; i++) - ff_mdct_end(&s->mdct_ctx[i]); - for(i = 0; i < s->nb_block_sizes; i++) - av_free(s->windows[i]); - - if (s->use_exp_vlc) { - free_vlc(&s->exp_vlc); - } - if (s->use_noise_coding) { - free_vlc(&s->hgain_vlc); - } - for(i = 0;i < 2; i++) { - free_vlc(&s->coef_vlc[i]); - av_free(s->run_table[i]); - av_free(s->level_table[i]); - } - - return 0; -} - AVCodec wmav1_decoder = { "wmav1", CODEC_TYPE_AUDIO, CODEC_ID_WMAV1, - sizeof(WMADecodeContext), + sizeof(WMACodecContext), wma_decode_init, NULL, - wma_decode_end, + ff_wma_end, wma_decode_superframe, + .long_name = "Windows Media Audio 1", }; AVCodec wmav2_decoder = @@ -1327,9 +870,10 @@ AVCodec wmav2_decoder = "wmav2", CODEC_TYPE_AUDIO, CODEC_ID_WMAV2, - sizeof(WMADecodeContext), + sizeof(WMACodecContext), wma_decode_init, NULL, - wma_decode_end, + ff_wma_end, wma_decode_superframe, + .long_name = "Windows Media Audio 2", };