From patchwork Fri Mar 27 12:57: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: 18429 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 26CDB44B885 for ; Fri, 27 Mar 2020 14:58:35 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0C82168B769; Fri, 27 Mar 2020 14:58:35 +0200 (EET) 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 9AD0168B52F for ; Fri, 27 Mar 2020 14:58:28 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 4130128589D for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id cXWqv3cs-CUL for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) 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) 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 C896A285554 for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 706A221200 for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 0A8qUaDb2RVH for ; Fri, 27 Mar 2020 13:58:26 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id BDBC12121A for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id A04D720E0099; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:39 +0100 Message-Id: <20200327125747.13460-5-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 05/14] pthread_frame: do not embed full AVFrame structs into per-thread contexts 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" Use the AVFrame API to properly allocate and free frames for delayed release. --- libavcodec/pthread_frame.c | 40 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 19073b1253..639c5ce574 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -93,9 +93,9 @@ typedef struct PerThreadContext { * Array of frames passed to ff_thread_release_buffer(). * Frames are released after all threads referencing them are finished. */ - AVFrame *released_buffers; - int num_released_buffers; - int released_buffers_allocated; + AVFrame **released_buffers; + int num_released_buffers; + int released_buffers_allocated; AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() int requested_flags; ///< flags passed to get_buffer() for requested_frame @@ -370,7 +370,7 @@ static void release_delayed_buffers(PerThreadContext *p) // fix extended data in case the caller screwed it up av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO || p->avctx->codec_type == AVMEDIA_TYPE_AUDIO); - f = &p->released_buffers[--p->num_released_buffers]; + f = p->released_buffers[--p->num_released_buffers]; f->extended_data = f->data; av_frame_unref(f); @@ -654,7 +654,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) { FrameThreadContext *fctx = avctx->internal->thread_ctx; const AVCodec *codec = avctx->codec; - int i; + int i, j; park_frame_worker_threads(fctx, thread_count); @@ -700,6 +700,9 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) pthread_cond_destroy(&p->progress_cond); pthread_cond_destroy(&p->output_cond); av_packet_unref(&p->avpkt); + + for (j = 0; j < p->released_buffers_allocated; j++) + av_frame_free(&p->released_buffers[j]); av_freep(&p->released_buffers); if (p->avctx) { @@ -988,7 +991,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) { PerThreadContext *p = avctx->internal->thread_ctx; FrameThreadContext *fctx; - AVFrame *dst, *tmp; + AVFrame *dst; int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || THREAD_SAFE_CALLBACKS(avctx); @@ -1009,16 +1012,23 @@ 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)) - goto fail; - tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated, - (p->num_released_buffers + 1) * - sizeof(*p->released_buffers)); - if (!tmp) - goto fail; - p->released_buffers = tmp; + if (p->num_released_buffers == p->released_buffers_allocated) { + AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1, + sizeof(*p->released_buffers)); + if (tmp) { + tmp[p->released_buffers_allocated] = av_frame_alloc(); + p->released_buffers = tmp; + } + + if (!tmp || !tmp[p->released_buffers_allocated]) { + av_log(avctx, AV_LOG_ERROR, "Cannot queue a buffer for delayed " + "release. This will leak memory.\n"); + goto fail; + } + p->released_buffers_allocated++; + } - dst = &p->released_buffers[p->num_released_buffers]; + dst = p->released_buffers[p->num_released_buffers]; av_frame_move_ref(dst, f->f); p->num_released_buffers++;