FFmpeg
Loading...
Searching...
No Matches
vf_avgblur_vulkan.c
Go to the documentation of this file.
1/*
2 * Copyright (c) Lynne
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
22#include "libavutil/opt.h"
23#include "libavutil/pixdesc.h"
24#include "vulkan_filter.h"
25
26#include "filters.h"
27#include "video.h"
28
29extern const unsigned char ff_avgblur_comp_spv_data[];
30extern const unsigned int ff_avgblur_comp_spv_len;
31
50
52{
53 int err;
54 AvgBlurVulkanContext *s = ctx->priv;
55 FFVulkanContext *vkctx = &s->vkctx;
56 const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
57 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->vkctx.output_format);
58
59 s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
60 if (!s->qf) {
61 av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
62 err = AVERROR(ENOTSUP);
63 goto fail;
64 }
65
66 RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, FF_VK_DEFAULT_EXEC_CONTEXTS, 0, 0, 0, NULL));
67
68 ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT,
69 NULL, (uint32_t []) { 32, 1, planes }, 0);
70
71 ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
72 VK_SHADER_STAGE_COMPUTE_BIT);
73
74 const FFVulkanDescriptorSetBinding desc_set[] = {
75 { /* input_img */
76 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
77 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
78 .elems = planes,
79 },
80 { /* output_img */
81 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
82 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
83 .elems = planes,
84 },
85 };
86 ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc_set, 2, 0);
87
88 RET(ff_vk_shader_link(vkctx, &s->shd,
91
92 RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
93
94 s->initialized = 1;
95 /* like avgblur, at most half the chroma plane */
96 s->opts.filter_len[0] = FFMIN(s->size_x,
97 AV_CEIL_RSHIFT(vkctx->output_width, desc->log2_chroma_w) / 2);
98 s->opts.filter_len[1] = FFMIN(s->size_y,
99 AV_CEIL_RSHIFT(vkctx->output_height, desc->log2_chroma_h) / 2);
100
101 s->opts.filter_norm[0] = 1.0/((s->opts.filter_len[0]*2 + 1)*(s->opts.filter_len[1]*2 + 1));
102 s->opts.filter_norm[1] = s->opts.filter_norm[0];
103 s->opts.filter_norm[2] = s->opts.filter_norm[0];
104 s->opts.filter_norm[3] = s->opts.filter_norm[0];
105
106fail:
107 return err;
108}
109
111{
112 int err;
113 AVFrame *out = NULL;
114 AVFilterContext *ctx = link->dst;
115 AvgBlurVulkanContext *s = ctx->priv;
116 AVFilterLink *outlink = ctx->outputs[0];
117
118 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
119 if (!out) {
120 err = AVERROR(ENOMEM);
121 goto fail;
122 }
123
124 if (!s->initialized)
125 RET(init_filter(ctx, in));
126
127 RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd,
128 out, in, VK_NULL_HANDLE,
129 1, &s->opts, sizeof(s->opts)));
130
131 err = av_frame_copy_props(out, in);
132 if (err < 0)
133 goto fail;
134
135 av_frame_free(&in);
136
137 return ff_filter_frame(outlink, out);
138
139fail:
140 av_frame_free(&in);
142 return err;
143}
144
146{
147 AvgBlurVulkanContext *s = avctx->priv;
148 FFVulkanContext *vkctx = &s->vkctx;
149
150 ff_vk_exec_pool_free(vkctx, &s->e);
151 ff_vk_shader_free(vkctx, &s->shd);
152
153 ff_vk_uninit(&s->vkctx);
154
155 s->initialized = 0;
156}
157
158#define OFFSET(x) offsetof(AvgBlurVulkanContext, x)
159#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
161 { "sizeX", "Set horizontal radius", OFFSET(size_x), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 32, .flags = FLAGS },
162 { "sizeY", "Set vertical radius", OFFSET(size_y), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 32, .flags = FLAGS },
163 { "planes", "Set planes to filter (bitmask)", OFFSET(opts.planes), AV_OPT_TYPE_INT, {.i64 = 0xF}, 0, 0xF, .flags = FLAGS },
164 { NULL },
165};
166
167AVFILTER_DEFINE_CLASS(avgblur_vulkan);
168
170 {
171 .name = "default",
172 .type = AVMEDIA_TYPE_VIDEO,
173 .filter_frame = &avgblur_vulkan_filter_frame,
174 .config_props = &ff_vk_filter_config_input,
175 },
176};
177
179 {
180 .name = "default",
181 .type = AVMEDIA_TYPE_VIDEO,
182 .config_props = &ff_vk_filter_config_output,
183 },
184};
185
187 .p.name = "avgblur_vulkan",
188 .p.description = NULL_IF_CONFIG_SMALL("Apply avgblur mask to input video"),
189 .p.priv_class = &avgblur_vulkan_class,
190 .p.flags = AVFILTER_FLAG_HWDEVICE,
191 .priv_size = sizeof(AvgBlurVulkanContext),
197 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
198};
const FFFilter ff_vf_avgblur_vulkan
static FILE * out
static AVFormatContext * ctx
static AVDictionary * opts
int32_t
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1073
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:596
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define NULL
Definition coverity.c:32
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define fail
Definition test.h:479
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition avfilter.h:193
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition filters.h:208
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition filters.h:254
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
Definition vulkan.c:2264
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
Definition vulkan.c:2523
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:335
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
Definition vulkan.c:399
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1631
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2781
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2759
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2557
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:320
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition vulkan.c:2427
const char * desc
Definition libsvtav1.c:83
static const struct @257111027162314367033347246032313251342043035002 planes[]
#define FFMIN(a, b)
Definition macros.h:49
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3524
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
An instance of a filter.
Definition avfilter.h:279
void * priv
private data for use by the filter
Definition avfilter.h:294
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
AVOption.
Definition opt.h:428
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
AVVulkanDeviceQueueFamily * qf
int output_height
Definition vulkan.h:352
#define av_log(a,...)
static const AVOption avgblur_vulkan_options[]
const unsigned char ff_avgblur_comp_spv_data[]
const unsigned int ff_avgblur_comp_spv_len
static const AVFilterPad avgblur_vulkan_outputs[]
static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
#define OFFSET(x)
static void avgblur_vulkan_uninit(AVFilterContext *avctx)
static int avgblur_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
static const AVFilterPad avgblur_vulkan_inputs[]
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:90
#define FF_VK_DEFAULT_EXEC_CONTEXTS
Definition vulkan.h:121
#define RET(x)
Definition vulkan.h:37
int ff_vk_filter_config_input(AVFilterLink *inlink)
int ff_vk_filter_config_output(AVFilterLink *outlink)
int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f, VkSampler sampler, uint32_t wgc_z, void *push_src, size_t push_size)
Submit a compute shader with a zero/one input and single out for execution.
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.