* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#define MAX_ORDER 256
#define WMALL_BLOCK_MIN_BITS 6 ///< log2 of min block size
-#define WMALL_BLOCK_MAX_BITS 12 ///< log2 of max block size
+#define WMALL_BLOCK_MAX_BITS 14 ///< log2 of max block size
#define WMALL_BLOCK_MAX_SIZE (1 << WMALL_BLOCK_MAX_BITS) ///< maximum block size
#define WMALL_BLOCK_SIZES (WMALL_BLOCK_MAX_BITS - WMALL_BLOCK_MIN_BITS + 1) ///< possible block sizes
int8_t mclms_scaling;
int16_t mclms_coeffs[128];
int16_t mclms_coeffs_cur[4];
- int16_t mclms_prevvalues[64];
- int16_t mclms_updates[64];
+ int16_t mclms_prevvalues[WMALL_MAX_CHANNELS * 2 * 32];
+ int16_t mclms_updates[WMALL_MAX_CHANNELS * 2 * 32];
int mclms_recent;
int movave_scaling;
int ave_sum[2];
- int channel_residues[2][2048];
+ int channel_residues[2][WMALL_BLOCK_MAX_SIZE];
int lpc_coefs[2][40];
int lpc_order;
int lpc_scaling;
int lpc_intbits;
- int channel_coeffs[2][2048];
+ int channel_coeffs[2][WMALL_BLOCK_MAX_SIZE];
} WmallDecodeCtx;
channel_mask = AV_RL32(edata_ptr + 2);
s->bits_per_sample = AV_RL16(edata_ptr);
if (s->bits_per_sample == 16)
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
else if (s->bits_per_sample == 24) {
- avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- av_log_missing_feature(avctx, "bit-depth higher than 16", 0);
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+ av_log_missing_feature(avctx, "Bit-depth higher than 16", 0);
return AVERROR_PATCHWELCOME;
} else {
av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %d\n",
} else {
av_log_ask_for_sample(avctx, "Unsupported extradata size\n");
- return AVERROR_INVALIDDATA;
+ return AVERROR_PATCHWELCOME;
}
/* generic init */
/* get frame len */
s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate,
3, s->decode_flags);
+ av_assert0(s->samples_per_frame <= WMALL_BLOCK_MAX_SIZE);
/* init previous block len */
for (i = 0; i < avctx->channels; i++)
s->acfilter_scaling = get_bits(&s->gb, 4);
for (i = 0; i < s->acfilter_order; i++)
- s->acfilter_coeffs[i] = get_bits(&s->gb, s->acfilter_scaling) + 1;
+ s->acfilter_coeffs[i] = (s->acfilter_scaling ?
+ get_bits(&s->gb, s->acfilter_scaling) : 0) + 1;
}
static void decode_mclms(WmallDecodeCtx *s)
residue = quo;
else {
rem_bits = av_ceil_log2(ave_mean);
- rem = rem_bits ? get_bits(&s->gb, rem_bits) : 0;
+ rem = rem_bits ? get_bits_long(&s->gb, rem_bits) : 0;
residue = (quo << rem_bits) + rem;
}
int num_channels = s->num_channels;
for (ich = 0; ich < num_channels; ich++) {
+ pred[ich] = 0;
if (!s->is_channel_coded[ich])
continue;
- pred[ich] = 0;
for (i = 0; i < order * num_channels; i++)
pred[ich] += s->mclms_prevvalues[i + s->mclms_recent] *
s->mclms_coeffs[i + order * num_channels * ich];
{
if (s->num_channels != 2)
return;
- else if (s->is_channel_coded[0] && s->is_channel_coded[1]) {
+ else if (s->is_channel_coded[0] || s->is_channel_coded[1]) {
int icoef;
for (icoef = 0; icoef < tile_size; icoef++) {
s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1;
s->do_arith_coding = get_bits1(&s->gb);
if (s->do_arith_coding) {
- av_log_missing_feature(s->avctx, "arithmetic coding", 1);
+ av_log_missing_feature(s->avctx, "Arithmetic coding", 1);
return AVERROR_PATCHWELCOME;
}
s->do_ac_filter = get_bits1(&s->gb);
else
use_normal_update_speed(s, i);
revert_cdlms(s, i, 0, subframe_len);
+ } else {
+ memset(s->channel_residues[i], 0, sizeof(**s->channel_residues) * subframe_len);
}
}
if (s->do_mclms)
for (j = 0; j < subframe_len; j++) {
if (s->bits_per_sample == 16) {
- *s->samples_16[c] = (int16_t) s->channel_residues[c][j];
- s->samples_16[c] += s->num_channels;
+ *s->samples_16[c]++ = (int16_t) s->channel_residues[c][j] << padding_zeroes;
} else {
- *s->samples_32[c] = s->channel_residues[c][j];
- s->samples_32[c] += s->num_channels;
+ *s->samples_32[c]++ = s->channel_residues[c][j] << padding_zeroes;
}
}
}
int more_frames = 0, len = 0, i, ret;
s->frame.nb_samples = s->samples_per_frame;
- if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) {
+ if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) {
/* 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");
return ret;
}
for (i = 0; i < s->num_channels; i++) {
- s->samples_16[i] = (int16_t *)s->frame.data[0] + i;
- s->samples_32[i] = (int32_t *)s->frame.data[0] + i;
+ s->samples_16[i] = (int16_t *)s->frame.extended_data[i];
+ s->samples_32[i] = (int32_t *)s->frame.extended_data[i];
}
/* get frame length */
/* 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)) {
- int skip;
+ int av_unused skip;
/* usually true for the first frame */
if (get_bits1(gb)) {
/* decode the cross packet frame if it is valid */
if (num_bits_prev_frame < remaining_packet_bits && !s->packet_loss)
- decode_frame(s);
+ decode_frame(s);
} else if (s->num_saved_bits - s->frame_offset) {
av_dlog(avctx, "ignoring %x previously saved bits\n",
s->num_saved_bits - s->frame_offset);
* to decode incomplete frames in the s->len_prefix == 0 case. */
s->num_saved_bits = 0;
s->packet_loss = 0;
+ init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
}
} else {
s->next_packet_start = 0;
s->cdlms[0][0].order = 0;
s->frame.nb_samples = 0;
+ init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
}
AVCodec ff_wmalossless_decoder = {
.name = "wmalossless",
.type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_WMALOSSLESS,
+ .id = AV_CODEC_ID_WMALOSSLESS,
.priv_data_size = sizeof(WmallDecodeCtx),
.init = decode_init,
.decode = decode_packet,
.flush = flush,
.capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S32P,
+ AV_SAMPLE_FMT_NONE },
};