From patchwork Mon May 29 19:14:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lynne X-Patchwork-Id: 41883 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c51c:b0:10c:5e6f:955f with SMTP id gm28csp1959533pzb; Mon, 29 May 2023 12:14:38 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5DofVr4cNZ6qEz3fo7aqjALGpqw8L2R0Qhs5UzJECh7IIUlQrtAyRiXx3QtFxP/IHkVM9M X-Received: by 2002:a17:907:6d82:b0:966:2123:e0c3 with SMTP id sb2-20020a1709076d8200b009662123e0c3mr176157ejc.15.1685387677602; Mon, 29 May 2023 12:14:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685387677; cv=none; d=google.com; s=arc-20160816; b=r4Cp7ns76pOtcdIgUj7ZxnlIcBFqJx0Ld42PRjVnQu60k2QsJxzdP4nK4xsGPvD5sR 5puj+3B4E+Vdr+pWeR4vsxH9tP/Lbue6ckc/figiwsXLP2NfKNoJYs4tfKm3xUza4tww TA9wc56pl2J3VhumCuN9M4MzUJlGNbKvhvs2HfmSOFX1TjrHaVnuqTIQCNml1Pp5AmbS cxfAVDjYpv3IYZD2Ur0CMspsmapjQOFY/sx+aPpyotXmcHNUmAkp42+e1WFBQ2xkFKTO LJ1GRtDrOVubVm+Crzo7mIugzr8jOkEEOO4J8I2OHTuHbkVciBTaX5XMJ+hPzuKNI7SJ Z7DQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:to:from:date:dkim-signature:delivered-to; bh=7CmBSeY+Saf8pLvRDFDqDdT+GwFeDlYIN2cS9JBlotk=; b=dN7TWmz+S9NBpAtQNQ2UfEZBXFcp9UAmg20gk2tIVgrTYsiW5kjcIEhIQLZqXHkzV0 hcpkDTnuvbz9pqqvj55t/ciuAF2eOLtQK4t8KB8ndetstGqCPIpZr4mcZY/SYs71JU0C A/+pEB1FfUE34K8XEzkION130SmQjBpJ5qOEMRv4mYqs/6ZG7+mlFjLsQbPCfeCd+hFD fmfubc1sbiNbbZPpYyMhVwk8IVUQvnsfsEAXpztjEVBxblKJn4wQqnzmhAJ0Wxj0TGzB 7uqGenPfmh7idiG+rsNdtgZd+TG1eYMgm++/ZO9YFT9Yl99osOeoiEHJkNy0ZGL3lSp5 VC6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@lynne.ee header.s=s1 header.b=s8aAmaU9; 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=NONE dis=NONE) header.from=lynne.ee Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id iy21-20020a170907819500b0096f4c6a68easi4713936ejc.1041.2023.05.29.12.14.36; Mon, 29 May 2023 12:14:37 -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=@lynne.ee header.s=s1 header.b=s8aAmaU9; 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=NONE dis=NONE) header.from=lynne.ee Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7D3A768C1C3; Mon, 29 May 2023 22:14:32 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from w4.tutanota.de (w4.tutanota.de [81.3.6.165]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3865268022D for ; Mon, 29 May 2023 22:14:25 +0300 (EEST) Received: from tutadb.w10.tutanota.de (unknown [192.168.1.10]) by w4.tutanota.de (Postfix) with ESMTP id 0A607106026C for ; Mon, 29 May 2023 19:14:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1685387664; s=s1; d=lynne.ee; h=From:From:To:To:Subject:Subject:Content-Description:Content-ID:Content-Type:Content-Type:Content-Transfer-Encoding:Cc:Date:Date:In-Reply-To:MIME-Version:MIME-Version:Message-ID:Message-ID:Reply-To:References:Sender; bh=pf54G/6JvcemGzPd/BFJhWcaeh4xyy+w0kijwLIAr3A=; b=s8aAmaU9puTLShNRD9VTDUFTyd084lNN4LOB4KsReS7Ijg+nPLtl2jpC5poD1BS+ ZSTZd8cqStge7aGcVIGGwhPNIlaWJ8DjZsfIldKuJDwT/Sdg9s061/Atrt8hGjjAXhp FeTB0IjOlUCWv0winhGue8sJllADiuTLSVo66iu6ZBIDRGr+shDZ3zqqJxK1HBgbkY4 Xk1ijg4tQpCuwu2aM7qwpiB6/wI8r4o8etP2lGhRxnNaDeGt2c7eixtry74VOlZbo0H HQrNl/Bqscb0G/qmHi4FPlRkKAoalz4y4eEKfLsX22W/WL4VFyB1xDnlvtg0yFoFlrJ yS8Uo3YRmQ== Date: Mon, 29 May 2023 21:14:24 +0200 (CEST) From: Lynne To: Ffmpeg Devel Message-ID: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] lavfi: add noise_vulkan filter 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: FAidUTlwUK99 Patch attached From 06985c12d8280f1d953a60b6e56b40d85debd849 Mon Sep 17 00:00:00 2001 From: Lynne Date: Mon, 29 May 2023 20:47:46 +0200 Subject: [PATCH] lavfi: add noise_vulkan filter --- configure | 1 + doc/filters.texi | 43 ++++++++++++++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vsrc_testsrc_vulkan.c | 85 +++++++++++++++++++++++++++++-- 5 files changed, 126 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 495493aa0e..a4cc214e76 100755 --- a/configure +++ b/configure @@ -3707,6 +3707,7 @@ negate_filter_deps="lut_filter" nlmeans_opencl_filter_deps="opencl" nlmeans_vulkan_filter_deps="vulkan spirv_compiler" nnedi_filter_deps="gpl" +noise_vulkan_filter_deps="vulkan spirv_compiler" ocr_filter_deps="libtesseract" ocv_filter_deps="libopencv" openclsrc_filter_deps="opencl" diff --git a/doc/filters.texi b/doc/filters.texi index c47e88e5d4..1f2828e450 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -27469,6 +27469,49 @@ Must be odd number in range [0, 99]. @end table +@section noise_vulkan + +Video source that creates a Vulkan frame containing TV static/white noise. +Useful for benchmarking, or overlaying. + +It accepts the following parameters: + +@table @option +@item size +The size of the output frame. Default value is @code{1920x1080}. + +@item rate +The framerate to output at. Default value is @code{60} frames per second. + +@item duration +The video duration. Default value is @code{-0.000001}. + +@item sar +The video signal aspect ratio. Default value is @code{1/1}. + +@item format +The pixel format of the output Vulkan frames. Default value is @code{yuv444p}. + +@item out_range +Set the output YCbCr sample range. + +This allows the autodetected value to be overridden as well as allows forcing +a specific value used for the output and encoder. If not specified, the +range depends on the pixel format. Possible values: + +@table @samp +@item auto/unknown +Choose automatically. + +@item jpeg/full/pc +Set full range (0-255 in case of 8-bit luma). + +@item mpeg/limited/tv +Set "MPEG" range (16-235 in case of 8-bit luma). +@end table + +@end table + @section overlay_vulkan Overlay one video on top of another. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 18935b1616..ff059cfab4 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -395,6 +395,7 @@ OBJS-$(CONFIG_NLMEANS_VULKAN_FILTER) += vf_nlmeans_vulkan.o vulkan.o vul OBJS-$(CONFIG_NNEDI_FILTER) += vf_nnedi.o OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NOISE_FILTER) += vf_noise.o +OBJS-$(CONFIG_NOISE_VULKAN_FILTER) += vsrc_testsrc_vulkan.o vulkan.o vulkan_filter.o OBJS-$(CONFIG_NORMALIZE_FILTER) += vf_normalize.o OBJS-$(CONFIG_NULL_FILTER) += vf_null.o OBJS-$(CONFIG_OCR_FILTER) += vf_ocr.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index f1f781101b..22f59e3ecf 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -550,6 +550,7 @@ extern const AVFilter ff_vsrc_haldclutsrc; extern const AVFilter ff_vsrc_life; extern const AVFilter ff_vsrc_mandelbrot; extern const AVFilter ff_vsrc_mptestsrc; +extern const AVFilter ff_vsrc_noise_vulkan; extern const AVFilter ff_vsrc_nullsrc; extern const AVFilter ff_vsrc_openclsrc; extern const AVFilter ff_vsrc_pal75bars; diff --git a/libavfilter/vsrc_testsrc_vulkan.c b/libavfilter/vsrc_testsrc_vulkan.c index 7eacb57c80..12ac556fff 100644 --- a/libavfilter/vsrc_testsrc_vulkan.c +++ b/libavfilter/vsrc_testsrc_vulkan.c @@ -29,10 +29,12 @@ enum TestSrcVulkanMode { TESTSRC_COLOR, + TESTSRC_NOISE, }; typedef struct TestSrcVulkanPushData { float color_comp[4]; + uint32_t frame_nb; } TestSrcVulkanPushData; typedef struct TestSrcVulkanContext { @@ -63,6 +65,23 @@ typedef struct TestSrcVulkanContext { AVFrame *picref; ///< cached reference containing the painted picture } TestSrcVulkanContext; +static const char noise_fn[] = { + C(0, vec4 noise_fn(inout uvec4 s) ) + C(0, { ) + C(1, s = 1664525u * s + uvec4(1013904223u); ) + C(1, s.x += s.y * s.w; ) + C(1, s.y += s.z * s.x; ) + C(1, s.z += s.x * s.y; ) + C(1, s.w += s.y * s.z; ) + C(1, s ^= s >> 16u; ) + C(1, s.x += s.y * s.w; ) + C(1, s.y += s.z * s.x; ) + C(1, s.z += s.x * s.y; ) + C(1, s.w += s.y * s.z; ) + C(1, return vec4(s) * 1.0/float(0xFFFFFFFFu); ) + C(0, } ) +}; + static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode) { int err; @@ -92,6 +111,7 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, vec4 color_comp; ); + GLSLC(1, uvec4 frame_nb; ); GLSLC(0, }; ); GLSLC(0, ); @@ -112,9 +132,6 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc_set, 1, 0, 0)); - GLSLC(0, void main() ); - GLSLC(0, { ); - GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); if (mode == TESTSRC_COLOR) { double rgb2yuv[3][3]; double rgbad[4]; @@ -164,6 +181,9 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode for (int i = 0; i < 4; i++) s->opts.color_comp[i] = yuvad[i]; + GLSLC(0, void main() ); + GLSLC(0, { ); + GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); GLSLC(1, vec4 r; ); GLSLC(0, ); for (int i = 0, c_off = 0; i < planes; i++) { @@ -176,8 +196,27 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode GLSLF(1, imageStore(output_img[%i], pos, r); ,i); GLSLC(0, ); } + } else if (mode == TESTSRC_NOISE) { + GLSLD( noise_fn ); + GLSLC(0, void main() ); + GLSLC(0, { ); + GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); + GLSLC(1, uvec4 s = uvec4(pos.x, pos.y, pos.x ^ pos.y, pos.x + pos.y) + uvec4(frame_nb); ); + GLSLC(1, vec4 r; ); + GLSLC(0, ); + for (int i = 0; i < planes; i++) { + GLSLC(1, r = noise_fn(s); ); + if (!(desc->flags & AV_PIX_FMT_FLAG_RGB)) { + int chroma = (i > 0) && (i != 3); + if (s->out_range == AVCOL_RANGE_MPEG) { + GLSLF(1, r *= (%i) / 255.0; ,chroma ? 224 : 219); + GLSLF(1, r += (%i) / 255.0; ,chroma ? 16 : 18); + } + } + GLSLF(1, imageStore(output_img[%i], pos, r); ,i); + } } - GLSLC(0, } ); + GLSLC(0, } ); RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); @@ -207,12 +246,19 @@ static int testsrc_vulkan_activate(AVFilterContext *ctx) AVFrame *frame; if (!s->initialized) { - enum TestSrcVulkanMode mode = TESTSRC_COLOR; + enum TestSrcVulkanMode mode; + if (!strcmp(ctx->filter->name, "color_vulkan")) + mode = TESTSRC_COLOR; + else if (!strcmp(ctx->filter->name, "noise_vulkan")) + mode = TESTSRC_NOISE; + err = init_filter(ctx, mode); if (err < 0) return err; } + s->opts.frame_nb = s->nb_frame; + if (!ff_outlink_frame_wanted(outlink)) return FFERROR_NOT_READY; if (s->duration >= 0 && @@ -375,3 +421,32 @@ const AVFilter ff_vsrc_color_vulkan = { .priv_class = &color_vulkan_class, .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; + +static const AVOption noise_vulkan_options[] = { + COMMON_OPTS + { "out_range", "Output colour range (from 0 to 2) (default 0)", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED}, AVCOL_RANGE_UNSPECIFIED, AVCOL_RANGE_JPEG, .flags = FLAGS, "range" }, + { "full", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, + { "limited", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, + { "jpeg", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, + { "mpeg", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, + { "tv", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, + { "pc", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, + { NULL }, +}; + +AVFILTER_DEFINE_CLASS(noise_vulkan); + +const AVFilter ff_vsrc_noise_vulkan = { + .name = "noise_vulkan", + .description = NULL_IF_CONFIG_SMALL("Generate video noise (Vulkan)"), + .priv_size = sizeof(TestSrcVulkanContext), + .init = &ff_vk_filter_init, + .uninit = &testsrc_vulkan_uninit, + .inputs = NULL, + .flags = AVFILTER_FLAG_HWDEVICE, + .activate = testsrc_vulkan_activate, + FILTER_OUTPUTS(testsrc_vulkan_outputs), + FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VULKAN), + .priv_class = &noise_vulkan_class, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, +}; -- 2.40.1