From patchwork Sun Apr 5 20:32:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18685 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 5448F448725 for ; Sun, 5 Apr 2020 23:32:58 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2924768B15B; Sun, 5 Apr 2020 23:32:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BFC1968AF26 for ; Sun, 5 Apr 2020 23:32:51 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id E7D7128666C for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 1p4Eq67ayhDP for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 85DAD286669 for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 13E44214ED for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 55Y5S3C9qyxu for ; Sun, 5 Apr 2020 22:32:48 +0200 (CEST) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id C046A2175C for ; Sun, 5 Apr 2020 22:32:46 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 224A620E004C; Sun, 5 Apr 2020 22:32:42 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sun, 5 Apr 2020 22:32:38 +0200 Message-Id: <20200405203241.13033-1-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/4] pthread_frame: make sure ff_thread_release_buffer always cleans the frame X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/pthread_frame.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 172731a98e..0e51e89653 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -982,10 +982,11 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) PerThreadContext *p = avctx->internal->thread_ctx; FrameThreadContext *fctx; AVFrame *dst, *tmp; + int ret = 0; int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || THREAD_SAFE_CALLBACKS(avctx); - if (!f->f || !f->f->buf[0]) + if (!f->f) return; if (avctx->debug & FF_DEBUG_BUFFERS) @@ -994,7 +995,8 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) av_buffer_unref(&f->progress); f->owner[0] = f->owner[1] = NULL; - if (can_direct_free) { + // when the frame buffers are not allocated, just reset it to clean state + if (can_direct_free || !f->f->buf[0]) { av_frame_unref(f->f); return; } @@ -1002,13 +1004,17 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) fctx = p->parent; pthread_mutex_lock(&fctx->buffer_mutex); - if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) + if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) { + ret = AVERROR(ENOMEM); goto fail; + } tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated, (p->num_released_buffers + 1) * sizeof(*p->released_buffers)); - if (!tmp) + if (!tmp) { + ret = AVERROR(ENOMEM); goto fail; + } p->released_buffers = tmp; dst = &p->released_buffers[p->num_released_buffers]; @@ -1018,4 +1024,14 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) fail: pthread_mutex_unlock(&fctx->buffer_mutex); + + // make sure the frame is clean even if we fail to free it + // this leaks, but it is better than crashing + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Could not queue a frame for freeing, this will leak\n"); + memset(f->f->buf, 0, sizeof(f->f->buf)); + if (f->f->extended_buf) + memset(f->f->extended_buf, 0, f->f->nb_extended_buf * sizeof(*f->f->extended_buf)); + av_frame_unref(f->f); + } } From patchwork Sun Apr 5 20:32:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18688 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 882B6448725 for ; Sun, 5 Apr 2020 23:33:01 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 711B268B1E7; Sun, 5 Apr 2020 23:33:01 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 42E9568AF80 for ; Sun, 5 Apr 2020 23:32:52 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id EDF39286669 for ; Sun, 5 Apr 2020 22:32:51 +0200 (CEST) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id Ug_q1FKTDqcF for ; Sun, 5 Apr 2020 22:32:51 +0200 (CEST) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id D844128677B for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 31BFD2175C for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 24a4Aif51vSg for ; Sun, 5 Apr 2020 22:32:49 +0200 (CEST) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id C21EB2175D for ; Sun, 5 Apr 2020 22:32:46 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id B997020E0085; Sun, 5 Apr 2020 22:32:44 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sun, 5 Apr 2020 22:32:39 +0200 Message-Id: <20200405203241.13033-2-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200405203241.13033-1-anton@khirnov.net> References: <20200405203241.13033-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/4] decode: make sure ff_get_buffer() cleans the frame on failure X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Merge ff_get_buffer() and get_buffer_internal() to simplify the code. --- libavcodec/decode.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index af6bb3f952..de1e9fa4a4 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1903,7 +1903,7 @@ int ff_attach_decode_data(AVFrame *frame) return 0; } -static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) { const AVHWAccel *hwaccel = avctx->hwaccel; int override_dimensions = 1; @@ -1912,7 +1912,8 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { if ((ret = av_image_check_size2(FFALIGN(avctx->width, STRIDE_ALIGN), avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } if (frame->width <= 0 || frame->height <= 0) { @@ -1923,56 +1924,48 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) { av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { if (frame->nb_samples * (int64_t)avctx->channels > avctx->max_samples) { av_log(avctx, AV_LOG_ERROR, "samples per frame %d, exceeds max_samples %"PRId64"\n", frame->nb_samples, avctx->max_samples); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } } ret = ff_decode_frame_props(avctx, frame); if (ret < 0) - return ret; + goto fail; if (hwaccel) { if (hwaccel->alloc_frame) { ret = hwaccel->alloc_frame(avctx, frame); - goto end; + goto fail; } } else avctx->sw_pix_fmt = avctx->pix_fmt; ret = avctx->get_buffer2(avctx, frame, flags); if (ret < 0) - goto end; + goto fail; validate_avframe_allocation(avctx, frame); ret = ff_attach_decode_data(frame); if (ret < 0) - goto end; + goto fail; -end: if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && !(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { frame->width = avctx->width; frame->height = avctx->height; } - if (ret < 0) - av_frame_unref(frame); - - return ret; -} - -int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - int ret = get_buffer_internal(avctx, frame, flags); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - frame->width = frame->height = 0; - } + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + av_frame_unref(frame); return ret; } From patchwork Sun Apr 5 20:32:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18687 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 78F92448725 for ; Sun, 5 Apr 2020 23:33:00 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6451368B16A; Sun, 5 Apr 2020 23:33:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 42F5668B132 for ; Sun, 5 Apr 2020 23:32:52 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id EFA57286899 for ; Sun, 5 Apr 2020 22:32:51 +0200 (CEST) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id PA-xtitdu1ov for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id D71DD28666E for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 1A9BB213CC for ; Sun, 5 Apr 2020 22:32:49 +0200 (CEST) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id xU_DI5FHNp46 for ; Sun, 5 Apr 2020 22:32:46 +0200 (CEST) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id BD630214ED for ; Sun, 5 Apr 2020 22:32:46 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id DBCFC20E0012; Sun, 5 Apr 2020 22:32:44 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sun, 5 Apr 2020 22:32:40 +0200 Message-Id: <20200405203241.13033-3-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200405203241.13033-1-anton@khirnov.net> References: <20200405203241.13033-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/4] wavpack: fully support stream parameter changes X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Fix invalid memory access on DSD streams with changing channel count. --- libavcodec/wavpack.c | 122 +++++++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 32 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index b27262b94e..9cc4104dd0 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/buffer.h" #include "libavutil/channel_layout.h" #define BITSTREAM_READER_LE @@ -109,7 +110,10 @@ typedef struct WavpackContext { AVFrame *frame; ThreadFrame curr_frame, prev_frame; Modulation modulation; + + AVBufferRef *dsd_ref; DSDContext *dsdctx; + int dsd_channels; } WavpackContext; #define LEVEL_DECAY(a) (((a) + 0x80) >> 8) @@ -978,6 +982,32 @@ static av_cold int wv_alloc_frame_context(WavpackContext *c) return 0; } +static int wv_dsd_reset(WavpackContext *s, int channels) +{ + int i; + + s->dsdctx = NULL; + s->dsd_channels = 0; + av_buffer_unref(&s->dsd_ref); + + if (!channels) + return 0; + + if (channels > INT_MAX / sizeof(*s->dsdctx)) + return AVERROR(EINVAL); + + s->dsd_ref = av_buffer_allocz(channels * sizeof(*s->dsdctx)); + if (!s->dsd_ref) + return AVERROR(ENOMEM); + s->dsdctx = (DSDContext*)s->dsd_ref->data; + s->dsd_channels = channels; + + for (i = 0; i < channels; i++) + memset(s->dsdctx[i].buf, 0x69, sizeof(s->dsdctx[i].buf)); + + return 0; +} + #if HAVE_THREADS static int init_thread_copy(AVCodecContext *avctx) { @@ -1008,6 +1038,17 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) return ret; } + av_buffer_unref(&fdst->dsd_ref); + fdst->dsdctx = NULL; + fdst->dsd_channels = 0; + if (fsrc->dsd_ref) { + fdst->dsd_ref = av_buffer_ref(fsrc->dsd_ref); + if (!fdst->dsd_ref) + return AVERROR(ENOMEM); + fdst->dsdctx = (DSDContext*)fdst->dsd_ref->data; + fdst->dsd_channels = fsrc->dsd_channels; + } + return 0; } #endif @@ -1025,15 +1066,9 @@ static av_cold int wavpack_decode_init(AVCodecContext *avctx) s->curr_frame.f = av_frame_alloc(); s->prev_frame.f = av_frame_alloc(); - // the DSD to PCM context is shared (and used serially) between all decoding threads - s->dsdctx = av_calloc(avctx->channels, sizeof(DSDContext)); - - if (!s->curr_frame.f || !s->prev_frame.f || !s->dsdctx) + if (!s->curr_frame.f || !s->prev_frame.f) return AVERROR(ENOMEM); - for (int i = 0; i < avctx->channels; i++) - memset(s->dsdctx[i].buf, 0x69, sizeof(s->dsdctx[i].buf)); - ff_init_dsd_data(); return 0; @@ -1053,8 +1088,7 @@ static av_cold int wavpack_decode_end(AVCodecContext *avctx) ff_thread_release_buffer(avctx, &s->prev_frame); av_frame_free(&s->prev_frame.f); - if (!avctx->internal->is_copy) - av_freep(&s->dsdctx); + av_buffer_unref(&s->dsd_ref); return 0; } @@ -1065,6 +1099,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, WavpackContext *wc = avctx->priv_data; WavpackFrameContext *s; GetByteContext gb; + enum AVSampleFormat sample_fmt; void *samples_l = NULL, *samples_r = NULL; int ret; int got_terms = 0, got_weights = 0, got_samples = 0, @@ -1102,7 +1137,15 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, return AVERROR_INVALIDDATA; } s->frame_flags = bytestream2_get_le32(&gb); - bpp = av_get_bytes_per_sample(avctx->sample_fmt); + + if (s->frame_flags & (WV_FLOAT_DATA | WV_DSD_DATA)) + sample_fmt = AV_SAMPLE_FMT_FLTP; + else if ((s->frame_flags & 0x03) <= 1) + sample_fmt = AV_SAMPLE_FMT_S16P; + else + sample_fmt = AV_SAMPLE_FMT_S32P; + + bpp = av_get_bytes_per_sample(sample_fmt); orig_bpp = ((s->frame_flags & 0x03) + 1) << 3; multiblock = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK; @@ -1436,11 +1479,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); return AVERROR_INVALIDDATA; } - if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) { + if (!got_float && sample_fmt == AV_SAMPLE_FMT_FLTP) { av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); return AVERROR_INVALIDDATA; } - if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) { + if (s->got_extra_bits && sample_fmt != AV_SAMPLE_FMT_FLTP) { const int size = get_bits_left(&s->gb_extra_bits); const int wanted = s->samples * s->extra_bits << s->stereo_in; if (size < wanted) { @@ -1462,27 +1505,54 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } if (!wc->ch_offset) { + int new_channels = avctx->channels; + uint64_t new_chmask = avctx->channel_layout; + int new_samplerate; int sr = (s->frame_flags >> 23) & 0xf; if (sr == 0xf) { if (!sample_rate) { av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n"); return AVERROR_INVALIDDATA; } - avctx->sample_rate = sample_rate * rate_x; + new_samplerate = sample_rate * rate_x; } else - avctx->sample_rate = wv_rates[sr] * rate_x; + new_samplerate = wv_rates[sr] * rate_x; if (multiblock) { if (chan) - avctx->channels = chan; + new_channels = chan; if (chmask) - avctx->channel_layout = chmask; + new_chmask = chmask; } else { - avctx->channels = s->stereo ? 2 : 1; - avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO : - AV_CH_LAYOUT_MONO; + new_channels = s->stereo ? 2 : 1; + new_chmask = s->stereo ? AV_CH_LAYOUT_STEREO : + AV_CH_LAYOUT_MONO; + } + + if (new_chmask && + av_get_channel_layout_nb_channels(new_chmask) != new_channels) { + av_log(avctx, AV_LOG_ERROR, "Channel mask does not match the channel count\n"); + return AVERROR_INVALIDDATA; } + /* clear DSD state if stream properties change */ + if (new_channels != wc->dsd_channels || + new_chmask != avctx->channel_layout || + new_samplerate != avctx->sample_rate || + !!got_dsd != !!wc->dsdctx) { + ret = wv_dsd_reset(wc, got_dsd ? new_channels : 0); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error reinitializing the DSD context\n"); + return ret; + } + ff_thread_release_buffer(avctx, &wc->curr_frame); + } + avctx->channels = new_channels; + avctx->channel_layout = new_chmask; + avctx->sample_rate = new_samplerate; + avctx->sample_fmt = sample_fmt; + avctx->bits_per_raw_sample = orig_bpp; + ff_thread_release_buffer(avctx, &wc->prev_frame); FFSWAP(ThreadFrame, wc->curr_frame, wc->prev_frame); @@ -1546,10 +1616,7 @@ static void wavpack_decode_flush(AVCodecContext *avctx) { WavpackContext *s = avctx->priv_data; - if (!avctx->internal->is_copy) { - for (int i = 0; i < avctx->channels; i++) - memset(s->dsdctx[i].buf, 0x69, sizeof(s->dsdctx[i].buf)); - } + wv_dsd_reset(s, 0); } static int dsd_channel(AVCodecContext *avctx, void *frmptr, int jobnr, int threadnr) @@ -1590,15 +1657,6 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, s->modulation = (frame_flags & WV_DSD_DATA) ? MODULATION_DSD : MODULATION_PCM; - if (frame_flags & (WV_FLOAT_DATA | WV_DSD_DATA)) { - avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; - } else if ((frame_flags & 0x03) <= 1) { - avctx->sample_fmt = AV_SAMPLE_FMT_S16P; - } else { - avctx->sample_fmt = AV_SAMPLE_FMT_S32P; - avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3; - } - while (buf_size > WV_HEADER_SIZE) { frame_size = AV_RL32(buf + 4) - 12; buf += 20; From patchwork Sun Apr 5 20:32:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18686 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 97EC9448725 for ; Sun, 5 Apr 2020 23:32:59 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 83AC168B170; Sun, 5 Apr 2020 23:32:59 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C260E68AF80 for ; Sun, 5 Apr 2020 23:32:51 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 28AD028666B for ; Sun, 5 Apr 2020 22:32:50 +0200 (CEST) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id jUQqjq8ntqV5 for ; Sun, 5 Apr 2020 22:32:49 +0200 (CEST) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 9B19C286669 for ; Sun, 5 Apr 2020 22:32:49 +0200 (CEST) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 6E4992175E for ; Sun, 5 Apr 2020 22:32:48 +0200 (CEST) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id vEcX-PxMEmxL for ; Sun, 5 Apr 2020 22:32:46 +0200 (CEST) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id BB7F7213CC for ; Sun, 5 Apr 2020 22:32:46 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 0742E20E0087; Sun, 5 Apr 2020 22:32:44 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sun, 5 Apr 2020 22:32:41 +0200 Message-Id: <20200405203241.13033-4-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200405203241.13033-1-anton@khirnov.net> References: <20200405203241.13033-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/4] lavf/wvdec: remove artificial restrictions on stream parameter changes X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" They are not forbidden by the specification. --- libavformat/wvdec.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c index b9fc6a59f9..4159bf1253 100644 --- a/libavformat/wvdec.c +++ b/libavformat/wvdec.c @@ -208,24 +208,6 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) if (!wc->rate) wc->rate = rate * rate_x; - if (flags && bpp != wc->bpp) { - av_log(ctx, AV_LOG_ERROR, - "Bits per sample differ, this block: %i, header block: %i\n", - bpp, wc->bpp); - return AVERROR_INVALIDDATA; - } - if (flags && !wc->multichannel && chan != wc->chan) { - av_log(ctx, AV_LOG_ERROR, - "Channels differ, this block: %i, header block: %i\n", - chan, wc->chan); - return AVERROR_INVALIDDATA; - } - if (flags && rate != -1 && !(flags & WV_DSD) && rate * rate_x != wc->rate) { - av_log(ctx, AV_LOG_ERROR, - "Sampling rate differ, this block: %i, header block: %i\n", - rate * rate_x, wc->rate); - return AVERROR_INVALIDDATA; - } return 0; }