* subframe in order to reconstruct the output samples.
*/
+#include <inttypes.h>
+
+#include "libavutil/float_dsp.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
+
#include "avcodec.h"
+#include "bitstream.h"
#include "internal.h"
-#include "get_bits.h"
#include "put_bits.h"
#include "wmaprodata.h"
-#include "dsputil.h"
#include "sinewin.h"
#include "wma.h"
+#include "wma_common.h"
/** current decoder limitations */
#define WMAPRO_MAX_CHANNELS 8 ///< max number of handled channels
#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size
#define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size
-#define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size
+#define WMAPRO_BLOCK_MAX_BITS 13 ///< log2 of max block size
+#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) ///< minimum block size
#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size
#define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes
static VLC vec2_vlc; ///< 2 coefficients per symbol
static VLC vec1_vlc; ///< 1 coefficient per symbol
static VLC coef_vlc[2]; ///< coefficient run length vlc codes
-static float sin64[33]; ///< sinus table for decorrelation
+static float sin64[33]; ///< sine table for decorrelation
/**
* @brief frame specific decoder context for a single channel
*/
-typedef struct {
+typedef struct WMAProChannelCtx {
int16_t prev_block_len; ///< length of the previous block
uint8_t transmit_coefs;
uint8_t num_subframes;
/**
* @brief channel group for channel transformations
*/
-typedef struct {
+typedef struct WMAProChannelGrp {
uint8_t num_channels; ///< number of channels in the group
int8_t transform; ///< transform on / off
int8_t transform_band[MAX_BANDS]; ///< controls if the transform is enabled for a certain band
typedef struct WMAProDecodeCtx {
/* generic decoder variables */
AVCodecContext* avctx; ///< codec context for av_log
- DSPContext dsp; ///< accelerated DSP functions
+ AVFloatDSPContext fdsp;
uint8_t frame_data[MAX_FRAMESIZE +
- FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
+ AV_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
PutBitContext pb; ///< context for filling the frame_data buffer
FFTContext mdct_ctx[WMAPRO_BLOCK_SIZES]; ///< MDCT context per block size
DECLARE_ALIGNED(32, float, tmp)[WMAPRO_BLOCK_MAX_SIZE]; ///< IMDCT output buffer
uint8_t bits_per_sample; ///< integer audio sample size for the unscaled IMDCT output (used to scale to [-1.0, 1.0])
uint16_t samples_per_frame; ///< number of samples to output
uint16_t log2_frame_size;
- int8_t num_channels; ///< number of channels in the stream (same as AVCodecContext.num_channels)
int8_t lfe_channel; ///< lfe channel index
uint8_t max_num_subframes;
uint8_t subframe_len_bits; ///< number of bits used for the subframe length
int16_t subwoofer_cutoffs[WMAPRO_BLOCK_SIZES]; ///< subwoofer cutoff values
/* packet decode state */
- GetBitContext pgb; ///< bitstream reader context for the packet
+ BitstreamContext pbc; ///< bitstream reader context for the packet
int next_packet_start; ///< start offset of the next wma packet in the demuxer packet
uint8_t packet_offset; ///< frame offset in the packet
uint8_t packet_sequence_number; ///< current packet number
/* frame decode state */
uint32_t frame_num; ///< current frame number (not used for decoding)
- GetBitContext gb; ///< bitstream reader context
+ BitstreamContext bc; ///< bitstream reader context
int buf_bit_size; ///< buffer size in bits
- float* samples; ///< current samplebuffer pointer
- float* samples_end; ///< maximum samplebuffer pointer
uint8_t drc_gain; ///< gain for the DRC tool
int8_t skip_frame; ///< skip output step
int8_t parsed_all_subframes; ///< all subframes decoded?
*@brief helper function to print the most important members of the context
*@param s context
*/
-static void av_cold dump_context(WMAProDecodeCtx *s)
+static av_cold void dump_context(WMAProDecodeCtx *s)
{
#define PRINT(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %d\n", a, b);
-#define PRINT_HEX(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %x\n", a, b);
+#define PRINT_HEX(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %"PRIx32"\n", a, b);
PRINT("ed sample bit depth", s->bits_per_sample);
PRINT_HEX("ed decode flags", s->decode_flags);
PRINT("log2 frame size", s->log2_frame_size);
PRINT("max num subframes", s->max_num_subframes);
PRINT("len prefix", s->len_prefix);
- PRINT("num channels", s->num_channels);
+ PRINT("num channels", s->avctx->channels);
}
/**
WMAProDecodeCtx *s = avctx->priv_data;
uint8_t *edata_ptr = avctx->extradata;
unsigned int channel_mask;
- int i;
+ int i, bits;
int log2_max_num_subframes;
int num_possible_block_sizes;
+ if (!avctx->block_align) {
+ av_log(avctx, AV_LOG_ERROR, "block_align is not set\n");
+ return AVERROR(EINVAL);
+ }
+
s->avctx = avctx;
- dsputil_init(&s->dsp, avctx);
+ avpriv_float_dsp_init(&s->fdsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
+
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
if (avctx->extradata_size >= 18) {
s->decode_flags = AV_RL16(edata_ptr+14);
s->bits_per_sample = AV_RL16(edata_ptr);
/** dump the extradata */
for (i = 0; i < avctx->extradata_size; i++)
- av_dlog(avctx, "[%x] ", avctx->extradata[i]);
- av_dlog(avctx, "\n");
+ ff_dlog(avctx, "[%x] ", avctx->extradata[i]);
+ ff_dlog(avctx, "\n");
} else {
- av_log_ask_for_sample(avctx, "Unknown extradata size\n");
- return AVERROR_INVALIDDATA;
+ avpriv_request_sample(avctx, "Unknown extradata size");
+ return AVERROR_PATCHWELCOME;
}
/** generic init */
s->len_prefix = (s->decode_flags & 0x40);
/** get frame len */
- s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate,
- 3, s->decode_flags);
+ bits = ff_wma_get_frame_len_bits(avctx->sample_rate, 3, s->decode_flags);
+ if (bits > WMAPRO_BLOCK_MAX_BITS) {
+ avpriv_request_sample(avctx, "14-bit block sizes");
+ return AVERROR_PATCHWELCOME;
+ }
+ s->samples_per_frame = 1 << bits;
/** subframe info */
log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3);
s->dynamic_range_compression = (s->decode_flags & 0x80);
if (s->max_num_subframes > MAX_SUBFRAMES) {
- av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %i\n",
+ av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %"PRId8"\n",
s->max_num_subframes);
return AVERROR_INVALIDDATA;
}
- s->num_channels = avctx->channels;
+ if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid minimum block size %"PRId8"\n",
+ s->max_num_subframes);
+ return AVERROR_INVALIDDATA;
+ }
- if (s->num_channels < 0) {
- av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels);
+ if (s->avctx->sample_rate <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
return AVERROR_INVALIDDATA;
- } else if (s->num_channels > WMAPRO_MAX_CHANNELS) {
- av_log_ask_for_sample(avctx, "unsupported number of channels\n");
+ }
+
+ if (avctx->channels < 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n",
+ avctx->channels);
+ return AVERROR_INVALIDDATA;
+ } else if (avctx->channels > WMAPRO_MAX_CHANNELS) {
+ avpriv_request_sample(avctx,
+ "More than %d channels", WMAPRO_MAX_CHANNELS);
return AVERROR_PATCHWELCOME;
}
/** init previous block len */
- for (i = 0; i < s->num_channels; i++)
+ for (i = 0; i < avctx->channels; i++)
s->channel[i].prev_block_len = s->samples_per_frame;
/** extract lfe channel position */
for (x = 0; x < num_possible_block_sizes; x++) {
int v = 0;
while (s->sfb_offsets[x][v + 1] << x < offset)
- ++v;
+ if (++v >= MAX_BANDS)
+ return AVERROR_INVALIDDATA;
s->sf_offsets[i][x][b] = v;
}
}
1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1))
/ (1 << (s->bits_per_sample - 1)));
- /** init MDCT windows: simple sinus window */
+ /** init MDCT windows: simple sine window */
for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) {
const int win_idx = WMAPRO_BLOCK_MAX_BITS - i;
ff_init_ff_sine_windows(win_idx);
dump_context(s);
avctx->channel_layout = channel_mask;
+
return 0;
}
/** 1 bit indicates if the subframe is of maximum length */
if (s->max_subframe_len_bit) {
- if (get_bits1(&s->gb))
- frame_len_shift = 1 + get_bits(&s->gb, s->subframe_len_bits-1);
+ if (bitstream_read_bit(&s->bc))
+ frame_len_shift = 1 + bitstream_read(&s->bc,
+ s->subframe_len_bits - 1);
} else
- frame_len_shift = get_bits(&s->gb, s->subframe_len_bits);
+ frame_len_shift = bitstream_read(&s->bc, s->subframe_len_bits);
subframe_len = s->samples_per_frame >> frame_len_shift;
*/
static int decode_tilehdr(WMAProDecodeCtx *s)
{
- uint16_t num_samples[WMAPRO_MAX_CHANNELS]; /**< sum of samples for all currently known subframes of a channel */
+ uint16_t num_samples[WMAPRO_MAX_CHANNELS] = { 0 };/**< sum of samples for all currently known subframes of a channel */
uint8_t contains_subframe[WMAPRO_MAX_CHANNELS]; /**< flag indicating if a channel contains the current subframe */
- int channels_for_cur_subframe = s->num_channels; /**< number of channels that contain the current subframe */
+ int channels_for_cur_subframe = s->avctx->channels; /**< number of channels that contain the current subframe */
int fixed_channel_layout = 0; /**< flag indicating that all channels use the same subframe offsets and sizes */
int min_channel_len = 0; /**< smallest sum of samples (channels with this length will be processed first) */
int c;
/* Should never consume more than 3073 bits (256 iterations for the
- * while loop when always the minimum amount of 128 samples is substracted
+ * while loop when always the minimum amount of 128 samples is subtracted
* from missing samples in the 8 channel case).
* 1 + BLOCK_MAX_SIZE * MAX_CHANNELS / BLOCK_MIN_SIZE * (MAX_CHANNELS + 4)
*/
/** reset tiling information */
- for (c = 0; c < s->num_channels; c++)
+ for (c = 0; c < s->avctx->channels; c++)
s->channel[c].num_subframes = 0;
- memset(num_samples, 0, sizeof(num_samples));
-
- if (s->max_num_subframes == 1 || get_bits1(&s->gb))
+ if (s->max_num_subframes == 1 || bitstream_read_bit(&s->bc))
fixed_channel_layout = 1;
/** loop until the frame data is split between the subframes */
int subframe_len;
/** check which channels contain the subframe */
- for (c = 0; c < s->num_channels; c++) {
+ for (c = 0; c < s->avctx->channels; c++) {
if (num_samples[c] == min_channel_len) {
if (fixed_channel_layout || channels_for_cur_subframe == 1 ||
(min_channel_len == s->samples_per_frame - s->min_samples_per_subframe))
contains_subframe[c] = 1;
else
- contains_subframe[c] = get_bits1(&s->gb);
+ contains_subframe[c] = bitstream_read_bit(&s->bc);
} else
contains_subframe[c] = 0;
}
/** add subframes to the individual channels and find new min_channel_len */
min_channel_len += subframe_len;
- for (c = 0; c < s->num_channels; c++) {
+ for (c = 0; c < s->avctx->channels; c++) {
WMAProChannelCtx* chan = &s->channel[c];
if (contains_subframe[c]) {
}
} while (min_channel_len < s->samples_per_frame);
- for (c = 0; c < s->num_channels; c++) {
+ for (c = 0; c < s->avctx->channels; c++) {
int i;
int offset = 0;
for (i = 0; i < s->channel[c].num_subframes; i++) {
- av_dlog(s->avctx, "frame[%i] channel[%i] subframe[%i]"
- " len %i\n", s->frame_num, c, i,
+ ff_dlog(s->avctx, "frame[%"PRIi32"] channel[%i] subframe[%i]"
+ " len %"PRIu16"\n", s->frame_num, c, i,
s->channel[c].subframe_len[i]);
s->channel[c].subframe_offset[i] = offset;
offset += s->channel[c].subframe_len[i];
int i;
int offset = 0;
int8_t rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS];
- memset(chgroup->decorrelation_matrix, 0, s->num_channels *
- s->num_channels * sizeof(*chgroup->decorrelation_matrix));
+ memset(chgroup->decorrelation_matrix, 0, s->avctx->channels *
+ s->avctx->channels * sizeof(*chgroup->decorrelation_matrix));
for (i = 0; i < chgroup->num_channels * (chgroup->num_channels - 1) >> 1; i++)
- rotation_offset[i] = get_bits(&s->gb, 6);
+ rotation_offset[i] = bitstream_read(&s->bc, 6);
for (i = 0; i < chgroup->num_channels; i++)
chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
- get_bits1(&s->gb) ? 1.0 : -1.0;
+ bitstream_read_bit(&s->bc) ? 1.0 : -1.0;
for (i = 1; i < chgroup->num_channels; i++) {
int x;
/** in the one channel case channel transforms are pointless */
s->num_chgroups = 0;
- if (s->num_channels > 1) {
+ if (s->avctx->channels > 1) {
int remaining_channels = s->channels_for_cur_subframe;
- if (get_bits1(&s->gb)) {
- av_log_ask_for_sample(s->avctx,
- "unsupported channel transform bit\n");
- return AVERROR_INVALIDDATA;
+ if (bitstream_read_bit(&s->bc)) {
+ avpriv_request_sample(s->avctx,
+ "Channel transform bit");
+ return AVERROR_PATCHWELCOME;
}
for (s->num_chgroups = 0; remaining_channels &&
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int channel_idx = s->channel_indexes_for_cur_subframe[i];
if (!s->channel[channel_idx].grouped
- && get_bits1(&s->gb)) {
+ && bitstream_read_bit(&s->bc)) {
++chgroup->num_channels;
s->channel[channel_idx].grouped = 1;
*channel_data++ = s->channel[channel_idx].coeffs;
/** decode transform type */
if (chgroup->num_channels == 2) {
- if (get_bits1(&s->gb)) {
- if (get_bits1(&s->gb)) {
- av_log_ask_for_sample(s->avctx,
- "unsupported channel transform type\n");
+ if (bitstream_read_bit(&s->bc)) {
+ if (bitstream_read_bit(&s->bc)) {
+ avpriv_request_sample(s->avctx,
+ "Unknown channel transform type");
+ return AVERROR_PATCHWELCOME;
}
} else {
chgroup->transform = 1;
- if (s->num_channels == 2) {
+ if (s->avctx->channels == 2) {
chgroup->decorrelation_matrix[0] = 1.0;
chgroup->decorrelation_matrix[1] = -1.0;
chgroup->decorrelation_matrix[2] = 1.0;
}
}
} else if (chgroup->num_channels > 2) {
- if (get_bits1(&s->gb)) {
+ if (bitstream_read_bit(&s->bc)) {
chgroup->transform = 1;
- if (get_bits1(&s->gb)) {
+ if (bitstream_read_bit(&s->bc)) {
decode_decorrelation_matrix(s, chgroup);
} else {
/** FIXME: more than 6 coupled channels not supported */
if (chgroup->num_channels > 6) {
- av_log_ask_for_sample(s->avctx,
- "coupled channels > 6\n");
+ avpriv_request_sample(s->avctx,
+ "Coupled channels > 6");
} else {
memcpy(chgroup->decorrelation_matrix,
default_decorrelation[chgroup->num_channels],
/** decode transform on / off */
if (chgroup->transform) {
- if (!get_bits1(&s->gb)) {
+ if (!bitstream_read_bit(&s->bc)) {
int i;
/** transform can be enabled for individual bands */
for (i = 0; i < s->num_bands; i++) {
- chgroup->transform_band[i] = get_bits1(&s->gb);
+ chgroup->transform_band[i] = bitstream_read_bit(&s->bc);
}
} else {
memset(chgroup->transform_band, 1, s->num_bands);
/* Integers 0..15 as single-precision floats. The table saves a
costly int to float conversion, and storing the values as
integers allows fast sign-flipping. */
- static const int fval_tab[16] = {
+ static const uint32_t fval_tab[16] = {
0x00000000, 0x3f800000, 0x40000000, 0x40400000,
0x40800000, 0x40a00000, 0x40c00000, 0x40e00000,
0x41000000, 0x41100000, 0x41200000, 0x41300000,
const uint16_t* run;
const float* level;
- av_dlog(s->avctx, "decode coefficients for channel %i\n", c);
+ ff_dlog(s->avctx, "decode coefficients for channel %i\n", c);
- vlctable = get_bits1(&s->gb);
+ vlctable = bitstream_read_bit(&s->bc);
vlc = &coef_vlc[vlctable];
if (vlctable) {
4 vector coded large values) */
while ((s->transmit_num_vec_coeffs || !rl_mode) &&
(cur_coeff + 3 < ci->num_vec_coeffs)) {
- int vals[4];
+ uint32_t vals[4];
int i;
unsigned int idx;
- idx = get_vlc2(&s->gb, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH);
+ idx = bitstream_read_vlc(&s->bc, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH);
if (idx == HUFF_VEC4_SIZE - 1) {
for (i = 0; i < 4; i += 2) {
- idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH);
+ idx = bitstream_read_vlc(&s->bc, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH);
if (idx == HUFF_VEC2_SIZE - 1) {
- int v0, v1;
- v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
+ uint32_t v0, v1;
+ v0 = bitstream_read_vlc(&s->bc, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
if (v0 == HUFF_VEC1_SIZE - 1)
- v0 += ff_wma_get_large_val(&s->gb);
- v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
+ v0 += ff_wma_get_large_val(&s->bc);
+ v1 = bitstream_read_vlc(&s->bc, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
if (v1 == HUFF_VEC1_SIZE - 1)
- v1 += ff_wma_get_large_val(&s->gb);
- ((float*)vals)[i ] = v0;
- ((float*)vals)[i+1] = v1;
+ v1 += ff_wma_get_large_val(&s->bc);
+ vals[i ] = av_float2int(v0);
+ vals[i+1] = av_float2int(v1);
} else {
vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ];
vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF];
/** decode sign */
for (i = 0; i < 4; i++) {
if (vals[i]) {
- int sign = get_bits1(&s->gb) - 1;
- *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31;
+ uint32_t sign = bitstream_read_bit(&s->bc) - 1;
+ AV_WN32A(&ci->coeffs[cur_coeff], vals[i] ^ sign << 31);
num_zeros = 0;
} else {
ci->coeffs[cur_coeff] = 0;
if (cur_coeff < s->subframe_len) {
memset(&ci->coeffs[cur_coeff], 0,
sizeof(*ci->coeffs) * (s->subframe_len - cur_coeff));
- if (ff_wma_run_level_decode(s->avctx, &s->gb, vlc,
+ if (ff_wma_run_level_decode(s->avctx, &s->bc, vlc,
level, run, 1, ci->coeffs,
cur_coeff, s->subframe_len,
s->subframe_len, s->esc_len, 0))
s->channel[c].saved_scale_factors[s->channel[c].scale_factor_idx][*sf_offsets++];
}
- if (!s->channel[c].cur_subframe || get_bits1(&s->gb)) {
-
+ if (!s->channel[c].cur_subframe || bitstream_read_bit(&s->bc)) {
if (!s->channel[c].reuse_sf) {
int val;
/** decode DPCM coded scale factors */
- s->channel[c].scale_factor_step = get_bits(&s->gb, 2) + 1;
+ s->channel[c].scale_factor_step = bitstream_read(&s->bc, 2) + 1;
val = 45 / s->channel[c].scale_factor_step;
for (sf = s->channel[c].scale_factors; sf < sf_end; sf++) {
- val += get_vlc2(&s->gb, sf_vlc.table, SCALEVLCBITS, SCALEMAXDEPTH) - 60;
+ val += bitstream_read_vlc(&s->bc, sf_vlc.table, SCALEVLCBITS, SCALEMAXDEPTH) - 60;
*sf = val;
}
} else {
int val;
int sign;
- idx = get_vlc2(&s->gb, sf_rl_vlc.table, VLCBITS, SCALERLMAXDEPTH);
+ idx = bitstream_read_vlc(&s->bc, sf_rl_vlc.table, VLCBITS, SCALERLMAXDEPTH);
if (!idx) {
- uint32_t code = get_bits(&s->gb, 14);
+ uint32_t code = bitstream_read(&s->bc, 14);
val = code >> 6;
sign = (code & 1) - 1;
skip = (code & 0x3f) >> 1;
} else {
skip = scale_rl_run[idx];
val = scale_rl_level[idx];
- sign = get_bits1(&s->gb)-1;
+ sign = bitstream_read_bit(&s->bc)-1;
}
i += skip;
(*ch)[y] = sum;
}
}
- } else if (s->num_channels == 2) {
+ } else if (s->avctx->channels == 2) {
int len = FFMIN(sfb[1], s->subframe_len) - sfb[0];
- s->dsp.vector_fmul_scalar(ch_data[0] + sfb[0],
- ch_data[0] + sfb[0],
- 181.0 / 128, len);
- s->dsp.vector_fmul_scalar(ch_data[1] + sfb[0],
- ch_data[1] + sfb[0],
- 181.0 / 128, len);
+ s->fdsp.vector_fmul_scalar(ch_data[0] + sfb[0],
+ ch_data[0] + sfb[0],
+ 181.0 / 128, len);
+ s->fdsp.vector_fmul_scalar(ch_data[1] + sfb[0],
+ ch_data[1] + sfb[0],
+ 181.0 / 128, len);
}
}
}
winlen >>= 1;
- s->dsp.vector_fmul_window(start, start, start + winlen,
- window, winlen);
+ s->fdsp.vector_fmul_window(start, start, start + winlen,
+ window, winlen);
s->channel[c].prev_block_len = s->subframe_len;
}
int offset = s->samples_per_frame;
int subframe_len = s->samples_per_frame;
int i;
- int total_samples = s->samples_per_frame * s->num_channels;
+ int total_samples = s->samples_per_frame * s->avctx->channels;
int transmit_coeffs = 0;
int cur_subwoofer_cutoff;
- s->subframe_offset = get_bits_count(&s->gb);
+ s->subframe_offset = bitstream_tell(&s->bc);
/** reset channel context and find the next block offset and size
== the next block of the channel with the smallest number of
decoded samples
*/
- for (i = 0; i < s->num_channels; i++) {
+ for (i = 0; i < s->avctx->channels; i++) {
s->channel[i].grouped = 0;
if (offset > s->channel[i].decoded_samples) {
offset = s->channel[i].decoded_samples;
}
}
- av_dlog(s->avctx,
+ ff_dlog(s->avctx,
"processing subframe with offset %i len %i\n", offset, subframe_len);
/** get a list of all channels that contain the estimated block */
s->channels_for_cur_subframe = 0;
- for (i = 0; i < s->num_channels; i++) {
+ for (i = 0; i < s->avctx->channels; i++) {
const int cur_subframe = s->channel[i].cur_subframe;
- /** substract already processed samples */
+ /** subtract already processed samples */
total_samples -= s->channel[i].decoded_samples;
/** and count if there are multiple subframes that match our profile */
s->parsed_all_subframes = 1;
- av_dlog(s->avctx, "subframe is part of %i channels\n",
+ ff_dlog(s->avctx, "subframe is part of %i channels\n",
s->channels_for_cur_subframe);
/** calculate number of scale factor bands and their offsets */
cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx];
/** configure the decoder for the current subframe */
+ offset += s->samples_per_frame >> 1;
+
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
- s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1)
- + offset];
+ s->channel[c].coeffs = &s->channel[c].out[offset];
}
s->subframe_len = subframe_len;
s->esc_len = av_log2(s->subframe_len - 1) + 1;
/** skip extended header if any */
- if (get_bits1(&s->gb)) {
+ if (bitstream_read_bit(&s->bc)) {
int num_fill_bits;
- if (!(num_fill_bits = get_bits(&s->gb, 2))) {
- int len = get_bits(&s->gb, 4);
- num_fill_bits = get_bits(&s->gb, len) + 1;
+ if (!(num_fill_bits = bitstream_read(&s->bc, 2))) {
+ int len = bitstream_read(&s->bc, 4);
+ num_fill_bits = bitstream_read(&s->bc, len) + 1;
}
if (num_fill_bits >= 0) {
- if (get_bits_count(&s->gb) + num_fill_bits > s->num_saved_bits) {
+ if (bitstream_tell(&s->bc) + num_fill_bits > s->num_saved_bits) {
av_log(s->avctx, AV_LOG_ERROR, "invalid number of fill bits\n");
return AVERROR_INVALIDDATA;
}
- skip_bits_long(&s->gb, num_fill_bits);
+ bitstream_skip(&s->bc, num_fill_bits);
}
}
/** no idea for what the following bit is used */
- if (get_bits1(&s->gb)) {
- av_log_ask_for_sample(s->avctx, "reserved bit set\n");
- return AVERROR_INVALIDDATA;
+ if (bitstream_read_bit(&s->bc)) {
+ avpriv_request_sample(s->avctx, "Reserved bit");
+ return AVERROR_PATCHWELCOME;
}
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
- if ((s->channel[c].transmit_coefs = get_bits1(&s->gb)))
+ if ((s->channel[c].transmit_coefs = bitstream_read_bit(&s->bc)))
transmit_coeffs = 1;
}
int quant_step = 90 * s->bits_per_sample >> 4;
/** decode number of vector coded coefficients */
- if ((s->transmit_num_vec_coeffs = get_bits1(&s->gb))) {
+ if ((s->transmit_num_vec_coeffs = bitstream_read_bit(&s->bc))) {
int num_bits = av_log2((s->subframe_len + 3)/4) + 1;
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
- s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
+ int num_vec_coeffs = bitstream_read(&s->bc, num_bits) << 2;
+ if (num_vec_coeffs + offset > FF_ARRAY_ELEMS(s->channel[c].out)) {
+ av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
+ return AVERROR_INVALIDDATA;
+ }
+ s->channel[c].num_vec_coeffs = num_vec_coeffs;
}
} else {
for (i = 0; i < s->channels_for_cur_subframe; i++) {
}
}
/** decode quantization step */
- step = get_sbits(&s->gb, 6);
+ step = bitstream_read_signed(&s->bc, 6);
quant_step += step;
if (step == -32 || step == 31) {
const int sign = (step == 31) - 1;
int quant = 0;
- while (get_bits_count(&s->gb) + 5 < s->num_saved_bits &&
- (step = get_bits(&s->gb, 5)) == 31) {
+ while (bitstream_tell(&s->bc) + 5 < s->num_saved_bits &&
+ (step = bitstream_read(&s->bc, 5)) == 31) {
quant += 31;
}
quant_step += ((quant + step) ^ sign) - sign;
if (s->channels_for_cur_subframe == 1) {
s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step = quant_step;
} else {
- int modifier_len = get_bits(&s->gb, 3);
+ int modifier_len = bitstream_read(&s->bc, 3);
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
s->channel[c].quant_step = quant_step;
- if (get_bits1(&s->gb)) {
+ if (bitstream_read_bit(&s->bc)) {
if (modifier_len) {
- s->channel[c].quant_step += get_bits(&s->gb, modifier_len) + 1;
+ s->channel[c].quant_step += bitstream_read(&s->bc, modifier_len) + 1;
} else
++s->channel[c].quant_step;
}
return AVERROR_INVALIDDATA;
}
- av_dlog(s->avctx, "BITSTREAM: subframe header length was %i\n",
- get_bits_count(&s->gb) - s->subframe_offset);
+ ff_dlog(s->avctx, "BITSTREAM: subframe header length was %i\n",
+ bitstream_tell(&s->bc) - s->subframe_offset);
/** parse coefficients */
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
if (s->channel[c].transmit_coefs &&
- get_bits_count(&s->gb) < s->num_saved_bits) {
+ bitstream_tell(&s->bc) < s->num_saved_bits) {
decode_coeffs(s, c);
} else
memset(s->channel[c].coeffs, 0,
sizeof(*s->channel[c].coeffs) * subframe_len);
}
- av_dlog(s->avctx, "BITSTREAM: subframe length was %i\n",
- get_bits_count(&s->gb) - s->subframe_offset);
+ ff_dlog(s->avctx, "BITSTREAM: subframe length was %i\n",
+ bitstream_tell(&s->bc) - s->subframe_offset);
if (transmit_coeffs) {
FFTContext *mdct = &s->mdct_ctx[av_log2(subframe_len) - WMAPRO_BLOCK_MIN_BITS];
s->channel[c].scale_factor_step;
const float quant = pow(10.0, exp / 20.0);
int start = s->cur_sfb_offsets[b];
- s->dsp.vector_fmul_scalar(s->tmp + start,
- s->channel[c].coeffs + start,
- quant, end - start);
+ s->fdsp.vector_fmul_scalar(s->tmp + start,
+ s->channel[c].coeffs + start,
+ quant, end - start);
}
/** apply imdct (imdct_half == DCTIV with reverse) */
*@return 0 if the trailer bit indicates that this is the last frame,
* 1 if there are additional frames
*/
-static int decode_frame(WMAProDecodeCtx *s)
+static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr)
{
- GetBitContext* gb = &s->gb;
+ AVCodecContext *avctx = s->avctx;
+ BitstreamContext *bc = &s->bc;
int more_frames = 0;
int len = 0;
- int i;
-
- /** check for potential output buffer overflow */
- if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) {
- /** return an error if no frame could be decoded at all */
- av_log(s->avctx, AV_LOG_ERROR,
- "not enough space for the output samples\n");
- s->packet_loss = 1;
- return 0;
- }
+ int i, ret;
/** get frame length */
if (s->len_prefix)
- len = get_bits(gb, s->log2_frame_size);
+ len = bitstream_read(bc, s->log2_frame_size);
- av_dlog(s->avctx, "decoding frame with length %x\n", len);
+ ff_dlog(s->avctx, "decoding frame with length %x\n", len);
/** decode tile information */
if (decode_tilehdr(s)) {
}
/** read postproc transform */
- if (s->num_channels > 1 && get_bits1(gb)) {
- if (get_bits1(gb)) {
- for (i = 0; i < s->num_channels * s->num_channels; i++)
- skip_bits(gb, 4);
+ if (s->avctx->channels > 1 && bitstream_read_bit(bc)) {
+ if (bitstream_read_bit(bc)) {
+ for (i = 0; i < avctx->channels * avctx->channels; i++)
+ bitstream_skip(bc, 4);
}
}
/** read drc info */
if (s->dynamic_range_compression) {
- s->drc_gain = get_bits(gb, 8);
- av_dlog(s->avctx, "drc_gain %i\n", s->drc_gain);
+ s->drc_gain = bitstream_read(bc, 8);
+ ff_dlog(s->avctx, "drc_gain %i\n", s->drc_gain);
}
/** no idea what these are for, might be the number of samples
that need to be skipped at the beginning or end of a stream */
- if (get_bits1(gb)) {
+ if (bitstream_read_bit(bc)) {
int av_unused skip;
/** usually true for the first frame */
- if (get_bits1(gb)) {
- skip = get_bits(gb, av_log2(s->samples_per_frame * 2));
- av_dlog(s->avctx, "start skip: %i\n", skip);
+ if (bitstream_read_bit(bc)) {
+ skip = bitstream_read(bc, av_log2(s->samples_per_frame * 2));
+ ff_dlog(s->avctx, "start skip: %i\n", skip);
}
/** sometimes true for the last frame */
- if (get_bits1(gb)) {
- skip = get_bits(gb, av_log2(s->samples_per_frame * 2));
- av_dlog(s->avctx, "end skip: %i\n", skip);
+ if (bitstream_read_bit(bc)) {
+ skip = bitstream_read(bc, av_log2(s->samples_per_frame * 2));
+ ff_dlog(s->avctx, "end skip: %i\n", skip);
}
}
- av_dlog(s->avctx, "BITSTREAM: frame header length was %i\n",
- get_bits_count(gb) - s->frame_offset);
+ ff_dlog(s->avctx, "BITSTREAM: frame header length was %i\n",
+ bitstream_tell(bc) - s->frame_offset);
/** reset subframe states */
s->parsed_all_subframes = 0;
- for (i = 0; i < s->num_channels; i++) {
+ for (i = 0; i < avctx->channels; i++) {
s->channel[i].decoded_samples = 0;
s->channel[i].cur_subframe = 0;
s->channel[i].reuse_sf = 0;
}
}
- /** interleave samples and write them to the output buffer */
- for (i = 0; i < s->num_channels; i++) {
- float* ptr = s->samples + i;
- int incr = s->num_channels;
- float* iptr = s->channel[i].out;
- float* iend = iptr + s->samples_per_frame;
-
- // FIXME should create/use a DSP function here
- while (iptr < iend) {
- *ptr = *iptr++;
- ptr += incr;
- }
+ /* get output buffer */
+ frame->nb_samples = s->samples_per_frame;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ s->packet_loss = 1;
+ return 0;
+ }
+
+ /** copy samples to the output buffer */
+ for (i = 0; i < avctx->channels; i++)
+ memcpy(frame->extended_data[i], s->channel[i].out,
+ s->samples_per_frame * sizeof(*s->channel[i].out));
+ for (i = 0; i < avctx->channels; i++) {
/** reuse second half of the IMDCT output for the next frame */
memcpy(&s->channel[i].out[0],
&s->channel[i].out[s->samples_per_frame],
if (s->skip_frame) {
s->skip_frame = 0;
- } else
- s->samples += s->num_channels * s->samples_per_frame;
+ *got_frame_ptr = 0;
+ av_frame_unref(frame);
+ } else {
+ *got_frame_ptr = 1;
+ }
if (s->len_prefix) {
- if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
+ if (len != (bitstream_tell(bc) - s->frame_offset) + 2) {
/** FIXME: not sure if this is always an error */
av_log(s->avctx, AV_LOG_ERROR,
- "frame[%i] would have to skip %i bits\n", s->frame_num,
- len - (get_bits_count(gb) - s->frame_offset) - 1);
+ "frame[%"PRIu32"] would have to skip %i bits\n",
+ s->frame_num,
+ len - (bitstream_tell(bc) - s->frame_offset) - 1);
s->packet_loss = 1;
return 0;
}
/** skip the rest of the frame data */
- skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1);
+ bitstream_skip(bc, len - (bitstream_tell(bc) - s->frame_offset) - 1);
} else {
- while (get_bits_count(gb) < s->num_saved_bits && get_bits1(gb) == 0) {
+ while (bitstream_tell(bc) < s->num_saved_bits && bitstream_read_bit(bc) == 0) {
}
}
/** decode trailer bit */
- more_frames = get_bits1(gb);
+ more_frames = bitstream_read_bit(bc);
++s->frame_num;
return more_frames;
/**
*@brief Calculate remaining input buffer length.
*@param s codec context
- *@param gb bitstream reader context
+ *@param bc bitstream reader context
*@return remaining size in bits
*/
-static int remaining_bits(WMAProDecodeCtx *s, GetBitContext *gb)
+static int remaining_bits(WMAProDecodeCtx *s, BitstreamContext *bc)
{
- return s->buf_bit_size - get_bits_count(gb);
+ return s->buf_bit_size - bitstream_tell(bc);
}
/**
*@brief Fill the bit reservoir with a (partial) frame.
*@param s codec context
- *@param gb bitstream reader context
+ *@param bc bitstream reader context
*@param len length of the partial frame
- *@param append decides wether to reset the buffer or not
+ *@param append decides whether to reset the buffer or not
*/
-static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
+static void save_bits(WMAProDecodeCtx *s, BitstreamContext *bc, int len,
int append)
{
int buflen;
/** when the frame data does not need to be concatenated, the input buffer
- is resetted and additional bits from the previous frame are copyed
+ is reset and additional bits from the previous frame are copied
and skipped later so that a fast byte copy is possible */
if (!append) {
- s->frame_offset = get_bits_count(gb) & 7;
+ s->frame_offset = bitstream_tell(bc) & 7;
s->num_saved_bits = s->frame_offset;
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
}
buflen = (s->num_saved_bits + len + 8) >> 3;
if (len <= 0 || buflen > MAX_FRAMESIZE) {
- av_log_ask_for_sample(s->avctx, "input buffer too small\n");
+ avpriv_request_sample(s->avctx, "Too small input buffer");
+ s->packet_loss = 1;
+ return;
+ }
+
+ if (len > put_bits_left(&s->pb)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Cannot append %d bits, only %d bits available.\n",
+ len, put_bits_left(&s->pb));
s->packet_loss = 1;
return;
}
s->num_saved_bits += len;
if (!append) {
- avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
- s->num_saved_bits);
+ avpriv_copy_bits(&s->pb, bc->buffer + (bitstream_tell(bc) >> 3),
+ s->num_saved_bits);
} else {
- int align = 8 - (get_bits_count(gb) & 7);
+ int align = 8 - (bitstream_tell(bc) & 7);
align = FFMIN(align, len);
- put_bits(&s->pb, align, get_bits(gb, align));
+ put_bits(&s->pb, align, bitstream_read(bc, align));
len -= align;
- avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
+ avpriv_copy_bits(&s->pb, bc->buffer + (bitstream_tell(bc) >> 3), len);
}
- skip_bits_long(gb, len);
+ bitstream_skip(bc, len);
{
PutBitContext tmp = s->pb;
flush_put_bits(&tmp);
}
- init_get_bits(&s->gb, s->frame_data, s->num_saved_bits);
- skip_bits(&s->gb, s->frame_offset);
+ bitstream_init(&s->bc, s->frame_data, s->num_saved_bits);
+ bitstream_skip(&s->bc, s->frame_offset);
}
/**
*@brief Decode a single WMA packet.
*@param avctx codec context
*@param data the output buffer
- *@param data_size number of bytes that were written to the output buffer
*@param avpkt input packet
*@return number of bytes that were read from the input buffer
*/
-static int decode_packet(AVCodecContext *avctx,
- void *data, int *data_size, AVPacket* avpkt)
+static int decode_packet(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket* avpkt)
{
WMAProDecodeCtx *s = avctx->priv_data;
- GetBitContext* gb = &s->pgb;
+ BitstreamContext *bc = &s->pbc;
const uint8_t* buf = avpkt->data;
int buf_size = avpkt->size;
int num_bits_prev_frame;
int packet_sequence_number;
- s->samples = data;
- s->samples_end = (float*)((int8_t*)data + *data_size);
- *data_size = 0;
+ *got_frame_ptr = 0;
if (s->packet_done || s->packet_loss) {
s->packet_done = 0;
/** sanity check for the buffer length */
- if (buf_size < avctx->block_align)
- return 0;
+ if (buf_size < avctx->block_align) {
+ av_log(avctx, AV_LOG_ERROR, "Input packet too small (%d < %d)\n",
+ buf_size, avctx->block_align);
+ return AVERROR_INVALIDDATA;
+ }
s->next_packet_start = buf_size - avctx->block_align;
buf_size = avctx->block_align;
s->buf_bit_size = buf_size << 3;
/** parse packet header */
- init_get_bits(gb, buf, s->buf_bit_size);
- packet_sequence_number = get_bits(gb, 4);
- skip_bits(gb, 2);
+ bitstream_init(bc, buf, s->buf_bit_size);
+ packet_sequence_number = bitstream_read(bc, 4);
+ bitstream_skip(bc, 2);
/** get number of bits that need to be added to the previous frame */
- num_bits_prev_frame = get_bits(gb, s->log2_frame_size);
- av_dlog(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number,
+ num_bits_prev_frame = bitstream_read(bc, s->log2_frame_size);
+ ff_dlog(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number,
num_bits_prev_frame);
/** check for packet loss */
if (!s->packet_loss &&
((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) {
s->packet_loss = 1;
- av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n",
+ av_log(avctx, AV_LOG_ERROR,
+ "Packet loss detected! seq %"PRIx8" vs %x\n",
s->packet_sequence_number, packet_sequence_number);
}
s->packet_sequence_number = packet_sequence_number;
if (num_bits_prev_frame > 0) {
- int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb);
+ int remaining_packet_bits = s->buf_bit_size - bitstream_tell(bc);
if (num_bits_prev_frame >= remaining_packet_bits) {
num_bits_prev_frame = remaining_packet_bits;
s->packet_done = 1;
/** append the previous frame data to the remaining data from the
previous packet to create a full frame */
- save_bits(s, gb, num_bits_prev_frame, 1);
- av_dlog(avctx, "accumulated %x bits of frame data\n",
+ save_bits(s, bc, num_bits_prev_frame, 1);
+ ff_dlog(avctx, "accumulated %x bits of frame data\n",
s->num_saved_bits - s->frame_offset);
/** decode the cross packet frame if it is valid */
if (!s->packet_loss)
- decode_frame(s);
+ decode_frame(s, data, got_frame_ptr);
} else if (s->num_saved_bits - s->frame_offset) {
- av_dlog(avctx, "ignoring %x previously saved bits\n",
+ ff_dlog(avctx, "ignoring %x previously saved bits\n",
s->num_saved_bits - s->frame_offset);
}
} else {
int frame_size;
s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3;
- init_get_bits(gb, avpkt->data, s->buf_bit_size);
- skip_bits(gb, s->packet_offset);
- if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size &&
- (frame_size = show_bits(gb, s->log2_frame_size)) &&
- frame_size <= remaining_bits(s, gb)) {
- save_bits(s, gb, frame_size, 0);
- s->packet_done = !decode_frame(s);
+ bitstream_init(bc, avpkt->data, s->buf_bit_size);
+ bitstream_skip(bc, s->packet_offset);
+ if (s->len_prefix && remaining_bits(s, bc) > s->log2_frame_size &&
+ (frame_size = bitstream_peek(bc, s->log2_frame_size)) &&
+ frame_size <= remaining_bits(s, bc)) {
+ save_bits(s, bc, frame_size, 0);
+ s->packet_done = !decode_frame(s, data, got_frame_ptr);
} else if (!s->len_prefix
- && s->num_saved_bits > get_bits_count(&s->gb)) {
+ && s->num_saved_bits > bitstream_tell(&s->bc)) {
/** when the frames do not have a length prefix, we don't know
the compressed length of the individual frames
however, we know what part of a new packet belongs to the
therefore we save the incoming packet first, then we append
the "previous frame" data from the next packet so that
we get a buffer that only contains full frames */
- s->packet_done = !decode_frame(s);
+ s->packet_done = !decode_frame(s, data, got_frame_ptr);
} else
s->packet_done = 1;
}
if (s->packet_done && !s->packet_loss &&
- remaining_bits(s, gb) > 0) {
+ remaining_bits(s, bc) > 0) {
/** save the rest of the data so that it can be decoded
with the next packet */
- save_bits(s, gb, remaining_bits(s, gb), 0);
+ save_bits(s, bc, remaining_bits(s, bc), 0);
}
- *data_size = (int8_t *)s->samples - (int8_t *)data;
- s->packet_offset = get_bits_count(gb) & 7;
+ s->packet_offset = bitstream_tell(bc) & 7;
+ if (s->packet_loss)
+ return AVERROR_INVALIDDATA;
- return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;
+ return bitstream_tell(bc) >> 3;
}
/**
int i;
/** reset output buffer as a part of it is used during the windowing of a
new frame */
- for (i = 0; i < s->num_channels; i++)
+ for (i = 0; i < avctx->channels; i++)
memset(s->channel[i].out, 0, s->samples_per_frame *
sizeof(*s->channel[i].out));
s->packet_loss = 1;
*/
AVCodec ff_wmapro_decoder = {
.name = "wmapro",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
.type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_WMAPRO,
+ .id = AV_CODEC_ID_WMAPRO,
.priv_data_size = sizeof(WMAProDecodeCtx),
.init = decode_init,
.close = decode_end,
.decode = decode_packet,
- .capabilities = CODEC_CAP_SUBFRAMES,
- .flush= flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
+ .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
+ .flush = flush,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_NONE },
};