From patchwork Tue Oct 1 13:54:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 51973 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cb8a:0:b0:48e:c0f8:d0de with SMTP id d10csp292254vqv; Tue, 1 Oct 2024 06:55:01 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCW7Wd3kADijZCWQK3fyDxWhUIwkvgL3YfwDpLGVz7dRCyi4e45/lThs81NLnU0rvtSQrEMGYK9Y65aZkyeSW/7p@gmail.com X-Google-Smtp-Source: AGHT+IEVcq5VMHGR9ziVidvLq/zty9mhi/ToAqfPe5JJztnfOkuApxGF2Vv3K/iFP7n26qSQhRA7 X-Received: by 2002:a2e:f0a:0:b0:2f6:1da6:1c64 with SMTP id 38308e7fff4ca-2f9d41a8595mr57920701fa.45.1727790900971; Tue, 01 Oct 2024 06:55:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727790900; cv=none; d=google.com; s=arc-20240605; b=KYkyX3MHl+Sb7aB8PPXfvJbcXcJk5JrfZPQfhkZgBNOScETkMeQMy4KrpYH0j+xN7U 5yUGHegn1YuuvexQJkDYiqOBvHKI0tl3PTKpnRbsKlow0igkiAcKDpGwCS0qY7u3a/Qv 3PJbOGBAb6BYfpKhcla5PkSRZF+SFm83PKKGlGab0pIiSJpTUp2G11P00932PWjZX4qK 3vDfCah6wdzDkHUlVsMI/O8NbrvZvhOqJz7FAKQfh7jXXPxaaBVVuHBWvHe0D6VZCsn7 kbWaB6CxUZkFzuedWqH8p5Yxonr01ST3BkOItV7Td9/gFaa6PEQG9PWAF7PVIsZc4b91 91ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=5WcFa6DBDTzRJdar2yTTEWv7a2GJGz9jQDUBfkcc+Jg=; fh=mZk9AfRmPBMGW9h158yccPeJgZmEjzU2tMQtLZcF184=; b=dpCINGaXaZxCEQjcQqDfZziFpAG1Oc8rwixqWYexYllr3kKqyG/IzTgcZVYKKsJg99 s5wrIZH3gYG+wHOLZBK6OgKNGc1UwHd+2OLyvl2Yq+SMt9a+LGn+TGzCbeTFDukgedOt yjfdyebJrwB9njBe9zqG+jSQY7py9LlyeOCQ0rBI/VzIv5DvBHzdAS9T6mGHGs6VkXhb HnNT6/lOwJ+xjrSWqubEZ7tNmhM0e60TAYXR2WJ2XXpXU749t38VWv4TePCSs9miU/LY g9nDbQKeyOT6qBxbnSib2tnQWZE3cIiLiwCtDjPElx28+kP+bxs/x4p41WAsLOmxRbg4 4DzA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=WEdgLcRY; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 4fb4d7f45d1cf-5c8824b0667si7285621a12.668.2024.10.01.06.55.00; Tue, 01 Oct 2024 06:55:00 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=WEdgLcRY; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DFC9C68DC96; Tue, 1 Oct 2024 16:54:56 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2F9E968D11F for ; Tue, 1 Oct 2024 16:54:49 +0300 (EEST) Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-20b7259be6fso27519025ad.0 for ; Tue, 01 Oct 2024 06:54:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727790887; x=1728395687; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=WTgj9XxtLQqVJx8VFK4hwXz+ce41mw7nVnKfPM9w73E=; b=WEdgLcRYz5EtiiMO82vp2QU7345ZwLotvL8IzwVbk1UqMl5bsHJbhKYmQNpnzfobi5 8gAB1Q/6HfinaGBHR9nPsLp+5wXJj7sOkzqyL2iEW1UwbfUyzOG6XSwa2OPMYVe1fago XooPIiUhlWTgOPzGP3MkIm4Bm8rvSMQaKoDr0Pkzc4FXUxXG1gwi2wS17FQdM3xd46VH wGpv9L2yq8PtVezVds7elPsns36zxw/MQfOGdl4qTkEVGobza4WHcijbd4+OxKLTarcY TNX8kZXherljTVKaUQQmH9+iZfKDMsNYla56W1WbVUnoL32u+K1rgfQr8tGGPdF7Yu+H A90A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727790887; x=1728395687; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=WTgj9XxtLQqVJx8VFK4hwXz+ce41mw7nVnKfPM9w73E=; b=edeN3LJgixltrnS6PanI+Xm8kwAqfsIkyHJEHmCkXyDEJ+Y+paK5OLWpLdjaWODFqO 4fQY4qnEPpozXMWpFI0+ls57BGGsPGxWMgs38uQkhhfirc/ETNxLD9bbSYlOubfvave2 idbNVDhbpFI6YAp61SQnQYHQrupbWmVs8BiFq/j/moR+EPg7TBbq2tlEDDE6VTPdZhx6 nH7NRkvATof6Uz15AX2kIJBUCeru2ZNUnAhFx96kS4OEKRRN+vFGPY8MG9i0WGVKA6gk X4lbGksDRHs1rl65dC3CVHUzvpZmDSfnS3XZsuUzj2zI8jUOfmLRuetWEzsK9T81F4Nk 1ESw== X-Gm-Message-State: AOJu0YwkImpH0K3SVBh70dI88dGMMzoZk9dVwKqg18VRm1K7eXVWt74i tL4nqNm0ccqKNv3RAFAnHkfeSR/w4yyEYRfcnN+RiVThL1ZzuBR880tC0USD X-Received: by 2002:a17:902:d2d0:b0:20b:433c:5833 with SMTP id d9443c01a7336-20b433c5de7mr227661045ad.26.1727790886908; Tue, 01 Oct 2024 06:54:46 -0700 (PDT) Received: from localhost ([112.64.8.17]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b37e20dffsm70117495ad.170.2024.10.01.06.54.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Oct 2024 06:54:46 -0700 (PDT) From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 1 Oct 2024 21:54:36 +0800 Message-Id: <20241001135438.39385-1-nuomi2021@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 1/3] avcodec: make a local copy of executor X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: x97YoJ8WTqeX We still need several refactors to improve the current VVC decoder's performance, which will frequently break the API/ABI. To mitigate this, we've copied the executor from avutil to avcodec. Once the API/ABI is stable, we will move this class back to avutil --- libavcodec/Makefile | 1 + libavcodec/executor.c | 221 ++++++++++++++++++++++++++++++++++++++++ libavcodec/executor.h | 73 +++++++++++++ libavcodec/vvc/thread.c | 8 +- 4 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 libavcodec/executor.c create mode 100644 libavcodec/executor.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index a4fcce3b42..da1a1aa945 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -43,6 +43,7 @@ OBJS = ac3_parser.o \ dirac.o \ dv_profile.o \ encode.o \ + executor.o \ get_buffer.o \ imgconvert.o \ jni.o \ diff --git a/libavcodec/executor.c b/libavcodec/executor.c new file mode 100644 index 0000000000..f8fc7c33ab --- /dev/null +++ b/libavcodec/executor.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2024 Nuo Mi + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include "libavutil/mem.h" +#include "libavutil/thread.h" + +#include "executor.h" + +#if !HAVE_THREADS + +#define ExecutorThread char + +#define executor_thread_create(t, a, s, ar) 0 +#define executor_thread_join(t, r) do {} while(0) + +#else + +#define ExecutorThread pthread_t + +#define executor_thread_create(t, a, s, ar) pthread_create(t, a, s, ar) +#define executor_thread_join(t, r) pthread_join(t, r) + +#endif //!HAVE_THREADS + +typedef struct ThreadInfo { + AVExecutor *e; + ExecutorThread thread; +} ThreadInfo; + +struct AVExecutor { + AVTaskCallbacks cb; + int thread_count; + bool recursive; + + ThreadInfo *threads; + uint8_t *local_contexts; + + AVMutex lock; + AVCond cond; + int die; + + AVTask *tasks; +}; + +static AVTask* remove_task(AVTask **prev, AVTask *t) +{ + *prev = t->next; + t->next = NULL; + return t; +} + +static void add_task(AVTask **prev, AVTask *t) +{ + t->next = *prev; + *prev = t; +} + +static int run_one_task(AVExecutor *e, void *lc) +{ + AVTaskCallbacks *cb = &e->cb; + AVTask **prev; + + for (prev = &e->tasks; *prev && !cb->ready(*prev, cb->user_data); prev = &(*prev)->next) + /* nothing */; + if (*prev) { + AVTask *t = remove_task(prev, *prev); + if (e->thread_count > 0) + ff_mutex_unlock(&e->lock); + cb->run(t, lc, cb->user_data); + if (e->thread_count > 0) + ff_mutex_lock(&e->lock); + return 1; + } + return 0; +} + +#if HAVE_THREADS +static void *executor_worker_task(void *data) +{ + ThreadInfo *ti = (ThreadInfo*)data; + AVExecutor *e = ti->e; + void *lc = e->local_contexts + (ti - e->threads) * e->cb.local_context_size; + + ff_mutex_lock(&e->lock); + while (1) { + if (e->die) break; + + if (!run_one_task(e, lc)) { + //no task in one loop + ff_cond_wait(&e->cond, &e->lock); + } + } + ff_mutex_unlock(&e->lock); + return NULL; +} +#endif + +static void executor_free(AVExecutor *e, const int has_lock, const int has_cond) +{ + if (e->thread_count) { + //signal die + ff_mutex_lock(&e->lock); + e->die = 1; + ff_cond_broadcast(&e->cond); + ff_mutex_unlock(&e->lock); + + for (int i = 0; i < e->thread_count; i++) + executor_thread_join(e->threads[i].thread, NULL); + } + if (has_cond) + ff_cond_destroy(&e->cond); + if (has_lock) + ff_mutex_destroy(&e->lock); + + av_free(e->threads); + av_free(e->local_contexts); + + av_free(e); +} + +AVExecutor* ff_executor_alloc(const AVTaskCallbacks *cb, int thread_count) +{ + AVExecutor *e; + int has_lock = 0, has_cond = 0; + if (!cb || !cb->user_data || !cb->ready || !cb->run || !cb->priority_higher) + return NULL; + + e = av_mallocz(sizeof(*e)); + if (!e) + return NULL; + e->cb = *cb; + + e->local_contexts = av_calloc(FFMAX(thread_count, 1), e->cb.local_context_size); + if (!e->local_contexts) + goto free_executor; + + e->threads = av_calloc(FFMAX(thread_count, 1), sizeof(*e->threads)); + if (!e->threads) + goto free_executor; + + if (!thread_count) + return e; + + has_lock = !ff_mutex_init(&e->lock, NULL); + has_cond = !ff_cond_init(&e->cond, NULL); + + if (!has_lock || !has_cond) + goto free_executor; + + for (/* nothing */; e->thread_count < thread_count; e->thread_count++) { + ThreadInfo *ti = e->threads + e->thread_count; + ti->e = e; + if (executor_thread_create(&ti->thread, NULL, executor_worker_task, ti)) + goto free_executor; + } + return e; + +free_executor: + executor_free(e, has_lock, has_cond); + return NULL; +} + +void ff_executor_free(AVExecutor **executor) +{ + int thread_count; + + if (!executor || !*executor) + return; + thread_count = (*executor)->thread_count; + executor_free(*executor, thread_count, thread_count); + *executor = NULL; +} + +void ff_executor_execute(AVExecutor *e, AVTask *t) +{ + AVTaskCallbacks *cb = &e->cb; + AVTask **prev; + + if (e->thread_count) + ff_mutex_lock(&e->lock); + if (t) { + for (prev = &e->tasks; *prev && cb->priority_higher(*prev, t); prev = &(*prev)->next) + /* nothing */; + add_task(prev, t); + } + if (e->thread_count) { + ff_cond_signal(&e->cond); + ff_mutex_unlock(&e->lock); + } + + if (!e->thread_count || !HAVE_THREADS) { + if (e->recursive) + return; + e->recursive = true; + // We are running in a single-threaded environment, so we must handle all tasks ourselves + while (run_one_task(e, e->local_contexts)) + /* nothing */; + e->recursive = false; + } +} diff --git a/libavcodec/executor.h b/libavcodec/executor.h new file mode 100644 index 0000000000..05d4b1e189 --- /dev/null +++ b/libavcodec/executor.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 Nuo Mi + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * We still need several refactors to improve the current VVC decoder's performance, + * which will frequently break the API/ABI. To mitigate this, we've copied the executor from + * avutil to avcodec. Once the API/ABI is stable, we will move this class back to avutil + */ + +#ifndef AVCODEC_EXECUTOR_H +#define AVCODEC_EXECUTOR_H + +typedef struct AVExecutor AVExecutor; +typedef struct AVTask AVTask; + +struct AVTask { + AVTask *next; +}; + +typedef struct AVTaskCallbacks { + void *user_data; + + int local_context_size; + + // return 1 if a's priority > b's priority + int (*priority_higher)(const AVTask *a, const AVTask *b); + + // task is ready for run + int (*ready)(const AVTask *t, void *user_data); + + // run the task + int (*run)(AVTask *t, void *local_context, void *user_data); +} AVTaskCallbacks; + +/** + * Alloc executor + * @param callbacks callback structure for executor + * @param thread_count worker thread number, 0 for run on caller's thread directly + * @return return the executor + */ +AVExecutor* ff_executor_alloc(const AVTaskCallbacks *callbacks, int thread_count); + +/** + * Free executor + * @param e pointer to executor + */ +void ff_executor_free(AVExecutor **e); + +/** + * Add task to executor + * @param e pointer to executor + * @param t pointer to task. If NULL, it will wakeup one work thread + */ +void ff_executor_execute(AVExecutor *e, AVTask *t); + +#endif //AVCODEC_EXECUTOR_H diff --git a/libavcodec/vvc/thread.c b/libavcodec/vvc/thread.c index 86a7753c6a..72f5c51382 100644 --- a/libavcodec/vvc/thread.c +++ b/libavcodec/vvc/thread.c @@ -22,7 +22,7 @@ #include -#include "libavutil/executor.h" +#include "libavcodec/executor.h" #include "libavutil/mem.h" #include "libavutil/thread.h" @@ -109,7 +109,7 @@ static void add_task(VVCContext *s, VVCTask *t) atomic_fetch_add(&ft->nb_scheduled_tasks, 1); - av_executor_execute(s->executor, &t->u.task); + ff_executor_execute(s->executor, &t->u.task); } static void task_init(VVCTask *t, VVCTaskStage stage, VVCFrameContext *fc, const int rx, const int ry) @@ -692,12 +692,12 @@ AVExecutor* ff_vvc_executor_alloc(VVCContext *s, const int thread_count) task_ready, task_run, }; - return av_executor_alloc(&callbacks, thread_count); + return ff_executor_alloc(&callbacks, thread_count); } void ff_vvc_executor_free(AVExecutor **e) { - av_executor_free(e); + ff_executor_free(e); } void ff_vvc_frame_thread_free(VVCFrameContext *fc) From patchwork Tue Oct 1 13:54:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 51974 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cb8a:0:b0:48e:c0f8:d0de with SMTP id d10csp292374vqv; Tue, 1 Oct 2024 06:55:12 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVssjpOsdR+m173vLkw7P1Gb9ZZJjtVNLdEoRY7NnmZhEsvhqL77RnjYLmAcM+qn7UJ7Mh3+EgvFVUvZqPvUOlr@gmail.com X-Google-Smtp-Source: AGHT+IFBJXeCOHuiy/LkKqjmmxGCZ1a+JaSdHvlM5aioWeUwl2apDDgvk80gUGUmBq1zWVsHa7wU X-Received: by 2002:a17:907:848:b0:a93:c2ae:ec5 with SMTP id a640c23a62f3a-a93c492970amr1575424666b.31.1727790911694; Tue, 01 Oct 2024 06:55:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727790911; cv=none; d=google.com; s=arc-20240605; b=Vmf/VO82Hhg53d5wCFGrjQW3PJOdnqjLyJKJBYpH9qb9HSmiNiSMeKPd8BJOHzvuyo RSbSIIu3C+r6sXSTT28q/YE91EW1Ft/mp8H3/+yRO46vjtTRbkJTB9R/xunOuJUgPJ/w b2L6S39tctBAdbkMWiRoURISCHqCalflsy31H/4F73lgR/iYOW3V5ja53Ib+LjM1UuZW gkmPcqjzmZ0AYdkYaAQFOWfJmwWESuA8icPRSdDSNSlNK09umckQBzRHr41lZlkXxXqj 50v9cHClBGrviwY4eKONdA0UV6hj0lJtUNjT6TTMLKBLlfz0rDasgwDUBjlu/fXNnRtT WIhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=kRR86L+pA5DWUndsXKhvvrIwk1HJic+06JY7NrO0DHQ=; fh=mZk9AfRmPBMGW9h158yccPeJgZmEjzU2tMQtLZcF184=; b=II32s4UkxIodBRwtZj0Nt16poXGM6KO/ZVYPwEwzVxgeStnYp9Kn7nSZNYNKvhn57g xziTfE3bYpzWC9+B9mybkqP+1GgzKHN3b/f5liIbphK4mLkGbqQ110u2LndMZtv9Vt2L 6PvgRnZZH7Rtv7DUlF5ocWM2enodAJBWOoCCScJW78vhO+izf1bk4gOsZtMfm3s22n3m 5hJAvcW+wlLmETgfby/XltN5cZ3bezKnZGurOD6bDkFCCMwW9ZThUN36up4fUQxvvOS+ Lh+bN+BcH/R1wx14WBeyjp9voEAANhUly5LLwkIW4Eu7eH+f6SAFrK9nZwno3dhcDLYe N09Q==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b="Rn8/aZ92"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a640c23a62f3a-a93c2a857bcsi737558366b.974.2024.10.01.06.55.11; Tue, 01 Oct 2024 06:55:11 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b="Rn8/aZ92"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3E40E68DCBE; Tue, 1 Oct 2024 16:55:03 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 96FAA68DCB3 for ; Tue, 1 Oct 2024 16:54:56 +0300 (EEST) Received: by mail-pf1-f169.google.com with SMTP id d2e1a72fcca58-71b070ff24dso4963341b3a.2 for ; Tue, 01 Oct 2024 06:54:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727790894; x=1728395694; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YdMdCqhvpd2uKjslCQWUOPF8DrclLuf2x0ej5PywxYo=; b=Rn8/aZ920k5nmORCWhts2ZEsYK8puPtfc7YKw6smem2dg0rd3OGUxwym8cBUDESwAp iSFiyXy83DTOi+bDDQ/ge5aD3u800+ubI/q7iIAZvt//nZvddYqxiWh548Z7cel08DuT QZWxmKSH/XVlEL8PRfih4XszyaP71bmkTKh9JcnD3NMCsG+q19l/2yHs2PGdIpPzReP/ g2AxLa0HCZMu2d9ZqKdLEQhBGVVF8GhTx07EhbehiMxnRB3z+fJ2Vgq5zz4CtRxXeY5Y t48b0zHB1rRukqEEmzZGmF9imBfo6K4zmgPf3mRkpg+s/EB80YMCdnXeLKPvJyEOXnsl ByWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727790894; x=1728395694; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YdMdCqhvpd2uKjslCQWUOPF8DrclLuf2x0ej5PywxYo=; b=FOg5yvM3p/KhlwR0QCvn3wuLsIxBtzuPCaSuxYKFVtyk0AL3zgtC2o2g2ALEO6bSgI fT7y3Wi5u1H1LeyEQY0cymxD1n2F0CwUTFVEO41/M6EHzSYE8Sbwpbb0X3muaQs4LvEV b9K//JZhSLyUEf2be/d/guyAgjPqbd4C9BJ/Cz9kfBx4FBPgRAWglLi58XG/lWslA5I7 SrjuOgQRvB/vdaLEsbns8thjhsIIPz3L+o6WjJ3xZXQ9ElinZHjyuGvoHi1UqVk/S38o OQrVDLyhRquXohhxzgw4HZw4kmj9/YhBQ2Vletr1cYRJJSvNaKtLMcTvfKhuXXTAFKEY HBrw== X-Gm-Message-State: AOJu0Yygua1M97zUjjMN5OHLhy9VSqSP8JARKIhc7cZFQVQQXw3KUL5K B9RabzbJG7UonUmLtxL4PU+ap3d6etxemsq4aS2o1GjMvTWqwUdCNaQiPIMY X-Received: by 2002:a05:6a20:e196:b0:1d3:e4e:b2bf with SMTP id adf61e73a8af0-1d4fa68ee9bmr23366581637.16.1727790894523; Tue, 01 Oct 2024 06:54:54 -0700 (PDT) Received: from localhost ([112.64.8.17]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71b2649a2cesm8005031b3a.43.2024.10.01.06.54.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Oct 2024 06:54:54 -0700 (PDT) From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 1 Oct 2024 21:54:37 +0800 Message-Id: <20241001135438.39385-2-nuomi2021@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001135438.39385-1-nuomi2021@gmail.com> References: <20241001135438.39385-1-nuomi2021@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 2/3] avcodec/executor: remove unused ready callback X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pfXS7YS48RlG Due to the nature of multithreading, using a "ready check" mechanism may introduce a deadlock. For example: Suppose all tasks have been submitted to the executor, and the last thread checks the entire list and finds no ready tasks. It then goes to sleep, waiting for a new task. However, for some multithreading-related reason, a task becomes ready after the check. Since no other thread is aware of this and no new tasks are being added to the executor, a deadlock occurs. In VVC, this function is unnecessary because we use a scoreboard. All tasks submitted to the executor are ready tasks. --- libavcodec/executor.c | 6 ++---- libavcodec/executor.h | 3 --- libavcodec/vvc/thread.c | 8 -------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/libavcodec/executor.c b/libavcodec/executor.c index f8fc7c33ab..8e6c134ba7 100644 --- a/libavcodec/executor.c +++ b/libavcodec/executor.c @@ -79,10 +79,8 @@ static void add_task(AVTask **prev, AVTask *t) static int run_one_task(AVExecutor *e, void *lc) { AVTaskCallbacks *cb = &e->cb; - AVTask **prev; + AVTask **prev = &e->tasks; - for (prev = &e->tasks; *prev && !cb->ready(*prev, cb->user_data); prev = &(*prev)->next) - /* nothing */; if (*prev) { AVTask *t = remove_task(prev, *prev); if (e->thread_count > 0) @@ -143,7 +141,7 @@ AVExecutor* ff_executor_alloc(const AVTaskCallbacks *cb, int thread_count) { AVExecutor *e; int has_lock = 0, has_cond = 0; - if (!cb || !cb->user_data || !cb->ready || !cb->run || !cb->priority_higher) + if (!cb || !cb->user_data || !cb->run || !cb->priority_higher) return NULL; e = av_mallocz(sizeof(*e)); diff --git a/libavcodec/executor.h b/libavcodec/executor.h index 05d4b1e189..c4688c86e6 100644 --- a/libavcodec/executor.h +++ b/libavcodec/executor.h @@ -42,9 +42,6 @@ typedef struct AVTaskCallbacks { // return 1 if a's priority > b's priority int (*priority_higher)(const AVTask *a, const AVTask *b); - // task is ready for run - int (*ready)(const AVTask *t, void *user_data); - // run the task int (*run)(AVTask *t, void *local_context, void *user_data); } AVTaskCallbacks; diff --git a/libavcodec/vvc/thread.c b/libavcodec/vvc/thread.c index 72f5c51382..da7fafed74 100644 --- a/libavcodec/vvc/thread.c +++ b/libavcodec/vvc/thread.c @@ -372,13 +372,6 @@ static int task_is_stage_ready(VVCTask *t, int add) return task_has_target_score(t, stage, score); } -static int task_ready(const AVTask *_t, void *user_data) -{ - VVCTask *t = (VVCTask*)_t; - - return task_is_stage_ready(t, 0); -} - #define CHECK(a, b) \ do { \ if ((a) != (b)) \ @@ -689,7 +682,6 @@ AVExecutor* ff_vvc_executor_alloc(VVCContext *s, const int thread_count) s, sizeof(VVCLocalContext), task_priority_higher, - task_ready, task_run, }; return ff_executor_alloc(&callbacks, thread_count); From patchwork Tue Oct 1 13:54:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 51977 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cb8a:0:b0:48e:c0f8:d0de with SMTP id d10csp306176vqv; Tue, 1 Oct 2024 07:11:16 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCV90G9K9tIJgUaLlgbw0MpYRZTCw/8FIZugxo8/Jy8Jzokgkm5UNYswDGUNeBDM0FCF9vNMRpjidjHFuNvws0BH@gmail.com X-Google-Smtp-Source: AGHT+IGHRHrVWi8K557GumrZgH/9gQouytiEcQh1+DUhZHlp0WxeUIYyE4i7MRw3N0zch8ZUA9Da X-Received: by 2002:a2e:752:0:b0:2f6:d5e2:7889 with SMTP id 38308e7fff4ca-2f9d3e7923dmr69742101fa.19.1727791876025; Tue, 01 Oct 2024 07:11:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727791876; cv=none; d=google.com; s=arc-20240605; b=Gz/4kOGp50t55e3Myr0/K5SvQgormjsminngBL69RUPqjKHJXSOlOAy2/9WdmzMVWl Y0yxQmSVZe+oppdpEowfAarQuvu74bqRyTNPfti1Omp3NEpgPsb5B582fqcnZyOwPa8A /scVDDQZYLkB8+VQ8BYPWklIQ/br4N4V3M/5FPpQp6gGx19w8z4++/ZZg2L6MXHWd7a6 cXifnp9QF7kR3yPzXj3GZDE2A1SuylDbiMY/R/v2K6CU0g/6KIF/bd941EujOSyhuB/t Et7Cmy239UPVa9wSEJj2YjREhCFv0j54R7EYduNFdDuqLkLy1LywfAqFZgZfGpkP//jb tWsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=xJjeu7Dskp1eeAiWew7GYwl4APvVEd0QaMpLONKhDcA=; fh=mZk9AfRmPBMGW9h158yccPeJgZmEjzU2tMQtLZcF184=; b=Tqb6lxyXCDWM2NDXZ0s2k57H0X+SnsN8PnhUV3Rpjj7i2sGdNze7P1YTVZAhDN/UeM sT4YAi3g/hlq7yBjVI3JxmYERXWxcYGJAEQbTNrcXhIcrsv7ESDn6FZbr+eh57HySwGY oNhsiIdII7118Qrx17EXVTXJuJ/rNB3IVC4WysjdBBo+BprEnY5wAs4BRcQCW6zVlezr Nay7Zk3HFGoCev5BXszUM6d59Yk2yG4QFQTKI9ECh+FiuUOGNHwFz+lGqeLyFb3uGk8Q JraLF7udGKjnL0fjCEQY9J+XBG6Mpz+dzXnE0rIr1YxqPlA5460fkzQatDkdOzBY7h91 dJLw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b="KJq/By13"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 38308e7fff4ca-2fac087d8bdsi23776101fa.415.2024.10.01.07.11.15; Tue, 01 Oct 2024 07:11:15 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b="KJq/By13"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8651368DCBF; Tue, 1 Oct 2024 16:55:07 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1FACE68DCCE for ; Tue, 1 Oct 2024 16:55:01 +0300 (EEST) Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-6e7b121be30so3697906a12.1 for ; Tue, 01 Oct 2024 06:55:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727790899; x=1728395699; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=18NAV5S/PjKhBSLlfP/cY3Q9Jb2Lb5SCwMgMHI4ayts=; b=KJq/By13LJS83RyvLuGRR/H6aMTr4FElZAYiWcLKFOvKa1FzXIlo2o+T34dmINRlDV ndX6lHUWGx8o82c2Ofiye0fFJkCJEoxJWDWY3YrTRTN36SwT2tNyz2eQJDhKaHLrFSoH 6NizIinUt61sfX+v3h2RJmXYTkfMQNfHCuJbGY9sHPCBqIyu5j8nswp/OVldVd3eGzmM KavTLr1aXxPwBt5Y9FJWjiGN/dnyGSHhxWtk2xxDcfMPnerA//2Ir6o/pCzP0iw8YjTh vJ+CbnP3uBrDY/PltfjISWkdTLkFFwtMBASqQ8Yln2dQke9/D+AVfEMprdCFB4MT06uG UV1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727790899; x=1728395699; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=18NAV5S/PjKhBSLlfP/cY3Q9Jb2Lb5SCwMgMHI4ayts=; b=LaX7PHtGL0qhnNAWbmdqXCuj6q7HXXIhwVtHMlrnLRtfYQpK8jOuH4d1+iJjAmU2e4 DkknMkKV3QCNO8foTgSZVbvV3q5s/72jOVjlxYbgaQoi9hVSJZOjm+yTqEIRVAL8eicp LNPQjjO4OWbOtS3CAzzG2XOYufntJ2n1tg+Wo8h+z+yJEB/1gO/4ozcHFd39aHzPMB9E VSE5kTXX5OYzlQqOd2g7+HhDOiW6bRi06Pa1Jz/drRfngOqvJzC3AmDoF6OtEesaxJyP 3NOnUiCks6OXi8cnc7NXNiCWqMA9DDl+4fR9xasxTvQ51XVb0EIDq8URtLJyiMjT4/OQ xsCA== X-Gm-Message-State: AOJu0YxwE6U3yyeSq4TeM0CLvmyBm9UIFWMERvuJ7Bg7H2TAXWTZ5No2 NPvhN+ZfwXlfkP/9hfPvTYXesY/neySYSYRIV3qlwAszM13GsrePl1ViaY6s X-Received: by 2002:a05:6a21:460c:b0:1c8:b849:c605 with SMTP id adf61e73a8af0-1d4fa8105edmr22970681637.44.1727790899125; Tue, 01 Oct 2024 06:54:59 -0700 (PDT) Received: from localhost ([112.64.8.17]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71b26539c5asm8000531b3a.210.2024.10.01.06.54.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Oct 2024 06:54:58 -0700 (PDT) From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 1 Oct 2024 21:54:38 +0800 Message-Id: <20241001135438.39385-3-nuomi2021@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001135438.39385-1-nuomi2021@gmail.com> References: <20241001135438.39385-1-nuomi2021@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 3/3] avcodec/vvc: simplify priority logical to improve performance for 4K/8K X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: hT/m6AX75BLO For 4K/8K video processing, it's possible to have over 1,000 tasks pending on the executor. In such cases, O(n) and O(log(n)) insertion times are too costly. Reducing this to O(1) will significantly decrease the time spent in critical sections clip | before | after | delta ------------------------------------------------------------|--------|--------|------- VVC_HDR_UHDTV2_OpenGOP_7680x4320_50fps_HLG10.bit | 24 | 27 | 12.5% VVC_HDR_UHDTV2_OpenGOP_7680x4320_50fps_HLG10_HighBitrate.bit| 12 | 17 | 41.7% tears_of_steel_4k_8M_8bit_2000.vvc | 34 | 102 | 200.0% VVC_UHDTV1_OpenGOP_3840x2160_60fps_HLG10.bit | 126 | 128 | 1.6% RitualDance_1920x1080_60_10_420_37_RA.266 | 350 | 378 | 8.0% NovosobornayaSquare_1920x1080.bin | 341 | 369 | 8.2% Tango2_3840x2160_60_10_420_27_LD.266 | 69 | 70 | 1.4% RitualDance_1920x1080_60_10_420_32_LD.266 | 243 | 259 | 6.6% Chimera_8bit_1080P_1000_frames.vvc | 420 | 392 | -6.7% BQTerrace_1920x1080_60_10_420_22_RA.vvc | 148 | 144 | -2.7% --- libavcodec/executor.c | 52 ++++++++++++++++++++++++++--------------- libavcodec/executor.h | 5 ++-- libavcodec/vvc/thread.c | 48 +++++++++++++++---------------------- 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/libavcodec/executor.c b/libavcodec/executor.c index 8e6c134ba7..6cea851e6a 100644 --- a/libavcodec/executor.c +++ b/libavcodec/executor.c @@ -48,6 +48,11 @@ typedef struct ThreadInfo { ExecutorThread thread; } ThreadInfo; +typedef struct Queue { + AVTask *head; + AVTask *tail; +} Queue; + struct AVExecutor { AVTaskCallbacks cb; int thread_count; @@ -60,29 +65,39 @@ struct AVExecutor { AVCond cond; int die; - AVTask *tasks; + Queue *q; }; -static AVTask* remove_task(AVTask **prev, AVTask *t) +static AVTask* remove_task(Queue *q) { - *prev = t->next; - t->next = NULL; + AVTask *t = q->head; + if (t) { + q->head = t->next; + t->next = NULL; + if (!q->head) + q->tail = NULL; + } return t; } -static void add_task(AVTask **prev, AVTask *t) +static void add_task(Queue *q, AVTask *t) { - t->next = *prev; - *prev = t; + t->next = NULL; + if (!q->head) + q->tail = q->head = t; + else + q->tail = q->tail->next = t; } static int run_one_task(AVExecutor *e, void *lc) { AVTaskCallbacks *cb = &e->cb; - AVTask **prev = &e->tasks; + AVTask *t = NULL; + + for (int i = 0; i < e->cb.priorities && !t; i++) + t = remove_task(e->q + i); - if (*prev) { - AVTask *t = remove_task(prev, *prev); + if (t) { if (e->thread_count > 0) ff_mutex_unlock(&e->lock); cb->run(t, lc, cb->user_data); @@ -132,6 +147,7 @@ static void executor_free(AVExecutor *e, const int has_lock, const int has_cond) ff_mutex_destroy(&e->lock); av_free(e->threads); + av_free(e->q); av_free(e->local_contexts); av_free(e); @@ -141,7 +157,7 @@ AVExecutor* ff_executor_alloc(const AVTaskCallbacks *cb, int thread_count) { AVExecutor *e; int has_lock = 0, has_cond = 0; - if (!cb || !cb->user_data || !cb->run || !cb->priority_higher) + if (!cb || !cb->user_data || !cb->run || !cb->priorities) return NULL; e = av_mallocz(sizeof(*e)); @@ -153,6 +169,10 @@ AVExecutor* ff_executor_alloc(const AVTaskCallbacks *cb, int thread_count) if (!e->local_contexts) goto free_executor; + e->q = av_calloc(e->cb.priorities, sizeof(Queue)); + if (!e->q) + goto free_executor; + e->threads = av_calloc(FFMAX(thread_count, 1), sizeof(*e->threads)); if (!e->threads) goto free_executor; @@ -192,16 +212,10 @@ void ff_executor_free(AVExecutor **executor) void ff_executor_execute(AVExecutor *e, AVTask *t) { - AVTaskCallbacks *cb = &e->cb; - AVTask **prev; - if (e->thread_count) ff_mutex_lock(&e->lock); - if (t) { - for (prev = &e->tasks; *prev && cb->priority_higher(*prev, t); prev = &(*prev)->next) - /* nothing */; - add_task(prev, t); - } + if (t) + add_task(e->q + t->priority % e->cb.priorities, t); if (e->thread_count) { ff_cond_signal(&e->cond); ff_mutex_unlock(&e->lock); diff --git a/libavcodec/executor.h b/libavcodec/executor.h index c4688c86e6..9d53534079 100644 --- a/libavcodec/executor.h +++ b/libavcodec/executor.h @@ -31,6 +31,7 @@ typedef struct AVExecutor AVExecutor; typedef struct AVTask AVTask; struct AVTask { + int priority; // task priority should >= 0 and < AVTaskCallbacks.priorities AVTask *next; }; @@ -39,8 +40,8 @@ typedef struct AVTaskCallbacks { int local_context_size; - // return 1 if a's priority > b's priority - int (*priority_higher)(const AVTask *a, const AVTask *b); + // How many priorities do we have? + int priorities; // run the task int (*run)(AVTask *t, void *local_context, void *user_data); diff --git a/libavcodec/vvc/thread.c b/libavcodec/vvc/thread.c index da7fafed74..a477c06ccb 100644 --- a/libavcodec/vvc/thread.c +++ b/libavcodec/vvc/thread.c @@ -103,13 +103,28 @@ typedef struct VVCFrameThread { AVCond cond; } VVCFrameThread; +#define PRIORITY_LOWEST 2 static void add_task(VVCContext *s, VVCTask *t) { - VVCFrameThread *ft = t->fc->ft; + VVCFrameThread *ft = t->fc->ft; + AVTask *task = &t->u.task; + const int priorities[] = { + 0, // VVC_TASK_STAGE_INIT, + 0, // VVC_TASK_STAGE_PARSE, + // For an 8K clip, a CTU line completed in the reference frame may trigger 64 and more inter tasks. + // We assign these tasks the lowest priority to avoid being overwhelmed with inter tasks. + PRIORITY_LOWEST, // VVC_TASK_STAGE_INTER + 1, // VVC_TASK_STAGE_RECON, + 1, // VVC_TASK_STAGE_LMCS, + 1, // VVC_TASK_STAGE_DEBLOCK_V, + 1, // VVC_TASK_STAGE_DEBLOCK_H, + 1, // VVC_TASK_STAGE_SAO, + 1, // VVC_TASK_STAGE_ALF, + }; atomic_fetch_add(&ft->nb_scheduled_tasks, 1); - - ff_executor_execute(s->executor, &t->u.task); + task->priority = priorities[t->stage]; + ff_executor_execute(s->executor, task); } static void task_init(VVCTask *t, VVCTaskStage stage, VVCFrameContext *fc, const int rx, const int ry) @@ -372,31 +387,6 @@ static int task_is_stage_ready(VVCTask *t, int add) return task_has_target_score(t, stage, score); } -#define CHECK(a, b) \ - do { \ - if ((a) != (b)) \ - return (a) < (b); \ - } while (0) - -static int task_priority_higher(const AVTask *_a, const AVTask *_b) -{ - const VVCTask *a = (const VVCTask*)_a; - const VVCTask *b = (const VVCTask*)_b; - - - if (a->stage <= VVC_TASK_STAGE_PARSE || b->stage <= VVC_TASK_STAGE_PARSE) { - CHECK(a->stage, b->stage); - CHECK(a->fc->decode_order, b->fc->decode_order); //decode order - CHECK(a->ry, b->ry); - return a->rx < b->rx; - } - - CHECK(a->fc->decode_order, b->fc->decode_order); //decode order - CHECK(a->rx + a->ry + a->stage, b->rx + b->ry + b->stage); //zigzag with type - CHECK(a->rx + a->ry, b->rx + b->ry); //zigzag - return a->ry < b->ry; -} - static void check_colocation(VVCContext *s, VVCTask *t) { const VVCFrameContext *fc = t->fc; @@ -681,7 +671,7 @@ AVExecutor* ff_vvc_executor_alloc(VVCContext *s, const int thread_count) AVTaskCallbacks callbacks = { s, sizeof(VVCLocalContext), - task_priority_higher, + PRIORITY_LOWEST + 1, task_run, }; return ff_executor_alloc(&callbacks, thread_count);