/*
* WMA compatible decoder
- * Copyright (c) 2002 The FFmpeg Project.
+ * Copyright (c) 2002 The FFmpeg Project
*
* This file is part of FFmpeg.
*
*/
/**
- * @file wmadec.c
+ * @file libavcodec/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
static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len);
#ifdef TRACE
-static void dump_shorts(WMADecodeContext *s, const char *name, const short *tab, int n)
+static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n)
{
int i;
}
}
-static void dump_floats(WMADecodeContext *s, 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;
flags2 = 0;
extradata = avctx->extradata;
if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) {
- flags1 = extradata[0] | (extradata[1] << 8);
- flags2 = extradata[2] | (extradata[3] << 8);
+ flags1 = AV_RL16(extradata);
+ flags2 = AV_RL16(extradata+2);
} 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);
+ flags1 = AV_RL32(extradata);
+ flags2 = AV_RL16(extradata+4);
}
// for(i=0; i<avctx->extradata_size; i++)
// av_log(NULL, AV_LOG_ERROR, "%02X ", extradata[i]);
s->use_bit_reservoir = flags2 & 0x0002;
s->use_variable_block_len = flags2 & 0x0004;
- ff_wma_init(avctx, flags2);
+ if(ff_wma_init(avctx, flags2)<0)
+ return -1;
/* init MDCT */
for(i = 0; i < s->nb_block_sizes; i++)
wma_lsp_to_curve_init(s, s->frame_len);
}
+ avctx->sample_fmt = SAMPLE_FMT_S16;
return 0;
}
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;
}
+
+ bsize = s->frame_len_bits - s->block_len_bits;
+
/* if no channel coded, no need to go further */
/* XXX: fix potential framing problems */
if (!v)
goto next;
- bsize = s->frame_len_bits - s->block_len_bits;
-
/* read total gain and extract corresponding number of bits for
coef escape coding */
total_gain = 1;
int i, n, a;
n = s->exponent_high_sizes[bsize];
for(i=0;i<n;i++) {
- a = get_bits(&s->gb, 1);
+ a = get_bits1(&s->gb);
s->high_band_coded[ch][i] = a;
/* if noise coding, the coefficients are not transmitted */
if (a)
/* exponents can be reused in short blocks. */
if ((s->block_len_bits == s->frame_len_bits) ||
- get_bits(&s->gb, 1)) {
+ get_bits1(&s->gb)) {
for(ch = 0; ch < s->nb_channels; ch++) {
if (s->channel_coded[ch]) {
if (s->use_exp_vlc) {
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;
}
}
+next:
for(ch = 0; ch < s->nb_channels; ch++) {
- if (s->channel_coded[ch]) {
- int n4, index, n;
+ int n4, index;
- n = s->block_len;
- n4 = s->block_len / 2;
- s->mdct_ctx[bsize].fft.imdct_calc(&s->mdct_ctx[bsize],
- s->output, s->coefs[ch], s->mdct_tmp);
+ n4 = s->block_len / 2;
+ if(s->channel_coded[ch]){
+ ff_imdct_calc(&s->mdct_ctx[bsize], s->output, s->coefs[ch]);
+ }else if(!(s->ms_stereo && ch==1))
+ memset(s->output, 0, sizeof(s->output));
- /* multiply by the window and add in the frame */
- index = (s->frame_len / 2) + s->block_pos - n4;
- wma_window(s, &s->frame_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]) {
- wma_window(s, &s->frame_out[1][index]);
- }
- }
+ /* multiply by the window and add in the frame */
+ index = (s->frame_len / 2) + s->block_pos - n4;
+ wma_window(s, &s->frame_out[ch][index]);
}
- next:
+
/* update block number */
s->block_num++;
s->block_pos += s->block_len;
/* decode a frame of frame_len 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;
iptr = s->frame_out[ch];
for(i=0;i<n;i++) {
- a = lrintf(*iptr++);
- if (a > 32767)
- a = 32767;
- else if (a < -32768)
- a = -32768;
- *ptr = a;
+ *ptr = av_clip_int16(lrintf(*iptr++));
ptr += incr;
}
/* prepare for next block */
static int wma_decode_superframe(AVCodecContext *avctx,
void *data, int *data_size,
- uint8_t *buf, int buf_size)
+ AVPacket *avpkt)
{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
WMACodecContext *s = avctx->priv_data;
int nb_frames, bit_offset, i, pos, len;
uint8_t *q;
s->last_superframe_len = 0;
return 0;
}
+ if (buf_size < s->block_align)
+ return 0;
+ buf_size = s->block_align;
samples = data;
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;
+ if((nb_frames+1) * s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n");
+ goto fail;
+ }
+
bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
if (s->last_superframe_len > 0) {
s->last_superframe_len = len;
memcpy(s->last_superframe, buf + pos, len);
} else {
+ if(s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n");
+ goto fail;
+ }
/* single frame decode */
if (wma_decode_frame(s, samples) < 0)
goto fail;
NULL,
ff_wma_end,
wma_decode_superframe,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
};
AVCodec wmav2_decoder =
NULL,
ff_wma_end,
wma_decode_superframe,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
};