From patchwork Mon Feb 8 12:23:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 25507 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 1590044A631 for ; Mon, 8 Feb 2021 14:24:14 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F0817689CA7; Mon, 8 Feb 2021 14:24:13 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C792C6883B3 for ; Mon, 8 Feb 2021 14:24:06 +0200 (EET) Received: by mail-ej1-f54.google.com with SMTP id bl23so24293128ejb.5 for ; Mon, 08 Feb 2021 04:24:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=ToCa5CibQWj1v1SBODyVeYMRH77vlyf+fy0h9wiDAWA=; b=VQYodgmMjzd4BRGVum+q3A4M5vibPfaSaaHUlAUu0i7qrLWNW1MHmbnkd/lgn+kCjw PrVb1u1Fa85aW9FER95OezNU9L3Lqk6644jD0DlrUwhjxWvh9S6NXET4rB7PXP/wai6B 6nAYSm7TEy8kX+2m978gBgZ6J+h/wnD8IA+XePQLi5qC4zJDWByiZ6zMD/KmCbgMmwQs 5xwMqfWC3+4xoOv4IS6BhYe8MWeyp4od/dzJREaCbfmIPjROBSM/tV+Cf33cgORwHMm1 pZapqPCuCv3g5mkZHgpgBRxA3E0kPs4TXvCZFecUcf8GfP3skFjz90V9MQuTBf+wYYXT H6Uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=ToCa5CibQWj1v1SBODyVeYMRH77vlyf+fy0h9wiDAWA=; b=nD/QHv9gDbY1IVSTj4PHc3qj8WMccrAYa57+QyWnerEn9Tdn+t90LHScDtuX+2/Bex MS4WAS7iXia+uor2O0pvYqvQxb3unJJyPokeA3m5cH32mz29tG42NA9iIanWvI0Y3cx9 67WlvAziaPMvunZTpEscr8DjV+EeFa9gUZdibv/doZlyjkA2eb08xoAdM18YQzIC96C6 MzrXIRjfC9SC0ZSrIAM2Sc9TWwk02uXIbRo/slx21ImScdrOb6ijfkL7cpa4x5o8Haze STIpTG6Ehg6C+3DKpsQuKoHWeUR7Y4/DK9PCThy1gOquOpSH98LKfWqyqGbF8Cf3kL+U UYog== X-Gm-Message-State: AOAM533xE+4zf/LQvfmo5rJU/89WVDet+PK87xtYK9hlIRqaOZubLfZv 2oGdlLk9VDAqsevti02TMz1gp7ZNXtM= X-Google-Smtp-Source: ABdhPJw7fipo0iSEjoFIQ4ZsM3KMB7P80YV7gDfJQ4IMZ9c4qJQtXmw2DsGB/EZGT3kwbo6UT2ccWw== X-Received: by 2002:a17:906:a2da:: with SMTP id by26mr17229443ejb.191.1612787045993; Mon, 08 Feb 2021 04:24:05 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id ah20sm8486820ejc.99.2021.02.08.04.24.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Feb 2021 04:24:05 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Mon, 8 Feb 2021 13:23:27 +0100 Message-Id: <20210208122330.555354-5-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210208122330.555354-1-andreas.rheinhardt@gmail.com> References: <20210208122330.555354-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/8] avcodec/frame_thread_encoder: Avoid allocations of AVFrames 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 Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Up until now, when using frame threaded encoding, an AVFrame would be allocated for every frame to be encoded. These AVFrames would reach the worker threads via a FIFO of tasks, a structure which contained the AVFrame as well as an index into an array which gives the place where the worker thread shall put the returned packet; in addition to that, said structure also contained several unused fields. This commit changes this: The AVFrames are now allocated during init in the array that is up until now only used to return the packets. The contents to be encoded are put into the AVFrame in the same array element that is also used to return the packets. Signed-off-by: Andreas Rheinhardt --- libavcodec/frame_thread_encoder.c | 40 +++++++++++++------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 7c2894c933..5fe886aed9 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -42,7 +42,6 @@ typedef struct{ AVFrame *indata; AVPacket *outdata; int64_t return_code; - unsigned index; int finished; } Task; @@ -74,7 +73,8 @@ static void * attribute_align_arg worker(void *v){ int got_packet = 0, ret; AVPacket *pkt; AVFrame *frame; - Task task; + Task *task; + unsigned task_index; pthread_mutex_lock(&c->task_fifo_mutex); while (av_fifo_size(c->task_fifo) <= 0 || atomic_load(&c->exit)) { @@ -84,14 +84,15 @@ static void * attribute_align_arg worker(void *v){ } pthread_cond_wait(&c->task_fifo_cond, &c->task_fifo_mutex); } - av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL); + av_fifo_generic_read(c->task_fifo, &task_index, sizeof(task_index), NULL); pthread_mutex_unlock(&c->task_fifo_mutex); /* The main thread ensures that any two outstanding tasks have * different indices, ergo each worker thread owns its element * of c->tasks with the exception of finished, which is shared * with the main thread and guarded by finished_task_mutex. */ - frame = task.indata; - pkt = c->tasks[task.index].outdata; + task = &c->tasks[task_index]; + frame = task->indata; + pkt = task->outdata; ret = avctx->codec->encode2(avctx, pkt, frame, &got_packet); if(got_packet) { @@ -106,10 +107,9 @@ static void * attribute_align_arg worker(void *v){ pthread_mutex_lock(&c->buffer_mutex); av_frame_unref(frame); pthread_mutex_unlock(&c->buffer_mutex); - av_frame_free(&frame); pthread_mutex_lock(&c->finished_task_mutex); - c->tasks[task.index].return_code = ret; - c->tasks[task.index].finished = 1; + task->return_code = ret; + task->finished = 1; pthread_cond_signal(&c->finished_task_cond); pthread_mutex_unlock(&c->finished_task_mutex); } @@ -187,7 +187,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ c->parent_avctx = avctx; - c->task_fifo = av_fifo_alloc_array(BUFFER_SIZE, sizeof(Task)); + c->task_fifo = av_fifo_alloc_array(BUFFER_SIZE, sizeof(unsigned)); if (!c->task_fifo) { av_freep(&avctx->internal->frame_thread_encoder); return AVERROR(ENOMEM); @@ -202,7 +202,8 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ c->max_tasks = avctx->thread_count + 2; for (unsigned i = 0; i < c->max_tasks; i++) { - if (!(c->tasks[i].outdata = av_packet_alloc())) + if (!(c->tasks[i].indata = av_frame_alloc()) || + !(c->tasks[i].outdata = av_packet_alloc())) goto fail; } @@ -267,13 +268,8 @@ void ff_frame_thread_encoder_free(AVCodecContext *avctx){ pthread_join(c->worker[i], NULL); } - while (av_fifo_size(c->task_fifo) > 0) { - Task task; - av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL); - av_frame_free(&task.indata); - } - for (unsigned i = 0; i < c->max_tasks; i++) { + av_frame_free(&c->tasks[i].indata); av_packet_free(&c->tasks[i].outdata); } @@ -290,20 +286,16 @@ int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, AVFrame *frame, int *got_packet_ptr) { ThreadContext *c = avctx->internal->frame_thread_encoder; - Task *outtask, task; + Task *outtask; av_assert1(!*got_packet_ptr); if(frame){ - AVFrame *new = av_frame_alloc(); - if(!new) - return AVERROR(ENOMEM); - av_frame_move_ref(new, frame); + av_frame_move_ref(c->tasks[c->task_index].indata, frame); - task.index = c->task_index; - task.indata = (void*)new; pthread_mutex_lock(&c->task_fifo_mutex); - av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL); + av_fifo_generic_write(c->task_fifo, &c->task_index, + sizeof(c->task_index), NULL); pthread_cond_signal(&c->task_fifo_cond); pthread_mutex_unlock(&c->task_fifo_mutex);