X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fwmadec.c;h=ef3cc7a3307c10b7afe957974aab200baefd5ff9;hb=2c48a21c4fb1a591321181bc84207534f506ea9d;hp=ab02feb7284c3ac48f839435b1f1a132e8076bfc;hpb=983e3246b7528e6ffc0cc347d54b86e161140fe6;p=ffmpeg diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index ab02feb7284..ef3cc7a3307 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -2,561 +2,137 @@ * 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 */ /** * @file wmadec.c * WMA compatible decoder. + * This decoder handles Microsoft Windows Media Audio data, versions 1 & 2. + * WMA v1 is identified by audio format 0x160 in Microsoft media files + * (ASF/AVI/WAV). WMA v2 is identified by audio format 0x161. + * + * To use this decoder, a calling application must supply the extra data + * bytes provided with the WMA data. These are the extra, codec-specific + * bytes at the end of a WAVEFORMATEX data structure. Transmit these bytes + * to the decoder using the extradata[_size] fields in AVCodecContext. There + * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data. */ #include "avcodec.h" -#include "dsputil.h" - -//#define DEBUG_PARAMS -//#define DEBUG_TRACE - -/* 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 4096 - -#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)]; -} WMADecodeContext; - -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; - -static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len); - -#include "wmadata.h" - -#ifdef DEBUG_TRACE -#include -int frame_count; - -static FILE *flog; - -void trace(const char *fmt, ...) -{ - va_list ap; - +#include "wma.h" - if (!flog) { - flog = fopen("/tmp/out.log", "w"); - setlinebuf(flog); - } +#undef NDEBUG +#include - va_start(ap, fmt); - vfprintf(flog, fmt, ap); - va_end(ap); -} +#define EXPVLCBITS 8 +#define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS) -#define get_bits(s, n) get_bits_trace(s, n) -#define get_vlc(s, vlc) get_vlc_trace(s, vlc) +#define HGAINVLCBITS 9 +#define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS) -unsigned int get_bits_trace(GetBitContext *s, int n) -{ - unsigned int val; - val = (get_bits)(s, n); - trace("get_bits(%d) : 0x%x\n", n, val); - return val; -} +static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); -static int get_vlc_trace(GetBitContext *s, VLC *vlc) -{ - int code; - code = (get_vlc)(s, vlc); - trace("get_vlc() : %d\n", code); - return code; -} - -static void dump_shorts(const char *name, const short *tab, int n) +#ifdef TRACE +static void dump_shorts(WMADecodeContext *s, const char *name, const short *tab, int n) { int i; - trace("%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) - trace("\n"); + tprintf(s->avctx, "\n"); } } -static void dump_floats(const char *name, int prec, const float *tab, int n) +static void dump_floats(WMADecodeContext *s, const char *name, int prec, const float *tab, int n) { int i; - trace("%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) - trace("\n"); + tprintf(s->avctx, "\n"); } if ((i & 7) != 0) - trace("\n"); + tprintf(s->avctx, "\n"); } - -#else - -#define trace(fmt, ...) - #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); - - 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, 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) { + if (avctx->codec->id == CODEC_ID_WMAV1 && 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) | + } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { + flags1 = extradata[0] | (extradata[1] << 8) | (extradata[2] << 16) | (extradata[3] << 24); flags2 = extradata[4] | (extradata[5] << 8); } +// 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; - } - } -#ifdef DEBUG_PARAMS - printf("flags1=0x%x flags2=0x%x\n", flags1, flags2); - printf("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); - printf("bps=%f bps1=%f high_freq=%f bitoffset=%d\n", - bps, bps1, high_freq, s->byte_offset_bits); - printf("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); -#endif - - /* 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 - trace("%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++) - trace(" %d", s->exponent_high_bands[k][j]); - trace("\n"); -#endif - } - } - -#ifdef DEBUG_TRACE - { - int i, j; - for(i = 0; i < s->nb_block_sizes; i++) { - trace("%5d: n=%2d:", - s->frame_len >> i, - s->exponent_sizes[i]); - for(j=0;jexponent_sizes[i];j++) - trace(" %d", s->exponent_bands[i][j]); - trace("\n"); - } - } -#endif + ff_wma_init(avctx, flags2); /* 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; - -#if defined(DEBUG_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); + 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); + 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 */ +/** + * 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; @@ -582,11 +158,13 @@ static void interpolate_array(float *scale, int old_size, int new_size) } } -/* 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; @@ -605,8 +183,8 @@ 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; @@ -642,10 +220,12 @@ 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, - float *out, float *val_max_ptr, +/** + * 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) { int i, j; @@ -671,8 +251,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; @@ -682,20 +264,22 @@ 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; float v, *q, max_scale, *q_end; - + band_ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; ptr = band_ptr; q = s->exponents[ch]; @@ -710,10 +294,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 ! */ @@ -731,22 +316,80 @@ 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]; int nb_coefs[MAX_CHANNELS]; float mdct_norm; - trace("***decode_block: %d:%d\n", frame_count - 1, s->block_num); +#ifdef TRACE + tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num); +#endif /* compute current block length */ if (s->use_variable_block_len) { n = av_log2(s->nb_block_sizes - 1) + 1; - + if (s->reset_block_lengths) { s->reset_block_lengths = 0; v = get_bits(&s->gb, n); @@ -803,17 +446,8 @@ static int wma_decode_block(WMADecodeContext *s) if (a != 127) 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; @@ -847,7 +481,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; @@ -858,13 +492,13 @@ 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) { for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { @@ -879,7 +513,7 @@ static int wma_decode_block(WMADecodeContext *s) } 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, + interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits, s->block_len); } } @@ -891,7 +525,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 */ @@ -904,7 +538,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) { @@ -926,7 +560,10 @@ static int wma_decode_block(WMADecodeContext *s) 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) @@ -937,7 +574,7 @@ static int wma_decode_block(WMADecodeContext *s) align_get_bits(&s->gb); } } - + /* normalize */ { int n4 = s->block_len / 2; @@ -967,16 +604,16 @@ static int wma_decode_block(WMADecodeContext *s) *coefs++ = s->noise_table[s->noise_index] * (*exponents++) * 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] - + exp_ptr = exponents + + s->high_band_start[bsize] - s->coefs_start; last_high_band = 0; /* avoid warning */ for(j=0;jexponent_high_bands[s->frame_len_bits - + n = s->exponent_high_bands[s->frame_len_bits - s->block_len_bits][j]; if (s->high_band_coded[ch][j]) { float e2, v; @@ -987,7 +624,7 @@ static int wma_decode_block(WMADecodeContext *s) } exp_power[j] = e2 / n; last_high_band = j; - trace("%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; } @@ -995,10 +632,10 @@ static int wma_decode_block(WMADecodeContext *s) /* main freqs and high freqs */ for(j=-1;jhigh_band_start[bsize] - + n = s->high_band_start[bsize] - s->coefs_start; } else { - n = s->exponent_high_bands[s->frame_len_bits - + n = s->exponent_high_bands[s->frame_len_bits - s->block_len_bits][j]; } if (j >= 0 && s->high_band_coded[ch][j]) { @@ -1045,15 +682,15 @@ static int wma_decode_block(WMADecodeContext *s) } } -#ifdef DEBUG_TRACE +#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 - + if (s->ms_stereo && s->channel_coded[1]) { float a, b; int i; @@ -1062,13 +699,11 @@ static int wma_decode_block(WMADecodeContext *s) /* no need to optimize this case because it should almost never happen */ if (!s->channel_coded[0]) { -#ifdef DEBUG_TRACE - trace("rare ms-stereo case happened\n"); -#endif + tprintf(s->avctx, "rare ms-stereo case happened\n"); memset(s->coefs[0], 0, sizeof(float) * s->block_len); s->channel_coded[0] = 1; } - + for(i = 0; i < s->block_len; i++) { a = s->coefs[0][i]; b = s->coefs[1][i]; @@ -1077,85 +712,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]); } } } @@ -1170,20 +743,22 @@ 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; int16_t *ptr; float *iptr; - trace("***decode_frame: %d size=%d\n", frame_count++, s->frame_len); +#ifdef TRACE + tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len); +#endif /* read each block */ s->block_num = 0; s->block_pos = 0; for(;;) { ret = wma_decode_block(s); - if (ret < 0) + if (ret < 0) return -1; if (ret) break; @@ -1208,32 +783,34 @@ static int wma_decode_frame(WMADecodeContext *s, int16_t *samples) /* 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 DEBUG_TRACE - dump_shorts("samples", samples, n * s->nb_channels); +#ifdef TRACE + dump_shorts(s, "samples", samples, n * s->nb_channels); #endif return 0; } -static int wma_decode_superframe(AVCodecContext *avctx, +static int wma_decode_superframe(AVCodecContext *avctx, void *data, int *data_size, 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; - - trace("***decode_superframe:\n"); + + tprintf(avctx, "***decode_superframe:\n"); + + if(buf_size==0){ + s->last_superframe_len = 0; + return 0; + } samples = data; init_get_bits(&s->gb, buf, buf_size*8); - + if (s->use_bit_reservoir) { /* read super frame header */ get_bits(&s->gb, 4); /* super frame index */ @@ -1244,19 +821,19 @@ static int wma_decode_superframe(AVCodecContext *avctx, if (s->last_superframe_len > 0) { // printf("skip=%d\n", s->last_bitoffset); /* add bit_offset bits to last frame */ - if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) > + if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) > MAX_CODED_SUPERFRAME_SIZE) 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; } if (len > 0) { *q++ = (get_bits)(&s->gb, len) << (8 - len); } - + /* XXX: bit_offset bits into last frame */ init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); /* skip unused bits */ @@ -1275,7 +852,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, len = pos & 7; if (len > 0) skip_bits(&s->gb, len); - + s->reset_block_lengths = 1; for(i=0;inb_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: @@ -1307,40 +887,15 @@ 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, }; @@ -1349,9 +904,9 @@ 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, };