diff options
Diffstat (limited to 'libavcodec/wma.c')
-rw-r--r-- | libavcodec/wma.c | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 697b41b..b499209 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -1,28 +1,27 @@ /* * WMA compatible codec - * Copyright (c) 2002-2007 The Libav Project + * Copyright (c) 2002-2007 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 */ #include "libavutil/attributes.h" #include "avcodec.h" -#include "bitstream.h" #include "internal.h" #include "sinewin.h" #include "wma.h" @@ -46,10 +45,10 @@ static av_cold int init_coef_vlc(VLC *vlc, uint16_t **prun_table, init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); - run_table = av_malloc(n * sizeof(uint16_t)); - level_table = av_malloc(n * sizeof(uint16_t)); - flevel_table = av_malloc(n * sizeof(*flevel_table)); - int_table = av_malloc(n * sizeof(uint16_t)); + run_table = av_malloc_array(n, sizeof(uint16_t)); + level_table = av_malloc_array(n, sizeof(uint16_t)); + flevel_table = av_malloc_array(n, sizeof(*flevel_table)); + int_table = av_malloc_array(n, sizeof(uint16_t)); if (!run_table || !level_table || !flevel_table || !int_table) { av_freep(&run_table); av_freep(&level_table); @@ -93,7 +92,6 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) avctx->bit_rate <= 0) return -1; - avpriv_float_dsp_init(&s->fdsp, avctx->flags & AV_CODEC_FLAG_BITEXACT); if (avctx->codec->id == AV_CODEC_ID_WMAV1) s->version = 1; @@ -142,6 +140,10 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) bps = (float) avctx->bit_rate / (float) (avctx->channels * avctx->sample_rate); s->byte_offset_bits = av_log2((int) (bps * s->frame_len / 8.0 + 0.5)) + 2; + if (s->byte_offset_bits + 3 > MIN_CACHE_BITS) { + av_log(avctx, AV_LOG_ERROR, "byte_offset_bits %d is too large\n", s->byte_offset_bits); + return AVERROR_PATCHWELCOME; + } /* compute high frequency value and choose if noise coding should * be activated */ @@ -183,7 +185,7 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) high_freq = high_freq * 0.5; } ff_dlog(s->avctx, "flags2=0x%x\n", flags2); - ff_dlog(s->avctx, "version=%d channels=%d sample_rate=%d bitrate=%d block_align=%d\n", + ff_dlog(s->avctx, "version=%d channels=%d sample_rate=%d bitrate=%"PRId64" block_align=%d\n", s->version, avctx->channels, avctx->sample_rate, avctx->bit_rate, avctx->block_align); ff_dlog(s->avctx, "bps=%f bps1=%f high_freq=%f bitoffset=%d\n", @@ -326,6 +328,10 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) #endif /* TRACE */ } + s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!s->fdsp) + return AVERROR(ENOMEM); + /* choose the VLC tables for the coefficients */ coef_vlc_table = 2; if (avctx->sample_rate >= 32000) { @@ -373,40 +379,41 @@ int ff_wma_end(AVCodecContext *avctx) ff_free_vlc(&s->hgain_vlc); for (i = 0; i < 2; i++) { ff_free_vlc(&s->coef_vlc[i]); - av_free(s->run_table[i]); - av_free(s->level_table[i]); - av_free(s->int_table[i]); + av_freep(&s->run_table[i]); + av_freep(&s->level_table[i]); + av_freep(&s->int_table[i]); } + av_freep(&s->fdsp); return 0; } /** * Decode an uncompressed coefficient. - * @param bc BitstreamContext + * @param gb GetBitContext * @return the decoded coefficient */ -unsigned int ff_wma_get_large_val(BitstreamContext *bc) +unsigned int ff_wma_get_large_val(GetBitContext *gb) { /** consumes up to 34 bits */ int n_bits = 8; /** decode length */ - if (bitstream_read_bit(bc)) { + if (get_bits1(gb)) { n_bits += 8; - if (bitstream_read_bit(bc)) { + if (get_bits1(gb)) { n_bits += 8; - if (bitstream_read_bit(bc)) + if (get_bits1(gb)) n_bits += 7; } } - return bitstream_read(bc, n_bits); + return get_bits_long(gb, n_bits); } /** * Decode run level compressed coefficients. * @param avctx codec context - * @param bc bitstream reader context - * @param vlc VLC table for bitstream_read_vlc + * @param gb bitstream reader context + * @param vlc vlc table for get_vlc2 * @param level_table level codes * @param run_table run codes * @param version 0 for wma1,2 1 for wmapro @@ -418,7 +425,7 @@ unsigned int ff_wma_get_large_val(BitstreamContext *bc) * @param coef_nb_bits number of bits for escaped level codes * @return 0 on success, -1 otherwise */ -int ff_wma_run_level_decode(AVCodecContext *avctx, BitstreamContext *bc, +int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, VLC *vlc, const float *level_table, const uint16_t *run_table, int version, WMACoef *ptr, int offset, int num_coefs, @@ -430,44 +437,48 @@ int ff_wma_run_level_decode(AVCodecContext *avctx, BitstreamContext *bc, uint32_t *iptr = (uint32_t *) ptr; const unsigned int coef_mask = block_len - 1; for (; offset < num_coefs; offset++) { - code = bitstream_read_vlc(bc, vlc->table, VLCBITS, VLCMAX); + code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); if (code > 1) { /** normal code */ offset += run_table[code]; - sign = bitstream_read_bit(bc) - 1; - iptr[offset & coef_mask] = ilvl[code] ^ sign << 31; + sign = get_bits1(gb) - 1; + iptr[offset & coef_mask] = ilvl[code] ^ (sign & 0x80000000); } else if (code == 1) { /** EOB */ break; } else { /** escape */ if (!version) { - level = bitstream_read(bc, coef_nb_bits); + level = get_bits(gb, coef_nb_bits); /** NOTE: this is rather suboptimal. reading * block_len_bits would be better */ - offset += bitstream_read(bc, frame_len_bits); + offset += get_bits(gb, frame_len_bits); } else { - level = ff_wma_get_large_val(bc); + level = ff_wma_get_large_val(gb); /** escape decode */ - if (bitstream_read_bit(bc)) { - if (bitstream_read_bit(bc)) { - if (bitstream_read_bit(bc)) { + if (get_bits1(gb)) { + if (get_bits1(gb)) { + if (get_bits1(gb)) { av_log(avctx, AV_LOG_ERROR, "broken escape sequence\n"); return -1; } else - offset += bitstream_read(bc, frame_len_bits) + 4; + offset += get_bits(gb, frame_len_bits) + 4; } else - offset += bitstream_read(bc, 2) + 1; + offset += get_bits(gb, 2) + 1; } } - sign = bitstream_read_bit(bc) - 1; + sign = get_bits1(gb) - 1; ptr[offset & coef_mask] = (level ^ sign) - sign; } } /** NOTE: EOB can be omitted */ if (offset > num_coefs) { - av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); + av_log(avctx, AV_LOG_ERROR, + "overflow (%d > %d) in spectral RLE, ignoring\n", + offset, + num_coefs + ); return -1; } |