diff options
Diffstat (limited to 'libavcodec/wmadec.c')
-rw-r--r-- | libavcodec/wmadec.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 2dd5898d76..466c1a9a10 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -1,21 +1,21 @@ /* * WMA compatible decoder - * Copyright (c) 2002 The Libav Project + * Copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -93,6 +93,16 @@ static av_cold int wma_decode_init(AVCodecContext * avctx) s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; + if(avctx->codec->id == AV_CODEC_ID_WMAV2 && avctx->extradata_size >= 8){ + if(AV_RL16(extradata+4)==0xd && s->use_variable_block_len){ + av_log(avctx, AV_LOG_WARNING, "Disabling use_variable_block_len, if this fails contact the ffmpeg developers and send us the file\n"); + s->use_variable_block_len= 0; // this fixes issue1503 + } + } + + for (i=0; i<MAX_CHANNELS; i++) + s->max_exponent[i] = 1.0; + if(ff_wma_init(avctx, flags2)<0) return -1; @@ -472,6 +482,11 @@ static int wma_decode_block(WMACodecContext *s) s->block_len_bits = s->frame_len_bits; } + if (s->frame_len_bits - s->block_len_bits >= s->nb_block_sizes){ + av_log(s->avctx, AV_LOG_ERROR, "block_len_bits not initialized to a valid value\n"); + return -1; + } + /* now check if the block length is coherent with the frame length */ s->block_len = 1 << s->block_len_bits; if ((s->block_pos + s->block_len) > s->frame_len){ @@ -500,6 +515,10 @@ static int wma_decode_block(WMACodecContext *s) coef escape coding */ total_gain = 1; for(;;) { + if (get_bits_left(&s->gb) < 7) { + av_log(s->avctx, AV_LOG_ERROR, "total_gain overread\n"); + return AVERROR_INVALIDDATA; + } a = get_bits(&s->gb, 7); total_gain += a; if (a != 127) @@ -812,7 +831,8 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, buf_size, avctx->block_align); return AVERROR_INVALIDDATA; } - buf_size = avctx->block_align; + if(avctx->block_align) + buf_size = avctx->block_align; init_get_bits(&s->gb, buf, buf_size*8); @@ -820,16 +840,18 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, /* read super frame header */ skip_bits(&s->gb, 4); /* super frame index */ nb_frames = get_bits(&s->gb, 4) - (s->last_superframe_len <= 0); + if (nb_frames <= 0) { + av_log(avctx, AV_LOG_ERROR, "nb_frames is %d\n", nb_frames); + return AVERROR_INVALIDDATA; + } } else { nb_frames = 1; } /* get output buffer */ frame->nb_samples = nb_frames * s->frame_len; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; - } samples = (float **)frame->extended_data; samples_offset = 0; @@ -905,13 +927,13 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, samples_offset += s->frame_len; } - av_dlog(s->avctx, "%d %d %d %d outbytes:%td eaten:%d\n", + av_dlog(s->avctx, "%d %d %d %d outbytes:%"PTRDIFF_SPECIFIER" eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len, (int8_t *)samples - (int8_t *)data, avctx->block_align); *got_frame_ptr = 1; - return avctx->block_align; + return buf_size; fail: /* when error, we reset the bit reservoir */ s->last_superframe_len = 0; @@ -926,6 +948,7 @@ static av_cold void flush(AVCodecContext *avctx) s->last_superframe_len= 0; } +#if CONFIG_WMAV1_DECODER AVCodec ff_wmav1_decoder = { .name = "wmav1", .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), @@ -940,7 +963,8 @@ AVCodec ff_wmav1_decoder = { .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; - +#endif +#if CONFIG_WMAV2_DECODER AVCodec ff_wmav2_decoder = { .name = "wmav2", .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), @@ -955,3 +979,4 @@ AVCodec ff_wmav2_decoder = { .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; +#endif |