Patch attached
>From 06985c12d8280f1d953a60b6e56b40d85debd849 Mon Sep 17 00:00:00 2001 From: Lynne <d...@lynne.ee> 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
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".