}
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
s->lsp_pow_m_table2[i] = b - a;
b = a;
}
-#if 0
- for(i=1;i<20;i++) {
- float v, r1, r2;
- v = 5.0 / i;
- r1 = pow_m1_4(s, v);
- r2 = pow(v,-0.25);
- printf("%f^-0.25=%f e=%f\n", v, r1, r2 - r1);
- }
-#endif
}
/**
}
/* NOTE: this offset is the same as MPEG4 AAC ! */
last_exp += code - 60;
- if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) {
+ if ((unsigned)last_exp + 60 >= FF_ARRAY_ELEMS(pow_tab)) {
av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n",
last_exp);
return -1;
int coef_nb_bits, total_gain;
int nb_coefs[MAX_CHANNELS];
float mdct_norm;
+ FFTContext *mdct;
#ifdef TRACE
tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num);
}
next:
+ mdct = &s->mdct_ctx[bsize];
+
for(ch = 0; ch < s->nb_channels; ch++) {
int n4, index;
n4 = s->block_len / 2;
if(s->channel_coded[ch]){
- ff_imdct_calc(&s->mdct_ctx[bsize], s->output, s->coefs[ch]);
+ mdct->imdct_calc(mdct, s->output, s->coefs[ch]);
}else if(!(s->ms_stereo && ch==1))
memset(s->output, 0, sizeof(s->output));
return 0;
}
-static int wma_decode_superframe(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int wma_decode_superframe(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, 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;
+ int nb_frames, bit_offset, i, pos, len, ret;
uint8_t *q;
int16_t *samples;
s->last_superframe_len = 0;
return 0;
}
- if (buf_size < s->block_align)
- return 0;
+ if (buf_size < s->block_align) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Input packet size too small (%d < %d)\n",
+ buf_size, s->block_align);
+ return AVERROR_INVALIDDATA;
+ }
buf_size = s->block_align;
- samples = data;
-
init_get_bits(&s->gb, buf, buf_size*8);
if (s->use_bit_reservoir) {
/* read super frame header */
skip_bits(&s->gb, 4); /* super frame index */
- nb_frames = get_bits(&s->gb, 4) - 1;
+ nb_frames = get_bits(&s->gb, 4) - (s->last_superframe_len <= 0);
+ } else {
+ nb_frames = 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;
- }
+ /* get output buffer */
+ s->frame.nb_samples = nb_frames * s->frame_len;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)s->frame.data[0];
+ if (s->use_bit_reservoir) {
bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
+ if (bit_offset > get_bits_left(&s->gb)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid last frame bit offset %d > buf size %d (%d)\n",
+ bit_offset, get_bits_left(&s->gb), buf_size);
+ goto fail;
+ }
if (s->last_superframe_len > 0) {
// printf("skip=%d\n", s->last_bitoffset);
if (len > 0) {
*q++ = (get_bits)(&s->gb, len) << (8 - len);
}
+ memset(q, 0, FF_INPUT_BUFFER_PADDING_SIZE);
/* XXX: bit_offset bits into last frame */
- init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8);
+ init_get_bits(&s->gb, s->last_superframe, s->last_superframe_len * 8 + bit_offset);
/* skip unused bits */
if (s->last_bitoffset > 0)
skip_bits(&s->gb, s->last_bitoffset);
if (wma_decode_frame(s, samples) < 0)
goto fail;
samples += s->nb_channels * s->frame_len;
+ nb_frames--;
}
/* read each frame starting from bit_offset */
pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3;
- init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8);
+ if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8 || pos > buf_size * 8)
+ return AVERROR_INVALIDDATA;
+ init_get_bits(&s->gb, buf + (pos >> 3), (buf_size - (pos >> 3))*8);
len = pos & 7;
if (len > 0)
skip_bits(&s->gb, len);
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;
//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;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return s->block_align;
fail:
/* when error, we reset the bit reservoir */
s->last_superframe_len= 0;
}
-AVCodec ff_wmav1_decoder =
-{
- "wmav1",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAV1,
- sizeof(WMACodecContext),
- wma_decode_init,
- NULL,
- ff_wma_end,
- wma_decode_superframe,
- .flush=flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
+AVCodec ff_wmav1_decoder = {
+ .name = "wmav1",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAV1,
+ .priv_data_size = sizeof(WMACodecContext),
+ .init = wma_decode_init,
+ .close = ff_wma_end,
+ .decode = wma_decode_superframe,
+ .flush = flush,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
};
-AVCodec ff_wmav2_decoder =
-{
- "wmav2",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAV2,
- sizeof(WMACodecContext),
- wma_decode_init,
- NULL,
- ff_wma_end,
- wma_decode_superframe,
- .flush=flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
+AVCodec ff_wmav2_decoder = {
+ .name = "wmav2",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAV2,
+ .priv_data_size = sizeof(WMACodecContext),
+ .init = wma_decode_init,
+ .close = ff_wma_end,
+ .decode = wma_decode_superframe,
+ .flush = flush,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
};