diff options
Diffstat (limited to 'libavcodec/wavpack.c')
-rw-r--r-- | libavcodec/wavpack.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 0847238595..47f598a6fe 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -2,20 +2,20 @@ * WavPack lossless audio decoder * Copyright (c) 2006,2011 Konstantin Shishkov * - * 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 */ @@ -25,6 +25,7 @@ #include "avcodec.h" #include "get_bits.h" #include "internal.h" +#include "thread.h" #include "unary.h" #include "bytestream.h" @@ -54,6 +55,8 @@ #define WV_FLT_ZERO_SENT 0x08 #define WV_FLT_ZERO_SIGN 0x10 +#define WV_MAX_SAMPLES 131072 + enum WP_ID_Flags { WP_IDF_MASK = 0x3F, WP_IDF_IGNORE = 0x20, @@ -381,6 +384,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, INC_MED(2); } if (!c->error_limit) { + if (add >= 0x2000000U) { + av_log(ctx->avctx, AV_LOG_ERROR, "k %d is too large\n", add); + goto error; + } ret = base + get_tail(gb, add); if (get_bits_left(gb) <= 0) goto error; @@ -721,6 +728,13 @@ static av_cold int wv_alloc_frame_context(WavpackContext *c) return 0; } +static int init_thread_copy(AVCodecContext *avctx) +{ + WavpackContext *s = avctx->priv_data; + s->avctx = avctx; + return 0; +} + static av_cold int wavpack_decode_init(AVCodecContext *avctx) { WavpackContext *s = avctx->priv_data; @@ -748,6 +762,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, AVFrame *frame, const uint8_t *buf, int buf_size) { WavpackContext *wc = avctx->priv_data; + ThreadFrame tframe = { .f = frame }; WavpackFrameContext *s; GetByteContext gb; void *samples_l, *samples_r; @@ -908,7 +923,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_ENTROPY: if (size != 6 * (s->stereo_in + 1)) { av_log(avctx, AV_LOG_ERROR, - "Entropy vars size should be %i, got %i", + "Entropy vars size should be %i, got %i.\n", 6 * (s->stereo_in + 1), size); bytestream2_skip(&gb, ssize); continue; @@ -1025,7 +1040,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, chmask = bytestream2_get_le24(&gb); break; case 3: - chmask = bytestream2_get_le32(&gb);; + chmask = bytestream2_get_le32(&gb); break; case 5: bytestream2_skip(&gb, 1); @@ -1113,11 +1128,10 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } /* get output buffer */ - frame->nb_samples = s->samples; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + frame->nb_samples = s->samples + 1; + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; - } + frame->nb_samples = s->samples; } if (wc->ch_offset + s->stereo >= avctx->channels) { @@ -1174,7 +1188,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, /* determine number of samples */ s->samples = AV_RL32(buf + 20); frame_flags = AV_RL32(buf + 24); - if (s->samples <= 0) { + if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); return AVERROR_INVALIDDATA; @@ -1231,6 +1245,7 @@ AVCodec ff_wavpack_decoder = { .close = wavpack_decode_end, .decode = wavpack_decode_frame, .flush = wavpack_decode_flush, - .capabilities = CODEC_CAP_DR1, + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .long_name = NULL_IF_CONFIG_SMALL("WavPack"), }; |