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); + } }