From patchwork Tue Oct 1 06:55:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 51955 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cb8a:0:b0:48e:c0f8:d0de with SMTP id d10csp85123vqv; Tue, 1 Oct 2024 00:51:12 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX9tZwRDqqiCojVp98Y/DoKBV1zdwcqNCyKz6fjmbcrE6nCye0+pnCSoADEE7d903NPuuQjQSiOMTg9bEQDRYKa@gmail.com X-Google-Smtp-Source: AGHT+IFC7QVrzuIX5HB1+350Bo8Lbx1O5+myfG05JYTd6KpOKyb8lUMVs8CmhaaaNguPQ5m46644 X-Received: by 2002:a05:6512:3a96:b0:535:6aa9:9868 with SMTP id 2adb3069b0e04-5389fc3c27fmr8346711e87.19.1727769072374; Tue, 01 Oct 2024 00:51:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727769072; cv=none; d=google.com; s=arc-20240605; b=LuWqxtcJXSQgCPVA2SmpDANXlJNK1RNCParyCHR7WbEUw40gkM8DMY91Lx69zg1ziQ U8HcxZShCXfk+n7wBBiz8ovn9ammpOHaHoidQQRtUBs8McoZz2eN9q9JJcYKing8Fd/f x2MrLe1IzMs/dFTDGLUfmtMN23+S5TKg4ZxcJ675VSYnKHAteq+Q6XZ7JtOcHpsID3Gw KmlbhQRUjbbHN07yfeenCYW5jhkd2/7sCZYjZdHvApuAL7t3OgZARz3ymBrbFlWAQZoa fYALy2TXn9LUapEu227nnu6Hc2dlF9bD8IPAoKSiJBbsfuAHODfQmOrVDKPzqqwLOSDO alIw== 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=l3A/4wU2hZsjQ0Vlrwp5BfjOCXrQ3/TWs6cbaKDTd0A=; fh=mZk9AfRmPBMGW9h158yccPeJgZmEjzU2tMQtLZcF184=; b=GOO2pcso/PJOVeW6ZwHJw4DMWgkBHsyiKV7dkbvocp9+BDJGZ8Swnf47Bp6HpUvT2q 4MRIHTvGZ5c2AKTLyuNzhJsS+qeQmcPyJ7wP5PlMDpr4tHy/FQMFaOkRoBaofBNzmg/L 4isd7+q48niHayBylaxyXEkxuTX67bb8oBSljP0NVCsYbG6iKH5HrBkM3ug56b+33efp e+xnE4WBrS97UcvdpFzCzoMFWyDJLEvS0g/9DBfL27SD+maesGMSkUCzj5oVGM0LWKIe trc6yt8FrLTLYc9ZtF2xnXBHdR3f9NeuKfrhf0C3iNv883rZcoBxrlMMdhQDNtR8pcFP JmTA==; 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=bEBs+a24; 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 2adb3069b0e04-538a045f98fsi3331313e87.609.2024.10.01.00.51.11; Tue, 01 Oct 2024 00:51:12 -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=bEBs+a24; 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 7EDCA68D9BD; Tue, 1 Oct 2024 09:56:23 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5E29568D775 for ; Tue, 1 Oct 2024 09:56:16 +0300 (EEST) Received: by mail-pg1-f178.google.com with SMTP id 41be03b00d2f7-7e6d04f74faso4452202a12.1 for ; Mon, 30 Sep 2024 23:56:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727765774; x=1728370574; 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=KGpcnT8eIFxBtjObmCg/DFSJtIGL8fTWQmZe4Er+eGM=; b=bEBs+a24Mx2SUzov94kuRurNvKSd1VE2MkFtU6Z2rTF5+rRKCD5N3blyIHo5bqHnmA Q4kjzv9cczzhTa2UY7Hc6YetbTGIwed6fXbLNydT1/hgxGGKQli2QHNA6cAr8Ia1WN28 OUO6C6L8+scPVohAbJvhvKE1fD68m1NrBIN1EeleTvaoQVggGSpwwYiY/fa1fMitb2ye qbsVdVWRtc8w9Yc8GI4Df6XqldCmnADFe5Tl0jBpZRo+c98ow7wuyKVF3uw2zdddEcs1 Kcfx1n6Yss1yvr/UceLSfx1pIIIcVAYn6sa4EhEfIppTZzkm+wmx3hPH8FQBa7ZuvbAF ypRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727765774; x=1728370574; 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=KGpcnT8eIFxBtjObmCg/DFSJtIGL8fTWQmZe4Er+eGM=; b=DbriRrI+Jxc+njcl1SyMon4A5/g1aIVDi01xRI0K+6h6Pur7xo3NkeYVfZAC8x9k7O j/tpFnvIafCnTsI5Vtk/TG5NRXlR+SmORAZF5iUvmZpHRJx6Oy4OYEDq7Ug9kMVSt/N5 X14LXqdKzPirZWvFOKy+tyw/M1jU3g5w98ga/6rYNjz0vw5HpUYL1RSaqMSDwIUs6Enj BaYBozjXGMTES6NF7JKpOC4NvEO7lbNXoziGieZzPvUsuukL+bMB55KtraUkGV+cJVfV 28s/8mSejt+kkszi6T1ClUGOTtRZukMEbILjzI1a8ciHXPwRVQZzSCQQBCDskgvk1JnF BJjA== X-Gm-Message-State: AOJu0YxlGiOPvfN8GG9phYF+ZARlZvnEteM9JZveRxKvGE6Avuf+V9o4 qj6UMhMSBbwkTZU9Lqs19ITe82BTd7U/3qrtPndEGm38obLbwJUDtElu0A== X-Received: by 2002:a05:6a20:b912:b0:1cf:1250:80a7 with SMTP id adf61e73a8af0-1d52d10a23cmr2957984637.12.1727765773529; Mon, 30 Sep 2024 23:56:13 -0700 (PDT) Received: from localhost ([112.64.8.17]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71b26538828sm7305893b3a.219.2024.09.30.23.56.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 23:56:13 -0700 (PDT) From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 1 Oct 2024 14:55:56 +0800 Message-Id: <20241001065558.56890-1-nuomi2021@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 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: 5c7Hci8HMwLd 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 | 2 +- 4 files changed, 296 insertions(+), 1 deletion(-) 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..db80d067ac --- /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* av_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 av_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 av_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..6083e41312 --- /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* av_executor_alloc(const AVTaskCallbacks *callbacks, int thread_count); + +/** + * Free executor + * @param e pointer to executor + */ +void av_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 av_executor_execute(AVExecutor *e, AVTask *t); + +#endif //AVCODEC_EXECUTOR_H diff --git a/libavcodec/vvc/thread.c b/libavcodec/vvc/thread.c index 86a7753c6a..a4d7b31c37 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" From patchwork Tue Oct 1 06:55:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 51953 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cb8a:0:b0:48e:c0f8:d0de with SMTP id d10csp62218vqv; Mon, 30 Sep 2024 23:56:38 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXY5DGtL4MX+I9yTBf+ImpexRYsK5oCX+IqSTjGEfiQe/mAqymNeIPlvb4lFKRX93EqJgI9ktJLMEWnNIvUGS4c@gmail.com X-Google-Smtp-Source: AGHT+IF0Nh43snKBjqhVSAawIdAEqPOcJNUW7t0NGBKsevBjbhsn2GrneGp+I56IfxIxGXw3lhYv X-Received: by 2002:a05:6402:90e:b0:5c7:18d3:633f with SMTP id 4fb4d7f45d1cf-5c8824d5ebbmr14369418a12.10.1727765798084; Mon, 30 Sep 2024 23:56:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727765798; cv=none; d=google.com; s=arc-20240605; b=BPHWiFi6JaRIMJzVrd4A/fubGx+OinSi9m1WftM5nmDWnGNos6fdQWPP1zi55zswr4 +5A2wu9dRzy8OjPhkKkQGbJ1Z02fIjDaht93AnbLamMYtaMQf9Co/UnWoWpmFTlUPPwv N4SwoyFw80Sjh/cuax6HUciph7BFPY7JmUVYXtRC1DcnSeGw5x7QAJ3iY877rvdVmkC3 lklWXWwVvF3Vnf/tDe1olcKdK8S2u2Ha5It+AnSZe6C7WjIfjYSUM0W1/JVUnY0s1rIC 7iAVdlVpHHjIGfgVsDmBj6bGRrC1hM8JGP89SQhSu0IwtRPKq8rJJXSAydy/ykYIivzy vRbw== 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=WO9t+rJhDYE/B+NpnxfXdEVqVU8cglrSiOEemWHNszg=; fh=mZk9AfRmPBMGW9h158yccPeJgZmEjzU2tMQtLZcF184=; b=gIdh6qEERB8ZEzVgyjtQJkvsZgXeUdxkMYjOFfVARLY/1sAS/eVZXacW0k/KRWOylb JsMODOMCBmfm3NWmAFgILL0dyOFHRBHYu2CUPL2tjBT4aGht4po/x38qbnnTTJ3FJz0d mPU4lPJMfP59Wn47Ix2UiyloaPM5r96h8hwfwYSHAPG7V8T9h+Nlv0vBB1Sed9I2hHhF s0g7lMctJOR0WNrUTb5QuE3UFk/3nXu20592151tSp0ZOhtbLq/Mxkf3SYb7JAC9tEXw tEHduLcRGRcKwEobr65/sgjiduWqu0Udh/aAr4dNsEvK8gyHC8NS3Jn0OQ8V5tHMdE8Q qYBQ==; 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=Hb8FgIjp; 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-5c8ad3697f6si191076a12.679.2024.09.30.23.56.37; Mon, 30 Sep 2024 23:56:38 -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=Hb8FgIjp; 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 A593468DA44; Tue, 1 Oct 2024 09:56:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2E08568DA33 for ; Tue, 1 Oct 2024 09:56:21 +0300 (EEST) Received: by mail-pg1-f178.google.com with SMTP id 41be03b00d2f7-7ae3d7222d4so4438288a12.3 for ; Mon, 30 Sep 2024 23:56:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727765779; x=1728370579; 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=oU5fCTqoepepKvz4f4SkUh9Oujh6kFl1jVpJ+kCA3lM=; b=Hb8FgIjpZnzXWSBL4XzIbgVNaanaiXaeOdHdKQvywH4JkSH87LzvfgY7LlMiEpcmmi 73P1OIfszgU27AY2DOiYSpq3D+gOHl4/BbdJqnLMpPn6cSrqQBX7GaMmJllSZ1JX6eUA reY20rlONTcakvRYwSulVNUs2dsWry0iUdOZoSjPrKVq1P9RQDy1AV1fDz6xgP167S5f /5XVel9HTa3icGY5HCyPZCGJW3m/B85mqEFVXArLm3iO1Cn6GEk5WXE+SfLZ4XM/sPCr j0CLEYyo1PUDUX30p/8WndgbJAKWgiSPVbuwkgXiRzhP1a/ps1MPZZwtjNGsg3fLaUiU EglQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727765779; x=1728370579; 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=oU5fCTqoepepKvz4f4SkUh9Oujh6kFl1jVpJ+kCA3lM=; b=DH6pC1ElMoSoK3TytT7D3u8sxms2BMTCbaA63/RsZ59LKoersAnNSSA0fQF2ffDdrV XpxfiV3VUKU17JtaOaE0kGoqN0iESfizKKpW+43GR+q3EPLJ5dGbBzKtfRD/EZoN8/Uo t/NRTZE1xc7Yj/ZHQvjncnh686fX1vfWjvgl4dE0FGC8QbMiT5zArjDB4vpz1Y7fOpNw A9dKCo20VHPGF0/23BgtBIoDXf/nU1HC61b3vqNNBnT6Sn9KkEiIdbFtd9RR3LcDvjJO ii66Wu1dDMBhKfP+uU+I6rroMC8+NTnFYu/a362oqhPG85RRu6PQVS1TGTY7wXTRCz3G bp7g== X-Gm-Message-State: AOJu0YwqGmEdXzBsRT65dUfYf2JX9pHl2OQjh65+FV8VARZIUprKnkFm q/q/hLfbmxOqZaAfzmtP5X6VzldDOX/z6qPlR8O4x1C2R5VIcM6RevQtmSrg X-Received: by 2002:a05:6a20:d489:b0:1cf:2b8c:b5e0 with SMTP id adf61e73a8af0-1d4fa78baffmr23678942637.37.1727765779341; Mon, 30 Sep 2024 23:56:19 -0700 (PDT) Received: from localhost ([112.64.8.17]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e12c26d5d5sm3628934a91.38.2024.09.30.23.56.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 23:56:19 -0700 (PDT) From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 1 Oct 2024 14:55:57 +0800 Message-Id: <20241001065558.56890-2-nuomi2021@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001065558.56890-1-nuomi2021@gmail.com> References: <20241001065558.56890-1-nuomi2021@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 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: j2iJyiSrKIUu 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 db80d067ac..84d52e7e3b 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* av_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 6083e41312..29fb55f66b 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 a4d7b31c37..993b682e1b 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 av_executor_alloc(&callbacks, thread_count); From patchwork Tue Oct 1 06:55:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 51954 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cb8a:0:b0:48e:c0f8:d0de with SMTP id d10csp83394vqv; Tue, 1 Oct 2024 00:46:35 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWRqmA4trBoNHOsTeQ685IrP+MxQgzQkYzqUR2TfupnrpLtBk2q4Cs+imkw290j+rsoO+Z/0tz0HaAHLW+36oOe@gmail.com X-Google-Smtp-Source: AGHT+IGfocHIcCOGIZgHBYDAn0nX+BHW+CXzWMj11qYXFzqlX0FVzpq+wiBnBYY478m1XkOky5Yv X-Received: by 2002:a2e:be1c:0:b0:2fa:cd3d:4a76 with SMTP id 38308e7fff4ca-2facd3d4c8fmr50379621fa.43.1727768795012; Tue, 01 Oct 2024 00:46:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727768794; cv=none; d=google.com; s=arc-20240605; b=N7bS3tol4UyklPU3Ww8+PVo39esYApfXZ9WBb4H1hd3UuCs8vbYVZXFZ7WFluhDJ3R CSi6JbhlUYwNhyVmJYGIs7nq3Z6kpCrLM6HaJard5O07NAjG9OVCaNPJJqsJ44LsOahh bN9gArq4IJD3mseFY1Bxttpyk/LXR8Wzy/qttIVWN8a5j0Y4pLLn/s9vrVdel6lW8Om+ BH0Q58Tx+yakeqg9V7jXzRMSviZkKIiAS9ISyIT0+ALbkb3f3UinQQMo5tsEWblsYiKP ChbegNzrifKqHDBo4NRQmgy/B6YpjCLazv07FMUMtIw7xPpC3QRdjUhA973FuX4Jz/B1 q1Ig== 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=xGiQziRh675FzZsjZqbV7l0bgOIyIDV7WqDrs1+kwew=; fh=mZk9AfRmPBMGW9h158yccPeJgZmEjzU2tMQtLZcF184=; b=HczI673rhQWvVAI1DXLyT8vamHCYf6pkOqz2VTVX9+pyT8BzyBDpXFnFUg+bfq9Nt8 9uZkuZMVPQA9vg/uYQ662wfxV5avfFZnkUKmkqXI3RTNyLkn2O4aGvDo7Xiq92KppLhz ywABNbjz5XyLwv69NaSkyDPfUqx+n7oSCnaCvP0qc3wz74TUV4oVeHUMLeIbYu0HGHl5 ff3HJEgTAI4SaJhRCo+bQrJChkkLlYgPnTThM85rSJL5ctBbI5fhUbLjVGuPvOm3KCoF Jf1JlwHzLGKbp6v1vyIpg137vDi4SbJYpXJlRNjoGMqlXv6MvXQ+Tk3Hvgm2hGIm/Kx6 B5qg==; 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=YLxH4Pix; 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-2fabeb5129asi23659261fa.59.2024.10.01.00.46.34; Tue, 01 Oct 2024 00:46:34 -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=YLxH4Pix; 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 200DA68DB05; Tue, 1 Oct 2024 09:56:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 36DD568DAAF for ; Tue, 1 Oct 2024 09:56:28 +0300 (EEST) Received: by mail-pf1-f177.google.com with SMTP id d2e1a72fcca58-71971d2099cso4180529b3a.2 for ; Mon, 30 Sep 2024 23:56:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727765786; x=1728370586; 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=UHwe/zxAR9aMG0muwQsKOdudIAU3yk8wmp5HFOGKIH4=; b=YLxH4PixDGweqcRY/mdcRL8y1cVm5kZdikUKWjufaUyfhc7bP3pV3cBaZdvuhjNhZU QwTT8Aw+GS8np5DbdDoEiEyRd2rt0HXkPkulz6x2L8TQ51Q92s9eEkmFoZB/jkkFVGu2 f3EQBxXZfxfBerkDY9+ZVgWTLN1e/+BUrN6/AQFHzGfCSF/hJOzTrj3h3Aa83JseHyvn AqxqkXfHysLqlnFDHE7Gdwl0JOZ+4PtEEedODmvRW5DN2O/ukT69TPulpgX16FN+JTGy Up7sq/pT6YS/tZBhRIHvvvn9AsI6N7LYvOo0JSIKMCFGWFNji8MNfxn01L4BQrlLHkEp eGKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727765786; x=1728370586; 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=UHwe/zxAR9aMG0muwQsKOdudIAU3yk8wmp5HFOGKIH4=; b=HoiKITM8vxTFXIou7YwO3+AH2fIhdTFgPXxNJ8WUXWKyyGLoKCJadHTALRrFUqrJOr Xb5QHSIeRvgL5IWZYaR2VWJvbC6R8bl480xQka9g2CJGmAECN74cAzwHDBDcMI64LdoH aAwCQzLLYm48xZd8NhIXKtl2oeaTjoKv2t4Q4Y2UjlnC6swa80bqYxLbvO+Tcd76rta8 YUQOVwASxkFmnxQa0uWwdGjuYmGw5XE0MxLMtAf/7v+XRZhzUJT9NHPzD9PglLjFnMY2 5C2/qg0P1Uex3Q95nyEozXq+RUb0WJsl7hbiemWuBlagfkIj5DnUGQysb5/eZdtPSL3w 6PFQ== X-Gm-Message-State: AOJu0Yw0WuU+lpvFtx+P0kPTcytPIyXBHHZBaJlayGpO4uyvCxtaTAoA HicfFzqxvYNWTjOaTHihuO58n3y2MnphxPXRIzuFVpjErmfajOmI4hfrxFuk X-Received: by 2002:a05:6a00:3c8e:b0:717:8d52:643 with SMTP id d2e1a72fcca58-71b25f39a5amr22072093b3a.11.1727765785934; Mon, 30 Sep 2024 23:56:25 -0700 (PDT) Received: from localhost ([112.64.8.17]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71b26516098sm7327723b3a.121.2024.09.30.23.56.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 23:56:25 -0700 (PDT) From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 1 Oct 2024 14:55:58 +0800 Message-Id: <20241001065558.56890-3-nuomi2021@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001065558.56890-1-nuomi2021@gmail.com> References: <20241001065558.56890-1-nuomi2021@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 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: l7dvAvot5Nla 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 | 54 ++++++++++++++++++++++++++--------------- libavcodec/executor.h | 5 ++-- libavcodec/vvc/thread.c | 48 +++++++++++++++--------------------- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/libavcodec/executor.c b/libavcodec/executor.c index 84d52e7e3b..362e961c4f 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,41 @@ 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->next = t; + q->tail = t; + } } static int run_one_task(AVExecutor *e, void *lc) { AVTaskCallbacks *cb = &e->cb; - AVTask **prev = &e->tasks; + AVTask *t = NULL; - if (*prev) { - AVTask *t = remove_task(prev, *prev); + for (int i = 0; i < e->cb.priorities && !t; i++) + t = remove_task(e->q + i); + + if (t) { if (e->thread_count > 0) ff_mutex_unlock(&e->lock); cb->run(t, lc, cb->user_data); @@ -132,6 +149,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 +159,7 @@ AVExecutor* av_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 +171,10 @@ AVExecutor* av_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 +214,10 @@ void av_executor_free(AVExecutor **executor) void av_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 29fb55f66b..2398acd56c 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 993b682e1b..1736092abe 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); - - av_executor_execute(s->executor, &t->u.task); + task->priority = priorities[t->stage]; + av_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 av_executor_alloc(&callbacks, thread_count);