FFmpeg
Loading...
Searching...
No Matches
vf_bwdif_vulkan.c
Go to the documentation of this file.
1/*
2 * Copyright (c) Lynne
3 * Copyright (C) 2018 Philip Langdale <philipl@overt.org>
4 * Copyright (C) 2016 Thomas Mundt <loudmax@yahoo.de>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
24#include "libavutil/opt.h"
25#include "vulkan_filter.h"
26#include "yadif.h"
27#include "filters.h"
28
38
44
45extern const unsigned char ff_bwdif_comp_spv_data[];
46extern const unsigned int ff_bwdif_comp_spv_len;
47
49{
50 int err;
51 BWDIFVulkanContext *s = ctx->priv;
52 FFVulkanContext *vkctx = &s->vkctx;
53 const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
54
55 s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
56 if (!s->qf) {
57 av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
58 err = AVERROR(ENOTSUP);
59 goto fail;
60 }
61
62 RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, FF_VK_DEFAULT_EXEC_CONTEXTS, 0, 0, 0, NULL));
63
64 ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
65 (uint32_t [3]) { 1, 64, planes }, 0);
66
67 const FFVulkanDescriptorSetBinding desc_set[] = {
68 { /* prev */
69 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
70 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
71 .elems = planes,
72 },
73 { /* cur */
74 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
75 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
76 .elems = planes,
77 },
78 { /* next */
79 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
80 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
81 .elems = planes,
82 },
83 { /* dst */
84 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
85 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
86 .elems = planes,
87 },
88 };
89 ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc_set, 4, 0);
90
92 VK_SHADER_STAGE_COMPUTE_BIT);
93
94 RET(ff_vk_shader_link(vkctx, &s->shd,
96 ff_bwdif_comp_spv_len, "main"));
97 RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
98
99 s->initialized = 1;
100
101fail:
102 return err;
103}
104
106 int parity, int tff)
107{
108 BWDIFVulkanContext *s = ctx->priv;
109 YADIFContext *y = &s->yadif;
111 .parity = parity,
112 .tff = tff,
113 .current_field = y->current_field,
114 };
115
116 ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, dst,
117 (AVFrame *[]){ y->prev, y->cur, y->next }, 3,
118 VK_NULL_HANDLE, 1, &params, sizeof(params));
119
122}
123
125{
126 BWDIFVulkanContext *s = avctx->priv;
127 FFVulkanContext *vkctx = &s->vkctx;
128
129 ff_vk_exec_pool_free(vkctx, &s->e);
130 ff_vk_shader_free(vkctx, &s->shd);
131
132 ff_vk_uninit(&s->vkctx);
133
134 ff_yadif_uninit(avctx);
135
136 s->initialized = 0;
137}
138
140{
141 FilterLink *l = ff_filter_link(inlink);
142 AVHWFramesContext *input_frames;
143 AVFilterContext *avctx = inlink->dst;
144 BWDIFVulkanContext *s = avctx->priv;
145 FFVulkanContext *vkctx = &s->vkctx;
146
147 if (!l->hw_frames_ctx) {
148 av_log(inlink->dst, AV_LOG_ERROR, "Vulkan filtering requires a "
149 "hardware frames context on the input.\n");
150 return AVERROR(EINVAL);
151 }
152
153 input_frames = (AVHWFramesContext *)l->hw_frames_ctx->data;
154 if (input_frames->format != AV_PIX_FMT_VULKAN)
155 return AVERROR(EINVAL);
156
157 /* Extract the device and default output format from the first input. */
158 if (avctx->inputs[0] != inlink)
159 return 0;
160
161 /* Save the ref, without reffing it */
163
164 /* Defaults */
165 vkctx->output_format = input_frames->sw_format;
166 vkctx->output_width = inlink->w;
167 vkctx->output_height = inlink->h;
168
169 return 0;
170}
171
173{
174 FilterLink *l = ff_filter_link(outlink);
175 int err;
176 AVFilterContext *avctx = outlink->src;
177 BWDIFVulkanContext *s = avctx->priv;
178 YADIFContext *y = &s->yadif;
179 FFVulkanContext *vkctx = &s->vkctx;
180
182
183 err = ff_vk_filter_init_context(avctx, vkctx, vkctx->input_frames_ref,
184 vkctx->output_width, vkctx->output_height,
185 vkctx->output_format);
186 if (err < 0)
187 return err;
188
189 /* For logging */
190 vkctx->class = y->class;
191
193 if (!l->hw_frames_ctx)
194 return AVERROR(ENOMEM);
195
196 err = ff_yadif_config_output_common(outlink);
197 if (err < 0)
198 return err;
199
202
203 if (AV_CEIL_RSHIFT(outlink->w, y->csp->log2_chroma_w) < 4 || AV_CEIL_RSHIFT(outlink->h, y->csp->log2_chroma_h) < 4) {
204 av_log(avctx, AV_LOG_ERROR, "Video with planes less than 4 columns or lines is not supported\n");
205 return AVERROR(EINVAL);
206 }
207
208 return init_filter(avctx);
209}
210
212 .class_name = "bwdif_vulkan",
213 .item_name = av_default_item_name,
214 .option = ff_yadif_options,
215 .version = LIBAVUTIL_VERSION_INT,
216 .category = AV_CLASS_CATEGORY_FILTER,
217};
218
220 {
221 .name = "default",
222 .type = AVMEDIA_TYPE_VIDEO,
223 .filter_frame = ff_yadif_filter_frame,
224 .config_props = &bwdif_vulkan_config_input,
225 },
226};
227
229 {
230 .name = "default",
231 .type = AVMEDIA_TYPE_VIDEO,
232 .request_frame = ff_yadif_request_frame,
233 .config_props = &bwdif_vulkan_config_output,
234 },
235};
236
238 .p.name = "bwdif_vulkan",
239 .p.description = NULL_IF_CONFIG_SMALL("Deinterlace Vulkan frames via bwdif"),
240 .p.priv_class = &bwdif_vulkan_class,
241 .p.flags = AVFILTER_FLAG_HWDEVICE |
243 .priv_size = sizeof(BWDIFVulkanContext),
249 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
250};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
SwsAArch64OpImplParams params
Definition ops.c:51
const FFFilter ff_vf_bwdif_vulkan
static AVFormatContext * ctx
#define s(width, name)
Definition cbs_vp9.c:198
#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
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition avfilter.h:187
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition avfilter.h:204
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
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
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition filters.h:254
#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:88
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:2240
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:2550
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:331
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:395
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1613
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2815
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2791
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2584
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:316
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:2444
static const struct @257111027162314367033347246032313251342043035002 planes[]
@ AV_CLASS_CATEGORY_FILTER
Definition log.h:36
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
AVFilterLink ** inputs
array of pointers to input links
Definition avfilter.h:281
void * priv
private data for use by the filter
Definition avfilter.h:288
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:472
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition pixdesc.h:80
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition pixdesc.h:89
FFVulkanContext vkctx
FFVulkanShader shd
AVVulkanDeviceQueueFamily * qf
AVHWFramesContext * frames
Definition vulkan.h:343
int output_height
Definition vulkan.h:351
const AVClass * class
Definition vulkan.h:295
AVBufferRef * input_frames_ref
Definition vulkan.h:341
AVBufferRef * frames_ref
Definition vulkan.h:342
enum AVPixelFormat output_format
Definition vulkan.h:352
void(* filter)(AVFilterContext *ctx, AVFrame *dstpic, int parity, int tff)
Definition yadif.h:65
int current_field
YADIFCurrentField.
Definition yadif.h:88
const AVPixFmtDescriptor * csp
Definition yadif.h:76
const AVClass * class
Definition yadif.h:52
#define av_log(a,...)
static const AVFilterPad bwdif_vulkan_outputs[]
static const AVClass bwdif_vulkan_class
static av_cold int init_filter(AVFilterContext *ctx)
const unsigned int ff_bwdif_comp_spv_len
static int bwdif_vulkan_config_output(AVFilterLink *outlink)
static void bwdif_vulkan_uninit(AVFilterContext *avctx)
static const AVFilterPad bwdif_vulkan_inputs[]
static void bwdif_vulkan_filter_frame(AVFilterContext *ctx, AVFrame *dst, int parity, int tff)
const unsigned char ff_bwdif_comp_spv_data[]
static int bwdif_vulkan_config_input(AVFilterLink *inlink)
mcdeint parity
Definition vf_mcdeint.c:293
#define FF_VK_DEFAULT_EXEC_CONTEXTS
Definition vulkan.h:121
#define RET(x)
Definition vulkan.h:37
int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, FFVulkanShader *shd, AVFrame *out, AVFrame *in[], int nb_in, VkSampler sampler, uint32_t wgc_z, void *push_src, size_t push_size)
Up to 16 inputs, one output.
int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, AVBufferRef *frames_ref, int width, int height, enum AVPixelFormat sw_format)
Can be called manually, if not using ff_vk_filter_config_output.
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.
@ YADIF_FIELD_NORMAL
A normal field in the middle of a sequence.
Definition yadif.h:48
@ YADIF_FIELD_END
The first or last field in a sequence.
Definition yadif.h:47
int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
int ff_yadif_request_frame(AVFilterLink *link)
const AVOption ff_yadif_options[]
void ff_yadif_uninit(AVFilterContext *ctx)
int ff_yadif_config_output_common(AVFilterLink *outlink)