FFmpeg
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 
23 #include "libavutil/random_seed.h"
24 #include "libavutil/opt.h"
25 #include "vulkan_filter.h"
26 #include "vulkan_spirv.h"
27 #include "yadif.h"
28 #include "internal.h"
29 
30 typedef struct BWDIFVulkanContext {
33 
37  VkSampler sampler;
41 
42 typedef struct BWDIFParameters {
43  int parity;
44  int tff;
47 
48 static const char filter_fn[] = {
49  "const vec4 coef_lf[2] = { vec4(4309), vec4(213), };\n"
50  "const vec4 coef_hf[3] = { vec4(5570), vec4(3801), vec4(1016) };\n"
51  "const vec4 coef_sp[2] = { vec4(5077), vec4(981), };\n"
52  C(0, )
53  C(0, vec4 process_intra(vec4 cur[4]) )
54  C(0, { )
55  C(1, return (coef_sp[0]*(cur[1] + cur[2]) - coef_sp[1]*(cur[0] + cur[3])) / (1 << 13); )
56  C(0, } )
57  C(0, )
58  C(0, vec4 process_line(vec4 prev2[5], vec4 prev1[2], vec4 cur[4], vec4 next1[2], vec4 next2[5]) )
59  C(0, { )
60  C(1, vec4 fc = cur[1]; )
61  C(1, vec4 fe = cur[2]; )
62  C(1, vec4 fs = prev2[2] + next2[2]; )
63  C(1, vec4 fd = fs / 2; )
64  C(0, )
65  C(1, vec4 temp_diff[3]; )
66  C(1, temp_diff[0] = abs(prev2[2] - next2[2]); )
67  C(1, temp_diff[1] = (abs(prev1[0] - fc) + abs(prev1[1] - fe)) / 2; )
68  C(1, temp_diff[1] = (abs(next1[0] - fc) + abs(next1[1] - fe)) / 2; )
69  C(1, vec4 diff = max(temp_diff[0] / 2, max(temp_diff[1], temp_diff[2])); )
70  C(1, bvec4 diff_mask = equal(diff, vec4(0)); )
71  C(0, )
72  C(1, vec4 fbs = prev2[1] + next2[1]; )
73  C(1, vec4 ffs = prev2[3] + next2[3]; )
74  C(1, vec4 fb = (fbs / 2) - fc; )
75  C(1, vec4 ff = (ffs / 2) - fe; )
76  C(1, vec4 dc = fd - fc; )
77  C(1, vec4 de = fd - fe; )
78  C(1, vec4 mmax = max(de, max(dc, min(fb, ff))); )
79  C(1, vec4 mmin = min(de, min(dc, max(fb, ff))); )
80  C(1, diff = max(diff, max(mmin, -mmax)); )
81  C(0, )
82 " vec4 interpolate_all = (((coef_hf[0]*(fs) - coef_hf[1]*(fbs + ffs) +\n"
83 " coef_hf[2]*(prev2[0] + next2[0] + prev2[4] + next2[4])) / 4) +\n"
84 " coef_lf[0]*(fc + fe) - coef_lf[1]*(cur[0] + cur[3])) / (1 << 13);\n"
85 " vec4 interpolate_cur = (coef_sp[0]*(fc + fe) - coef_sp[1]*(cur[0] + cur[3])) / (1 << 13);\n"
86  C(0, )
87  C(1, bvec4 interpolate_cnd1 = greaterThan(abs(fc - fe), temp_diff[0]); )
88  C(1, vec4 interpol = mix(interpolate_cur, interpolate_all, interpolate_cnd1); )
89  C(1, interpol = clamp(interpol, fd - diff, fd + diff); )
90  C(1, return mix(interpol, fd, diff_mask); )
91  C(0, } )
92 };
93 
95 {
96  int err;
97  uint8_t *spv_data;
98  size_t spv_len;
99  void *spv_opaque = NULL;
100  BWDIFVulkanContext *s = ctx->priv;
101  FFVulkanContext *vkctx = &s->vkctx;
102  const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
103  FFVkSPIRVShader *shd;
104  FFVkSPIRVCompiler *spv;
106 
107  spv = ff_vk_spirv_init();
108  if (!spv) {
109  av_log(ctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n");
110  return AVERROR_EXTERNAL;
111  }
112 
113  ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
114  RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
115  RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
116  RET(ff_vk_shader_init(&s->pl, &s->shd, "bwdif_compute",
117  VK_SHADER_STAGE_COMPUTE_BIT, 0));
118  shd = &s->shd;
119 
120  ff_vk_shader_set_compute_sizes(shd, 1, 64, 1);
121 
123  {
124  .name = "prev",
125  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
126  .dimensions = 2,
127  .elems = planes,
128  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
129  .samplers = DUP_SAMPLER(s->sampler),
130  },
131  {
132  .name = "cur",
133  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
134  .dimensions = 2,
135  .elems = planes,
136  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
137  .samplers = DUP_SAMPLER(s->sampler),
138  },
139  {
140  .name = "next",
141  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
142  .dimensions = 2,
143  .elems = planes,
144  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
145  .samplers = DUP_SAMPLER(s->sampler),
146  },
147  {
148  .name = "dst",
149  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
150  .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.output_format),
151  .mem_quali = "writeonly",
152  .dimensions = 2,
153  .elems = planes,
154  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
155  },
156  };
157 
158  RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 4, 0, 0));
159 
160  GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
161  GLSLC(1, int parity; );
162  GLSLC(1, int tff; );
163  GLSLC(1, int current_field; );
164  GLSLC(0, }; );
165 
166  ff_vk_add_push_constant(&s->pl, 0, sizeof(BWDIFParameters),
167  VK_SHADER_STAGE_COMPUTE_BIT);
168 
169  GLSLD( filter_fn );
170  GLSLC(0, void main() );
171  GLSLC(0, { );
172  GLSLC(1, vec4 res; );
173  GLSLC(1, ivec2 size; );
174  GLSLC(1, vec4 dcur[4]; );
175  GLSLC(1, vec4 prev1[2]; );
176  GLSLC(1, vec4 next1[2]; );
177  GLSLC(1, vec4 prev2[5]; );
178  GLSLC(1, vec4 next2[5]; );
179  GLSLC(1, const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
180  GLSLC(1, bool filter_field = ((pos.y ^ parity) & 1) == 1; );
181  GLSLF(1, bool is_intra = filter_field && (current_field == %i); ,YADIF_FIELD_END);
182  GLSLC(1, bool field_parity = (parity ^ tff) != 0; );
183  GLSLC(0, );
184 
185  for (int i = 0; i < planes; i++) {
186  GLSLC(0, );
187  GLSLF(1, size = imageSize(dst[%i]); ,i);
188  GLSLC(1, if (!IS_WITHIN(pos, size)) { );
189  GLSLC(2, return; );
190  GLSLC(1, } else if (is_intra) { );
191  GLSLF(2, dcur[0] = texture(cur[%i], pos - ivec2(0, 3)); ,i);
192  GLSLF(2, dcur[1] = texture(cur[%i], pos - ivec2(0, 1)); ,i);
193  GLSLF(2, dcur[2] = texture(cur[%i], pos + ivec2(0, 1)); ,i);
194  GLSLF(2, dcur[3] = texture(cur[%i], pos + ivec2(0, 3)); ,i);
195  GLSLC(0, );
196  GLSLC(2, res = process_intra(dcur); );
197  GLSLF(2, imageStore(dst[%i], pos, res); ,i);
198  GLSLC(1, } else if (filter_field) { );
199  GLSLF(2, dcur[0] = texture(cur[%i], pos - ivec2(0, 3)); ,i);
200  GLSLF(2, dcur[1] = texture(cur[%i], pos - ivec2(0, 1)); ,i);
201  GLSLF(2, dcur[2] = texture(cur[%i], pos + ivec2(0, 1)); ,i);
202  GLSLF(2, dcur[3] = texture(cur[%i], pos + ivec2(0, 3)); ,i);
203  GLSLC(0, );
204  GLSLF(2, prev1[0] = texture(prev[%i], pos - ivec2(0, 1)); ,i);
205  GLSLF(2, prev1[1] = texture(prev[%i], pos + ivec2(0, 1)); ,i);
206  GLSLC(0, );
207  GLSLF(2, next1[0] = texture(next[%i], pos - ivec2(0, 1)); ,i);
208  GLSLF(2, next1[1] = texture(next[%i], pos + ivec2(0, 1)); ,i);
209  GLSLC(0, );
210  GLSLC(2, if (field_parity) { );
211  GLSLF(3, prev2[0] = texture(prev[%i], pos - ivec2(0, 4)); ,i);
212  GLSLF(3, prev2[1] = texture(prev[%i], pos - ivec2(0, 2)); ,i);
213  GLSLF(3, prev2[2] = texture(prev[%i], pos); ,i);
214  GLSLF(3, prev2[3] = texture(prev[%i], pos + ivec2(0, 2)); ,i);
215  GLSLF(3, prev2[4] = texture(prev[%i], pos + ivec2(0, 4)); ,i);
216  GLSLC(0, );
217  GLSLF(3, next2[0] = texture(cur[%i], pos - ivec2(0, 4)); ,i);
218  GLSLF(3, next2[1] = texture(cur[%i], pos - ivec2(0, 2)); ,i);
219  GLSLF(3, next2[2] = texture(cur[%i], pos); ,i);
220  GLSLF(3, next2[3] = texture(cur[%i], pos + ivec2(0, 2)); ,i);
221  GLSLF(3, next2[4] = texture(cur[%i], pos + ivec2(0, 4)); ,i);
222  GLSLC(2, } else { );
223  GLSLF(3, prev2[0] = texture(cur[%i], pos - ivec2(0, 4)); ,i);
224  GLSLF(3, prev2[1] = texture(cur[%i], pos - ivec2(0, 2)); ,i);
225  GLSLF(3, prev2[2] = texture(cur[%i], pos); ,i);
226  GLSLF(3, prev2[3] = texture(cur[%i], pos + ivec2(0, 2)); ,i);
227  GLSLF(3, prev2[4] = texture(cur[%i], pos + ivec2(0, 4)); ,i);
228  GLSLC(0, );
229  GLSLF(3, next2[0] = texture(next[%i], pos - ivec2(0, 4)); ,i);
230  GLSLF(3, next2[1] = texture(next[%i], pos - ivec2(0, 2)); ,i);
231  GLSLF(3, next2[2] = texture(next[%i], pos); ,i);
232  GLSLF(3, next2[3] = texture(next[%i], pos + ivec2(0, 2)); ,i);
233  GLSLF(3, next2[4] = texture(next[%i], pos + ivec2(0, 4)); ,i);
234  GLSLC(2, } );
235  GLSLC(0, );
236  GLSLC(2, res = process_line(prev2, prev1, dcur, next1, next2); );
237  GLSLF(2, imageStore(dst[%i], pos, res); ,i);
238  GLSLC(1, } else { );
239  GLSLF(2, res = texture(cur[%i], pos); ,i);
240  GLSLF(2, imageStore(dst[%i], pos, res); ,i);
241  GLSLC(1, } );
242  }
243 
244  GLSLC(0, } );
245 
246  RET(spv->compile_shader(spv, ctx, &s->shd, &spv_data, &spv_len, "main",
247  &spv_opaque));
248  RET(ff_vk_shader_create(vkctx, &s->shd, spv_data, spv_len, "main"));
249 
250  RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, &s->shd));
251  RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
252 
253  s->initialized = 1;
254 
255 fail:
256  if (spv_opaque)
257  spv->free_shader(spv, &spv_opaque);
258  if (spv)
259  spv->uninit(&spv);
260 
261  return err;
262 }
263 
265  int parity, int tff)
266 {
267  BWDIFVulkanContext *s = ctx->priv;
268  YADIFContext *y = &s->yadif;
269  BWDIFParameters params = {
270  .parity = parity,
271  .tff = tff,
272  .current_field = y->current_field,
273  };
274 
275  ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, dst,
276  (AVFrame *[]){ y->prev, y->cur, y->next }, 3,
277  s->sampler, &params, sizeof(params));
278 
279  if (y->current_field == YADIF_FIELD_END)
281 }
282 
284 {
285  BWDIFVulkanContext *s = avctx->priv;
286  FFVulkanContext *vkctx = &s->vkctx;
287  FFVulkanFunctions *vk = &vkctx->vkfn;
288 
289  ff_vk_exec_pool_free(vkctx, &s->e);
290  ff_vk_pipeline_free(vkctx, &s->pl);
291  ff_vk_shader_free(vkctx, &s->shd);
292 
293  if (s->sampler)
294  vk->DestroySampler(vkctx->hwctx->act_dev, s->sampler,
295  vkctx->hwctx->alloc);
296 
297  ff_vk_uninit(&s->vkctx);
298 
299  s->initialized = 0;
300 }
301 
303 {
304  AVHWFramesContext *input_frames;
305  AVFilterContext *avctx = inlink->dst;
306  BWDIFVulkanContext *s = avctx->priv;
307  FFVulkanContext *vkctx = &s->vkctx;
308 
309  if (!inlink->hw_frames_ctx) {
310  av_log(inlink->dst, AV_LOG_ERROR, "Vulkan filtering requires a "
311  "hardware frames context on the input.\n");
312  return AVERROR(EINVAL);
313  }
314 
315  input_frames = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
316  if (input_frames->format != AV_PIX_FMT_VULKAN)
317  return AVERROR(EINVAL);
318 
319  /* Extract the device and default output format from the first input. */
320  if (avctx->inputs[0] != inlink)
321  return 0;
322 
323  /* Save the ref, without reffing it */
324  vkctx->input_frames_ref = inlink->hw_frames_ctx;
325 
326  /* Defaults */
327  vkctx->output_format = input_frames->sw_format;
328  vkctx->output_width = inlink->w;
329  vkctx->output_height = inlink->h;
330 
331  return 0;
332 }
333 
335 {
336  int err;
337  AVFilterContext *avctx = outlink->src;
338  BWDIFVulkanContext *s = avctx->priv;
339  YADIFContext *y = &s->yadif;
340  FFVulkanContext *vkctx = &s->vkctx;
341 
342  av_buffer_unref(&outlink->hw_frames_ctx);
343 
344  err = ff_vk_filter_init_context(avctx, vkctx, vkctx->input_frames_ref,
345  vkctx->output_width, vkctx->output_height,
346  vkctx->output_format);
347  if (err < 0)
348  return err;
349 
350  /* For logging */
351  vkctx->class = y->class;
352 
353  outlink->hw_frames_ctx = av_buffer_ref(vkctx->frames_ref);
354  if (!outlink->hw_frames_ctx)
355  return AVERROR(ENOMEM);
356 
357  outlink->time_base = av_mul_q(avctx->inputs[0]->time_base, (AVRational){1, 2});
358  outlink->w = vkctx->output_width;
359  outlink->h = vkctx->output_height;
360 
361  if (y->mode & 1)
362  outlink->frame_rate = av_mul_q(avctx->inputs[0]->frame_rate,
363  (AVRational){2, 1});
364 
365  if (outlink->w < 4 || outlink->h < 4) {
366  av_log(avctx, AV_LOG_ERROR, "Video of less than 4 columns or lines is not "
367  "supported\n");
368  return AVERROR(EINVAL);
369  }
370 
371  y->csp = av_pix_fmt_desc_get(vkctx->frames->sw_format);
373 
374  return init_filter(avctx);
375 }
376 
377 static const AVClass bwdif_vulkan_class = {
378  .class_name = "bwdif_vulkan",
379  .item_name = av_default_item_name,
380  .option = ff_yadif_options,
381  .version = LIBAVUTIL_VERSION_INT,
382  .category = AV_CLASS_CATEGORY_FILTER,
383 };
384 
386  {
387  .name = "default",
388  .type = AVMEDIA_TYPE_VIDEO,
389  .filter_frame = ff_yadif_filter_frame,
390  .config_props = &bwdif_vulkan_config_input,
391  },
392 };
393 
395  {
396  .name = "default",
397  .type = AVMEDIA_TYPE_VIDEO,
398  .request_frame = ff_yadif_request_frame,
399  .config_props = &bwdif_vulkan_config_output,
400  },
401 };
402 
404  .name = "bwdif_vulkan",
405  .description = NULL_IF_CONFIG_SMALL("Deinterlace Vulkan frames via bwdif"),
406  .priv_size = sizeof(BWDIFVulkanContext),
412  .priv_class = &bwdif_vulkan_class,
413  .flags = AVFILTER_FLAG_HWDEVICE |
415  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
416 };
filter_fn
static const char filter_fn[]
Definition: vf_bwdif_vulkan.c:48
YADIFContext::class
const AVClass * class
Definition: yadif.h:52
interpol
static int interpol(MBContext *s, uint32_t *color, int x, int y, int linesize)
Definition: vsrc_mandelbrot.c:184
ff_vk_pipeline_free
void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
Definition: vulkan.c:1868
FFVulkanContext::output_height
int output_height
Definition: vulkan.h:266
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
FF_FILTER_FLAG_HWFRAME_AWARE
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition: internal.h:364
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2964
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
ff_vf_bwdif_vulkan
const AVFilter ff_vf_bwdif_vulkan
Definition: vf_bwdif_vulkan.c:403
ff_vk_qf_init
int ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf, VkQueueFlagBits dev_family)
Chooses a QF and loads it into a context.
Definition: vulkan.c:225
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
YADIFContext::csp
const AVPixFmtDescriptor * csp
Definition: yadif.h:76
YADIFContext::mode
int mode
YADIFMode.
Definition: yadif.h:54
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
ff_vk_filter_init
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.
Definition: vulkan_filter.c:219
ff_vk_filter_process_Nin
int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, FFVulkanPipeline *pl, AVFrame *out, AVFrame *in[], int nb_in, VkSampler sampler, void *push_src, size_t push_size)
Up to 16 inputs, one output.
Definition: vulkan_filter.c:385
FFVulkanContext::class
const AVClass * class
Definition: vulkan.h:230
ff_vk_shader_create
int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd, uint8_t *spirv, size_t spirv_size, const char *entrypoint)
Definition: vulkan.c:1413
BWDIFParameters::current_field
int current_field
Definition: vf_bwdif_vulkan.c:45
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:464
max
#define max(a, b)
Definition: cuda_runtime.h:33
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:1897
FFVkSPIRVCompiler::uninit
void(* uninit)(struct FFVkSPIRVCompiler **ctx)
Definition: vulkan_spirv.h:33
BWDIFVulkanContext::pl
FFVulkanPipeline pl
Definition: vf_bwdif_vulkan.c:38
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
ff_vk_pipeline_descriptor_set_add
int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl, FFVkSPIRVShader *shd, FFVulkanDescriptorSetBinding *desc, int nb, int read_only, int print_to_shader_only)
Add descriptor to a pipeline.
Definition: vulkan.c:1463
ff_vk_shader_set_compute_sizes
void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z)
Definition: vulkan.c:1371
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:376
BWDIFParameters::tff
int tff
Definition: vf_bwdif_vulkan.c:44
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3004
bwdif_vulkan_uninit
static void bwdif_vulkan_uninit(AVFilterContext *avctx)
Definition: vf_bwdif_vulkan.c:283
AVVulkanDeviceContext::alloc
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
Definition: hwcontext_vulkan.h:48
ff_vk_add_push_constant
int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition: vulkan.c:1143
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:412
fail
#define fail()
Definition: checkasm.h:138
vulkan_filter.h
coef_sp
static const uint16_t coef_sp[2]
Definition: bwdifdsp.c:49
ff_vk_filter_init_context
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.
Definition: vulkan_filter.c:23
FFVulkanContext::frames_ref
AVBufferRef * frames_ref
Definition: vulkan.h:257
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:47
C
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
Definition: writing_filters.txt:58
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
bwdif_vulkan_config_input
static int bwdif_vulkan_config_input(AVFilterLink *inlink)
Definition: vf_bwdif_vulkan.c:302
FFVulkanContext::output_width
int output_width
Definition: vulkan.h:265
s
#define s(width, name)
Definition: cbs_vp9.c:198
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
process_line
static int process_line(URLContext *h, char *line, int line_count)
Definition: http.c:1082
ctx
AVFormatContext * ctx
Definition: movenc.c:48
BWDIFVulkanContext::shd
FFVkSPIRVShader shd
Definition: vf_bwdif_vulkan.c:39
FFVkSPIRVCompiler::compile_shader
int(* compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx, struct FFVkSPIRVShader *shd, uint8_t **data, size_t *size, const char *entrypoint, void **opaque)
Definition: vulkan_spirv.h:29
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:256
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:192
if
if(ret)
Definition: filter_design.txt:179
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
BWDIFVulkanContext::initialized
int initialized
Definition: vf_bwdif_vulkan.c:34
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:222
av_buffer_unref
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
GLSLD
#define GLSLD(D)
Definition: vulkan.h:60
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
fbs
#define fbs(width, name, subs,...)
Definition: cbs_av1.c:470
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:405
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
ff_vk_init_compute_pipeline
int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl, FFVkSPIRVShader *shd)
Definition: vulkan.c:1809
abs
#define abs(x)
Definition: cuda_runtime.h:35
ff_vk_exec_pool_init
int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *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:296
FFVulkanContext
Definition: vulkan.h:229
bwdif_vulkan_config_output
static int bwdif_vulkan_config_output(AVFilterLink *outlink)
Definition: vf_bwdif_vulkan.c:334
FFVulkanPipeline
Definition: vulkan.h:132
BWDIFParameters::parity
int parity
Definition: vf_bwdif_vulkan.c:43
AV_CLASS_CATEGORY_FILTER
@ AV_CLASS_CATEGORY_FILTER
Definition: log.h:36
ff_yadif_options
const AVOption ff_yadif_options[]
Definition: yadif_common.c:217
ff_vk_shader_init
int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name, VkShaderStageFlags stage, uint32_t required_subgroup_size)
Shader management.
Definition: vulkan.c:1345
main
int main(int argc, char **argv)
Definition: avio_http_serve_files.c:99
yadif.h
FFVulkanDescriptorSetBinding
Definition: vulkan.h:84
dc
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
Definition: snow.txt:400
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
BWDIFVulkanContext::vkctx
FFVulkanContext vkctx
Definition: vf_bwdif_vulkan.c:32
AVFILTER_FLAG_HWDEVICE
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition: avfilter.h:138
size
int size
Definition: twinvq_data.h:10344
FFVkQueueFamilyCtx
Definition: vulkan.h:111
YADIFContext::filter
void(* filter)(AVFilterContext *ctx, AVFrame *dstpic, int parity, int tff)
Definition: yadif.h:65
parity
mcdeint parity
Definition: vf_mcdeint.c:281
BWDIFVulkanContext::yadif
YADIFContext yadif
Definition: vf_bwdif_vulkan.c:31
FFVulkanContext::output_format
enum AVPixelFormat output_format
Definition: vulkan.h:267
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:164
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
internal.h
FFVulkanContext::input_frames_ref
AVBufferRef * input_frames_ref
Definition: vulkan.h:256
FFVkSPIRVCompiler
Definition: vulkan_spirv.h:27
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: internal.h:182
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
BWDIFVulkanContext
Definition: vf_bwdif_vulkan.c:30
DUP_SAMPLER
#define DUP_SAMPLER(x)
Definition: vulkan.h:74
fb
#define fb(width, name)
Definition: cbs_av1.c:585
planes
static const struct @363 planes[]
ff_vk_shader_rep_fmt
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt)
Returns the format to use for images in shaders.
Definition: vulkan.c:1207
YADIFContext
Definition: yadif.h:51
vulkan_spirv.h
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:53
GLSLF
#define GLSLF(N, S,...)
Definition: vulkan.h:55
BWDIFVulkanContext::e
FFVkExecPool e
Definition: vf_bwdif_vulkan.c:35
FFVkSPIRVCompiler::free_shader
void(* free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque)
Definition: vulkan_spirv.h:32
AVFilter
Filter definition.
Definition: avfilter.h:166
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:232
FFVkExecPool
Definition: vulkan.h:211
pos
unsigned int pos
Definition: spdifenc.c:413
BWDIFVulkanContext::qf
FFVkQueueFamilyCtx qf
Definition: vf_bwdif_vulkan.c:36
bwdif_vulkan_class
static const AVClass bwdif_vulkan_class
Definition: vf_bwdif_vulkan.c:377
bwdif_vulkan_outputs
static const AVFilterPad bwdif_vulkan_outputs[]
Definition: vf_bwdif_vulkan.c:394
random_seed.h
FFVkSPIRVShader
Definition: vulkan.h:76
YADIF_FIELD_END
@ YADIF_FIELD_END
The first or last field in a sequence.
Definition: yadif.h:47
ff_yadif_request_frame
int ff_yadif_request_frame(AVFilterLink *link)
Definition: yadif_common.c:178
bwdif_vulkan_inputs
static const AVFilterPad bwdif_vulkan_inputs[]
Definition: vf_bwdif_vulkan.c:385
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVFilterContext
An instance of a filter.
Definition: avfilter.h:397
YADIF_FIELD_NORMAL
@ YADIF_FIELD_NORMAL
A normal field in the middle of a sequence.
Definition: yadif.h:48
desc
const char * desc
Definition: libsvtav1.c:83
GLSLC
#define GLSLC(N, S)
Definition: vulkan.h:45
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFVulkanContext::hwctx
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:254
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:70
equal
static int equal(MetadataContext *s, const char *value1, const char *value2)
Definition: f_metadata.c:143
YADIFContext::current_field
int current_field
YADIFCurrentField.
Definition: yadif.h:88
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:193
ff_vk_init_sampler
int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, int unnorm_coords, VkFilter filt)
Create a sampler.
Definition: vulkan.c:1163
bwdif_vulkan_filter_frame
static void bwdif_vulkan_filter_frame(AVFilterContext *ctx, AVFrame *dst, int parity, int tff)
Definition: vf_bwdif_vulkan.c:264
ff_vk_exec_pipeline_register
int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanPipeline *pl)
Register a pipeline with an exec pool.
Definition: vulkan.c:1577
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
#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:155
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
init_filter
static av_cold int init_filter(AVFilterContext *ctx)
Definition: vf_bwdif_vulkan.c:94
BWDIFParameters
Definition: vf_bwdif_vulkan.c:42
FFVulkanContext::frames
AVHWFramesContext * frames
Definition: vulkan.h:258
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:285
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd)
Definition: vulkan.c:1404
BWDIFVulkanContext::sampler
VkSampler sampler
Definition: vf_bwdif_vulkan.c:37
RET
#define RET(x)
Definition: vulkan.h:68
FFVulkanFunctions
Definition: vulkan_functions.h:226
ff_yadif_filter_frame
int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
Definition: yadif_common.c:100
min
float min
Definition: vorbis_enc_data.h:429