From patchwork Tue Mar 23 12:35:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26557 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 70CC6449E98 for ; Tue, 23 Mar 2021 14:36:17 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4677A68AAEB; Tue, 23 Mar 2021 14:36:17 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D8CF268AAD5 for ; Tue, 23 Mar 2021 14:36:10 +0200 (EET) Received: by mail-ed1-f46.google.com with SMTP id y6so23277470eds.1 for ; Tue, 23 Mar 2021 05:36:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:reply-to:mime-version :content-transfer-encoding; bh=Qwi0dfU71vtXrRS7uMxj4Ku4iFOYjGFs/naWmdKFjMs=; b=tlTCBQwDDPHMyJZ1EAwwrgt0xMS6z87JK6c/rjMlHPpzYOCNQE5jSvSEJlw1+cWLPk i910jNel0iR9h7hQrsiiwprY4cD9P0aZOjZNo98zZ1MJ3jX3IYYpI+4ISSxvCcw6UQKK 1BjFUGKc6QUGKxR0fqJhBWzW/VdDNgNAUEhp5rMpjmyPhQCJVPjYikElJdbMh0PlZLhO FGKfp0Hc3Zws/0Y/GQrkN765e7tWgT4kfnUyy7GdW1C0XXCvWMhGSE2gJUT8DRlAkHdV uipKFwcQVUrF5DzmGXkL7h85vA+iscNadyyTNF03hJhxpitq9gdrAn6vzbW/iRhzt1Ek Vu2Q== 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:reply-to :mime-version:content-transfer-encoding; bh=Qwi0dfU71vtXrRS7uMxj4Ku4iFOYjGFs/naWmdKFjMs=; b=DQByPmGbq7AwaF8+2TkcRq7Vhtu9/5nDOtdQsk49zur3aDk1036cvuHjDrB4Avcz/Z /mHm2VCSXx8YqNuFbxwWfdHN65BoywUN6duAbnbi/JD/TDBwE3CcW2F8GUxYKLQdrEfN NfPKaz5B9IveFCasY21+5fyG6nI+t941hRw/WE0qA7rgyKgYjlRDzM86MZtRsxPUl0kX als2JdE5o6MvbJZs6g/iDNmfvxjf5kPSkuR0bwWux0RkUBgvuNmhsumebk61/uyM2TTX ONdkDasK6XaU3kv6VCwhr5+QvVxRbIbtEYEIy5sgDTCQhGH0Jqm2zHJJSEshg6Z/PeTQ Cwfw== X-Gm-Message-State: AOAM531wExDXeFn7GqOub/jYNsWXeMLEJ0LA4aSPfwaMdsNZiul/3cwf OgggEXVAuqtVbsKPzJcWX3e6w/VKxcwhqA== X-Google-Smtp-Source: ABdhPJxYrUFW/ec5rbd7tjAI/Owom64oHcznd+/G36F+KcIWZGiREGnsm5UWzw2dvGdbKLwPGJh/Hg== X-Received: by 2002:a50:fe06:: with SMTP id f6mr4385012edt.349.1616502969864; Tue, 23 Mar 2021 05:36:09 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc08960.dynamic.kabel-deutschland.de. [188.192.137.96]) by smtp.gmail.com with ESMTPSA id mp36sm10728532ejc.48.2021.03.23.05.36.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Mar 2021 05:36:07 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 23 Mar 2021 13:35:51 +0100 Message-Id: <20210323123554.1370260-1-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/4] avcodec/pthread_frame: Factor initializing single thread out 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" Signed-off-by: Andreas Rheinhardt --- libavcodec/pthread_frame.c | 127 ++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 7bcb9a7bcc..311d6ed771 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -763,52 +763,12 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) avctx->codec = NULL; } -int ff_frame_thread_init(AVCodecContext *avctx) +static av_cold int init_thread(PerThreadContext *p, + FrameThreadContext *fctx, AVCodecContext *avctx, + AVCodecContext *src, const AVCodec *codec, int first) { - int thread_count = avctx->thread_count; - const AVCodec *codec = avctx->codec; - AVCodecContext *src = avctx; - FrameThreadContext *fctx; - int i, err = 0; - - if (!thread_count) { - int nb_cpus = av_cpu_count(); - // use number of cores + 1 as thread count if there is more than one - if (nb_cpus > 1) - thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); - else - thread_count = avctx->thread_count = 1; - } - - if (thread_count <= 1) { - avctx->active_thread_type = 0; - return 0; - } - - avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); - if (!fctx) - return AVERROR(ENOMEM); - - fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); - if (!fctx->threads) { - av_freep(&avctx->internal->thread_ctx); - return AVERROR(ENOMEM); - } - - pthread_mutex_init(&fctx->buffer_mutex, NULL); - pthread_mutex_init(&fctx->hwaccel_mutex, NULL); - pthread_mutex_init(&fctx->async_mutex, NULL); - pthread_cond_init(&fctx->async_cond, NULL); - - fctx->async_lock = 1; - fctx->delaying = 1; - - if (codec->type == AVMEDIA_TYPE_VIDEO) - avctx->delay = src->thread_count - 1; - - for (i = 0; i < thread_count; i++) { AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); - PerThreadContext *p = &fctx->threads[i]; + int err; pthread_mutex_init(&p->mutex, NULL); pthread_mutex_init(&p->progress_mutex, NULL); @@ -819,22 +779,19 @@ int ff_frame_thread_init(AVCodecContext *avctx) p->frame = av_frame_alloc(); if (!p->frame) { av_freep(©); - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } p->avpkt = av_packet_alloc(); if (!p->avpkt) { av_freep(©); - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } p->parent = fctx; p->avctx = copy; if (!copy) { - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } *copy = *src; @@ -842,8 +799,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) copy->internal = av_malloc(sizeof(AVCodecInternal)); if (!copy->internal) { copy->priv_data = NULL; - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } *copy->internal = *src->internal; copy->internal->thread_ctx = p; @@ -854,27 +810,27 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (codec->priv_data_size) { copy->priv_data = av_mallocz(codec->priv_data_size); if (!copy->priv_data) { - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } if (codec->priv_class) { *(const AVClass **)copy->priv_data = codec->priv_class; err = av_opt_copy(copy->priv_data, src->priv_data); if (err < 0) - goto error; + return err; } } - if (i) + if (!first) copy->internal->is_copy = 1; if (codec->init) err = codec->init(copy); + if (err < 0) { + return err; + } - if (err) goto error; - - if (!i) + if (first) update_context_from_thread(avctx, copy, 1); atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); @@ -882,6 +838,59 @@ int ff_frame_thread_init(AVCodecContext *avctx) err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); p->thread_init= !err; if(!p->thread_init) + return err; + return 0; +} + +int ff_frame_thread_init(AVCodecContext *avctx) +{ + int thread_count = avctx->thread_count; + const AVCodec *codec = avctx->codec; + AVCodecContext *src = avctx; + FrameThreadContext *fctx; + int i, err = 0; + + if (!thread_count) { + int nb_cpus = av_cpu_count(); + // use number of cores + 1 as thread count if there is more than one + if (nb_cpus > 1) + thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); + else + thread_count = avctx->thread_count = 1; + } + + if (thread_count <= 1) { + avctx->active_thread_type = 0; + return 0; + } + + avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); + if (!fctx) + return AVERROR(ENOMEM); + + fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); + if (!fctx->threads) { + av_freep(&avctx->internal->thread_ctx); + return AVERROR(ENOMEM); + } + + pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_cond_init(&fctx->async_cond, NULL); + + fctx->async_lock = 1; + fctx->delaying = 1; + + if (codec->type == AVMEDIA_TYPE_VIDEO) + avctx->delay = src->thread_count - 1; + + for (i = 0; i < thread_count; i++) { + PerThreadContext *p = &fctx->threads[i]; + int first = !i; + + err = init_thread(p, fctx, avctx, src, codec, first); + if (err < 0) goto error; }