* [FFmpeg-devel] [PATCH] lavfi: add noise_vulkan filter
@ 2023-05-29 19:14 Lynne
0 siblings, 0 replies; only message in thread
From: Lynne @ 2023-05-29 19:14 UTC (permalink / raw)
To: Ffmpeg Devel
[-- Attachment #1: Type: text/plain, Size: 16 bytes --]
Patch attached
[-- Attachment #2: 0001-lavfi-add-noise_vulkan-filter.patch --]
[-- Type: text/x-diff, Size: 11521 bytes --]
From 06985c12d8280f1d953a60b6e56b40d85debd849 Mon Sep 17 00:00:00 2001
From: Lynne <dev@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
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-05-29 19:14 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-29 19:14 [FFmpeg-devel] [PATCH] lavfi: add noise_vulkan filter Lynne
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git