#define WMAPRO_MAX_CHANNELS 8 ///< max number of handled channels
#define MAX_SUBFRAMES 32 ///< max number of subframes per channel
#define MAX_BANDS 29 ///< max number of scale factor bands
-#define MAX_FRAMESIZE 16384 ///< maximum compressed frame size
+#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size
#define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size
#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size
int8_t reuse_sf; ///< share scale factors between subframes
int8_t scale_factor_step; ///< scaling step for the current subframe
int max_scale_factor; ///< maximum scale factor for the current subframe
- int scale_factors[MAX_BANDS]; ///< scale factor values for the current subframe
- int saved_scale_factors[MAX_BANDS]; ///< scale factors from a previous subframe
+ int saved_scale_factors[2][MAX_BANDS]; ///< resampled and (previously) transmitted scale factor values
+ int8_t scale_factor_idx; ///< index for the transmitted scale factor values (used for resampling)
+ int* scale_factors; ///< pointer to the scale factor values used for decoding
uint8_t table_idx; ///< index in sf_offsets for the scale factor reference block
float* coeffs; ///< pointer to the subframe decode buffer
DECLARE_ALIGNED_16(float, out[WMAPRO_BLOCK_MAX_SIZE + WMAPRO_BLOCK_MAX_SIZE / 2]); ///< output buffer
uint8_t frame_data[MAX_FRAMESIZE +
FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
PutBitContext pb; ///< context for filling the frame_data buffer
- MDCTContext mdct_ctx[WMAPRO_BLOCK_SIZES]; ///< MDCT context per block size
+ FFTContext mdct_ctx[WMAPRO_BLOCK_SIZES]; ///< MDCT context per block size
DECLARE_ALIGNED_16(float, tmp[WMAPRO_BLOCK_MAX_SIZE]); ///< IMDCT output buffer
float* windows[WMAPRO_BLOCK_SIZES]; ///< windows for the different block sizes
/* packet decode state */
GetBitContext pgb; ///< bitstream reader context for the packet
+ uint8_t packet_offset; ///< frame offset in the packet
uint8_t packet_sequence_number; ///< current packet number
int num_saved_bits; ///< saved number of bits
int frame_offset; ///< frame offset in the bit reservoir
int subframe_offset; ///< subframe offset in the bit reservoir
uint8_t packet_loss; ///< set in case of bitstream error
- uint8_t output_buffer_full; ///< flag indicating that the output buffer is full
+ uint8_t packet_done; ///< set when a packet is fully decoded
/* frame decode state */
uint32_t frame_num; ///< current frame number (not used for decoding)
GetBitContext gb; ///< bitstream reader context
int buf_bit_size; ///< buffer size in bits
- float* samples_start; ///< start samplebuffer pointer
float* samples; ///< current samplebuffer pointer
float* samples_end; ///< maximum samplebuffer pointer
uint8_t drc_gain; ///< gain for the DRC tool
/** init MDCT windows: simple sinus window */
for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) {
- const int n = 1 << (WMAPRO_BLOCK_MAX_BITS - i);
- const int win_idx = WMAPRO_BLOCK_MAX_BITS - i - 7;
- ff_sine_window_init(ff_sine_windows[win_idx], n);
+ const int win_idx = WMAPRO_BLOCK_MAX_BITS - i;
+ ff_init_ff_sine_windows(win_idx);
s->windows[WMAPRO_BLOCK_SIZES - i - 1] = ff_sine_windows[win_idx];
}
*/
static int decode_coeffs(WMAProDecodeCtx *s, int c)
{
+ /* 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] = {
+ 0x00000000, 0x3f800000, 0x40000000, 0x40400000,
+ 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000,
+ 0x41000000, 0x41100000, 0x41200000, 0x41300000,
+ 0x41400000, 0x41500000, 0x41600000, 0x41700000,
+ };
int vlctable;
VLC* vlc;
WMAProChannelCtx* ci = &s->channel[c];
int cur_coeff = 0;
int num_zeros = 0;
const uint16_t* run;
- const uint16_t* level;
+ const float* level;
dprintf(s->avctx, "decode coefficients for channel %i\n", c);
for (i = 0; i < 4; i += 2) {
idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH);
if (idx == HUFF_VEC2_SIZE - 1) {
- vals[i] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
- if (vals[i] == HUFF_VEC1_SIZE - 1)
- vals[i] += ff_wma_get_large_val(&s->gb);
- vals[i+1] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
- if (vals[i+1] == HUFF_VEC1_SIZE - 1)
- vals[i+1] += ff_wma_get_large_val(&s->gb);
+ int v0, v1;
+ v0 = get_vlc2(&s->gb, 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);
+ if (v1 == HUFF_VEC1_SIZE - 1)
+ v1 += ff_wma_get_large_val(&s->gb);
+ ((float*)vals)[i ] = v0;
+ ((float*)vals)[i+1] = v1;
} else {
- vals[i] = symbol_to_vec2[idx] >> 4;
- vals[i+1] = symbol_to_vec2[idx] & 0xF;
+ vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ];
+ vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF];
}
}
} else {
- vals[0] = symbol_to_vec4[idx] >> 12;
- vals[1] = (symbol_to_vec4[idx] >> 8) & 0xF;
- vals[2] = (symbol_to_vec4[idx] >> 4) & 0xF;
- vals[3] = symbol_to_vec4[idx] & 0xF;
+ vals[0] = fval_tab[ symbol_to_vec4[idx] >> 12 ];
+ vals[1] = fval_tab[(symbol_to_vec4[idx] >> 8) & 0xF];
+ vals[2] = fval_tab[(symbol_to_vec4[idx] >> 4) & 0xF];
+ vals[3] = fval_tab[ symbol_to_vec4[idx] & 0xF];
}
/** decode sign */
for (i = 0; i < 4; i++) {
if (vals[i]) {
int sign = get_bits1(&s->gb) - 1;
- ci->coeffs[cur_coeff] = (vals[i] ^ sign) - sign;
+ *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31;
num_zeros = 0;
} else {
ci->coeffs[cur_coeff] = 0;
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
int* sf;
- int* sf_end = s->channel[c].scale_factors + s->num_bands;
+ int* sf_end;
+ s->channel[c].scale_factors = s->channel[c].saved_scale_factors[!s->channel[c].scale_factor_idx];
+ sf_end = s->channel[c].scale_factors + s->num_bands;
/** resample scale factors for the new block size
* as the scale factors might need to be resampled several times
int b;
for (b = 0; b < s->num_bands; b++)
s->channel[c].scale_factors[b] =
- s->channel[c].saved_scale_factors[*sf_offsets++];
+ s->channel[c].saved_scale_factors[s->channel[c].scale_factor_idx][*sf_offsets++];
}
if (!s->channel[c].cur_subframe || get_bits1(&s->gb)) {
s->channel[c].scale_factors[i] += (val ^ sign) - sign;
}
}
-
- /** save transmitted scale factors so that they can be reused for
- the next subframe */
- memcpy(s->channel[c].saved_scale_factors,
- s->channel[c].scale_factors, s->num_bands *
- sizeof(*s->channel[c].saved_scale_factors));
+ /** swap buffers */
+ s->channel[c].scale_factor_idx = !s->channel[c].scale_factor_idx;
s->channel[c].table_idx = s->table_idx;
s->channel[c].reuse_sf = 1;
}
}
}
} else if (s->num_channels == 2) {
- for (y = sfb[0]; y < FFMIN(sfb[1], s->subframe_len); y++) {
- ch_data[0][y] *= 181.0 / 128;
- ch_data[1][y] *= 181.0 / 128;
- }
+ 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->channel[c].max_scale_factor - *sf++) *
s->channel[c].scale_factor_step;
const float quant = pow(10.0, exp / 20.0);
- int start;
-
- for (start = s->cur_sfb_offsets[b]; start < end; start++)
- s->tmp[start] = s->channel[c].coeffs[start] * quant;
+ int start = s->cur_sfb_offsets[b];
+ s->dsp.vector_fmul_scalar(s->tmp + start,
+ s->channel[c].coeffs + start,
+ quant, end - start);
}
/** apply imdct (ff_imdct_half == DCTIV with reverse) */
/** 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 */
- if (s->samples_start == s->samples) {
- av_log(s->avctx, AV_LOG_ERROR,
- "not enough space for the output samples\n");
- s->packet_loss = 1;
- } else
- s->output_buffer_full = 1;
+ av_log(s->avctx, AV_LOG_ERROR,
+ "not enough space for the output samples\n");
+ s->packet_loss = 1;
return 0;
}
void *data, int *data_size, AVPacket* avpkt)
{
WMAProDecodeCtx *s = avctx->priv_data;
- GetBitContext* gb = &s->pgb;
- const uint8_t* buf = avpkt->data;
- int buf_size = avpkt->size;
- int more_frames = 1;
+ GetBitContext* gb = &s->pgb;
+ 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_start = data;
- s->samples_end = (float*)((int8_t*)data + *data_size);
+ s->samples = data;
+ s->samples_end = (float*)((int8_t*)data + *data_size);
*data_size = 0;
- if (!s->output_buffer_full) {
- s->buf_bit_size = buf_size << 3;
+ if (s->packet_done || s->packet_loss) {
+ s->packet_done = 0;
+ s->buf_bit_size = buf_size << 3;
- /** sanity check for the buffer length */
- if (buf_size < avctx->block_align)
- return 0;
+ /** sanity check for the buffer length */
+ if (buf_size < avctx->block_align)
+ return 0;
- buf_size = avctx->block_align;
+ buf_size = avctx->block_align;
- /** parse packet header */
- init_get_bits(gb, buf, s->buf_bit_size);
- packet_sequence_number = get_bits(gb, 4);
- skip_bits(gb, 2);
+ /** parse packet header */
+ init_get_bits(gb, buf, s->buf_bit_size);
+ packet_sequence_number = get_bits(gb, 4);
+ skip_bits(gb, 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);
- dprintf(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number,
- num_bits_prev_frame);
+ /** get number of bits that need to be added to the previous frame */
+ num_bits_prev_frame = get_bits(gb, s->log2_frame_size);
+ dprintf(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",
- s->packet_sequence_number, packet_sequence_number);
- }
- s->packet_sequence_number = packet_sequence_number;
-
- if (num_bits_prev_frame > 0) {
- /** 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);
- dprintf(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);
- } else if (s->num_saved_bits - s->frame_offset) {
- dprintf(avctx, "ignoring %x previously saved bits\n",
- s->num_saved_bits - s->frame_offset);
- }
+ /** 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",
+ s->packet_sequence_number, packet_sequence_number);
+ }
+ s->packet_sequence_number = packet_sequence_number;
+
+ if (num_bits_prev_frame > 0) {
+ /** 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);
+ dprintf(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);
+ } else if (s->num_saved_bits - s->frame_offset) {
+ dprintf(avctx, "ignoring %x previously saved bits\n",
+ s->num_saved_bits - s->frame_offset);
+ }
- s->packet_loss = 0;
+ s->packet_loss = 0;
} else {
- /** continue decoding */
- s->output_buffer_full = 0;
- more_frames = decode_frame(s);
- }
-
- /** decode the rest of the packet */
- while (!s->packet_loss && !s->output_buffer_full && more_frames &&
- remaining_bits(s, gb) > s->log2_frame_size) {
- int frame_size = show_bits(gb, s->log2_frame_size);
-
- /** there is enough data for a full frame */
- if (remaining_bits(s, gb) >= frame_size && frame_size > 0) {
+ int frame_size;
+ s->buf_bit_size = avpkt->size << 3;
+ init_get_bits(gb, avpkt->data, s->buf_bit_size);
+ skip_bits(gb, s->packet_offset);
+ if (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);
-
- /** decode the frame */
- more_frames = decode_frame(s);
-
- if (!more_frames) {
- dprintf(avctx, "no more frames\n");
- }
+ s->packet_done = !decode_frame(s);
} else
- more_frames = 0;
+ s->packet_done = 1;
}
- if (!s->output_buffer_full && !s->packet_loss &&
+ if (s->packet_done && !s->packet_loss &&
remaining_bits(s, gb) > 0) {
/** save the rest of the data so that it can be decoded
with the next packet */
}
*data_size = (int8_t *)s->samples - (int8_t *)data;
+ s->packet_offset = get_bits_count(gb) & 7;
- return (s->output_buffer_full)?0: avctx->block_align;
+ return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;
}
/**
NULL,
decode_end,
decode_packet,
+ .capabilities = CODEC_CAP_SUBFRAMES,
.flush= flush,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
};