From patchwork Fri Jun 16 09:29:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 42133 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c526:b0:117:ac03:c9de with SMTP id gm38csp1390636pzb; Fri, 16 Jun 2023 02:30:43 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7IuRnyzREh4g0uYEk5BOWV+zvEnYjOi+cfMOaZvbJh+0HKg29KXNhITmB31L8XWbWEasul X-Received: by 2002:a17:907:97cb:b0:979:7624:1f71 with SMTP id js11-20020a17090797cb00b0097976241f71mr1417585ejc.26.1686907842862; Fri, 16 Jun 2023 02:30:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686907842; cv=none; d=google.com; s=arc-20160816; b=WWKwvHJWzxO4jaW4AdMNtZcMNp22RIyt6626YqfEBs3jIODGbGGn5X6ZH9CaZwVPGc Y4XRuSqRGO7jmuOr2880r6zI8wjASGJ2eDUoEmixp5kpBb5/HtHiuZ4zLRvPILAPAI6a v1aEnWPr5fmplUsEpZ3JRB/mrljYYU1WHdP7LUWncqkjn6ZoYUFYcM+tes5f+QufU1UK SQOkgKPWSkUJq28UF3Zi2xbAOVeOtEbq4aVbSqkgoIPEhM9VS5AUMJ0ppxWy0cwdzWdG EXJl3PRDtMp2sa7YX9zwJFNenrM7+BgPgAP2vAcStQhtIB7OFDNICvVXHzZe0u5iCqo8 gNmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; 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=y1VlNYKng2Ofv476157X2oQ9N2vhUNGhR19Qerskx3g=; b=dSKtSVb1SLypnAjnlrYM9ygePcVcX1nLvy7vLzyu+Ug1zg1BWwQr2TW+yCaHUFu0f3 6YbOmQ6WoJH1nrtM/AR2gu4Y/izoaUKgBD1DBvf1/Itv/t7X8u7u5GQRerGD6rraiRCn HdndaBu0c4AIIPsCd+eX3zDk5VEu9DUTRrrHefJL0Nmg3bDmgRPss0YNjzeFdkLd2dGs 4klKaVM9EWmy5xHnBAf5ZyLx7GEqi8maeRPKkcPtCkY3vCrTK4/dKjyE/mzUabHV3GD0 x9ByomFqzwaj7IGRM9GGg8vMZdXxzEnV4irj59iQEiyf//VtY5lZQL8zPRowOCLJE5wL M7/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=YBTSl5mP; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gf5-20020a170906e20500b00977c9989f33si10311463ejb.858.2023.06.16.02.30.42; Fri, 16 Jun 2023 02:30:42 -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=@haasn.xyz header.s=mail header.b=YBTSl5mP; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0C6D868C597; Fri, 16 Jun 2023 12:30:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from haasn.dev (haasn.dev [78.46.187.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D1C5A68C500 for ; Fri, 16 Jun 2023 12:30:20 +0300 (EEST) Received: from localhost (217-74-0-168.hsi.r-kom.net [217.74.0.168]) by haasn.dev (Postfix) with ESMTPSA id 870BE41B2C; Fri, 16 Jun 2023 11:30:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1686907820; bh=NZkdY9HQh/6ffmv2Q8E72w8z4j4LhcDeENFR8rSQhHo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YBTSl5mPFm/CVBJxP6mqDUZ9BkeehN/MqFbk/0J4SVpkBKnqyHmI0BkfURAQcsGjn aX4VgLN4lDa528RwmVYrOyWXzoGL8UwU4K+dn20vq8JUDD/RW+Jn0UMVwn+oItLQ3j 4rKCFLaDxlEFiVnLG2ffcJsk+OoUIa8KgD01r+gE= From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Fri, 16 Jun 2023 11:29:39 +0200 Message-ID: <20230616092959.5247-2-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230616092959.5247-1-ffmpeg@haasn.xyz> References: <20230616092959.5247-1-ffmpeg@haasn.xyz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 02/22] lavfi/vf_libplacebo: move input-specific state to struct 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: Niklas Haas Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: UhBct09anYLZ From: Niklas Haas In anticipation of a refactor which will enable multiple input support. Note: the renderer is also input-specific because it maintains a frame cache, HDR peak detection state and mixing cache, all of which are tied to a specific input stream. --- libavfilter/vf_libplacebo.c | 80 ++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c index a048424cec..10fd432745 100644 --- a/libavfilter/vf_libplacebo.c +++ b/libavfilter/vf_libplacebo.c @@ -113,6 +113,16 @@ enum var_name { VAR_VARS_NB }; +/* per-input dynamic filter state */ +typedef struct LibplaceboInput { + pl_renderer renderer; + pl_queue queue; + AVFilterLink *link; + AVFifo *out_pts; ///< timestamps of wanted output frames + int64_t status_pts; + int status; +} LibplaceboInput; + typedef struct LibplaceboContext { /* lavfi vulkan*/ FFVulkanContext vkctx; @@ -121,14 +131,10 @@ typedef struct LibplaceboContext { pl_log log; pl_vulkan vulkan; pl_gpu gpu; - pl_renderer renderer; - pl_queue queue; pl_tex tex[4]; - /* filter state */ - AVFifo *out_pts; ///< timestamps of wanted output frames - int64_t status_pts; - int status; + /* input state */ + LibplaceboInput input; /* settings */ char *out_format_string; @@ -536,8 +542,6 @@ static int libplacebo_init(AVFilterContext *avctx) RET(av_expr_parse(&s->pos_h_pexpr, s->pos_h_expr, var_names, NULL, NULL, NULL, NULL, 0, s)); - /* Initialize dynamic filter state */ - s->out_pts = av_fifo_alloc2(1, sizeof(int64_t), AV_FIFO_FLAG_AUTO_GROW); if (strcmp(s->fps_string, "none") != 0) RET(av_parse_video_rate(&s->fps, s->fps_string)); @@ -564,6 +568,28 @@ static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx) } #endif +static int input_init(AVFilterContext *avctx, AVFilterLink *link, + LibplaceboInput *input) +{ + LibplaceboContext *s = avctx->priv; + + input->out_pts = av_fifo_alloc2(1, sizeof(int64_t), AV_FIFO_FLAG_AUTO_GROW); + if (!input->out_pts) + return AVERROR(ENOMEM); + input->queue = pl_queue_create(s->gpu); + input->renderer = pl_renderer_create(s->log, s->gpu); + input->link = link; + + return 0; +} + +static void input_uninit(LibplaceboInput *input) +{ + pl_renderer_destroy(&input->renderer); + pl_queue_destroy(&input->queue); + av_fifo_freep2(&input->out_pts); +} + static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx) { int err = 0; @@ -620,10 +646,7 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct goto fail; } - /* Create the renderer */ s->gpu = s->vulkan->gpu; - s->renderer = pl_renderer_create(s->log, s->gpu); - s->queue = pl_queue_create(s->gpu); /* Parse the user shaders, if requested */ if (s->shader_bin_len) @@ -634,6 +657,9 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct RET(parse_shader(avctx, buf, buf_len)); } + /* Initialize inputs */ + RET(input_init(avctx, avctx->inputs[0], &s->input)); + /* fall through */ fail: if (buf) @@ -649,8 +675,7 @@ static void libplacebo_uninit(AVFilterContext *avctx) pl_tex_destroy(s->gpu, &s->tex[i]); for (int i = 0; i < s->num_hooks; i++) pl_mpv_user_shader_destroy(&s->hooks[i]); - pl_renderer_destroy(&s->renderer); - pl_queue_destroy(&s->queue); + input_uninit(&s->input); pl_vulkan_destroy(&s->vulkan); pl_log_destroy(&s->log); ff_vk_uninit(&s->vkctx); @@ -664,7 +689,6 @@ static void libplacebo_uninit(AVFilterContext *avctx) av_expr_free(s->pos_y_pexpr); av_expr_free(s->pos_w_pexpr); av_expr_free(s->pos_h_pexpr); - av_fifo_freep2(&s->out_pts); } static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd, @@ -826,7 +850,7 @@ static int output_frame_mix(AVFilterContext *ctx, } update_crops(ctx, mix, &target, ref_sig, out->pts * av_q2d(outlink->time_base)); - pl_render_image_mix(s->renderer, mix, &target, &s->params); + pl_render_image_mix(s->input.renderer, mix, &target, &s->params); if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) { pl_unmap_avframe(s->gpu, &target); @@ -886,7 +910,7 @@ static int libplacebo_activate(AVFilterContext *ctx) while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) { in->opaque = s; - pl_queue_push(s->queue, &(struct pl_source_frame) { + pl_queue_push(s->input.queue, &(struct pl_source_frame) { .pts = in->pts * av_q2d(inlink->time_base), .duration = in->duration * av_q2d(inlink->time_base), .first_field = pl_field_from_avframe(in), @@ -899,19 +923,19 @@ static int libplacebo_activate(AVFilterContext *ctx) if (!s->fps.num) { /* Internally queue an output frame for the same PTS */ av_assert1(!av_cmp_q(inlink->time_base, outlink->time_base)); - av_fifo_write(s->out_pts, &in->pts, 1); + av_fifo_write(s->input.out_pts, &in->pts, 1); } } if (ret < 0) return ret; - if (!s->status && ff_inlink_acknowledge_status(inlink, &status, &pts)) { + if (!s->input.status && ff_inlink_acknowledge_status(inlink, &status, &pts)) { pts = av_rescale_q_rnd(pts, inlink->time_base, outlink->time_base, AV_ROUND_UP); - pl_queue_push(s->queue, NULL); /* Signal EOF to pl_queue */ - s->status = status; - s->status_pts = pts; + pl_queue_push(s->input.queue, NULL); /* Signal EOF to pl_queue */ + s->input.status = status; + s->input.status_pts = pts; } if (ff_outlink_frame_wanted(outlink)) { @@ -920,22 +944,22 @@ static int libplacebo_activate(AVFilterContext *ctx) if (s->fps.num) { pts = outlink->frame_count_out; - } else if (av_fifo_peek(s->out_pts, &pts, 1, 0) < 0) { + } else if (av_fifo_peek(s->input.out_pts, &pts, 1, 0) < 0) { /* No frames queued */ - if (s->status) { - pts = s->status_pts; + if (s->input.status) { + pts = s->input.status_pts; } else { ff_inlink_request_frame(inlink); return 0; } } - if (s->status && pts >= s->status_pts) { - ff_outlink_set_status(outlink, s->status, s->status_pts); + if (s->input.status && pts >= s->input.status_pts) { + ff_outlink_set_status(outlink, s->input.status, s->input.status_pts); return 0; } - ret = pl_queue_update(s->queue, &mix, pl_queue_params( + ret = pl_queue_update(s->input.queue, &mix, pl_queue_params( .pts = pts * av_q2d(outlink->time_base), .radius = pl_frame_mix_radius(&s->params), .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)), @@ -947,7 +971,7 @@ static int libplacebo_activate(AVFilterContext *ctx) return 0; case PL_QUEUE_OK: if (!s->fps.num) - av_fifo_drain2(s->out_pts, 1); + av_fifo_drain2(s->input.out_pts, 1); return output_frame_mix(ctx, &mix, pts); case PL_QUEUE_ERR: return AVERROR_EXTERNAL;