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  ff_yadif_uninit(avctx);
300 
301  s->initialized = 0;
302 }
303 
305 {
306  AVHWFramesContext *input_frames;
307  AVFilterContext *avctx = inlink->dst;
308  BWDIFVulkanContext *s = avctx->priv;
309  FFVulkanContext *vkctx = &s->vkctx;
310 
311  if (!inlink->hw_frames_ctx) {
312  av_log(inlink->dst, AV_LOG_ERROR, "Vulkan filtering requires a "
313  "hardware frames context on the input.\n");
314  return AVERROR(EINVAL);
315  }
316 
317  input_frames = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
318  if (input_frames->format != AV_PIX_FMT_VULKAN)
319  return AVERROR(EINVAL);
320 
321  /* Extract the device and default output format from the first input. */
322  if (avctx->inputs[0] != inlink)
323  return 0;
324 
325  /* Save the ref, without reffing it */
326  vkctx->input_frames_ref = inlink->hw_frames_ctx;
327 
328  /* Defaults */
329  vkctx->output_format = input_frames->sw_format;
330  vkctx->output_width = inlink->w;
331  vkctx->output_height = inlink->h;
332 
333  return 0;
334 }
335 
337 {
338  int err;
339  AVFilterContext *avctx = outlink->src;
340  BWDIFVulkanContext *s = avctx->priv;
341  YADIFContext *y = &s->yadif;
342  FFVulkanContext *vkctx = &s->vkctx;
343 
344  av_buffer_unref(&outlink->hw_frames_ctx);
345 
346  err = ff_vk_filter_init_context(avctx, vkctx, vkctx->input_frames_ref,
347  vkctx->output_width, vkctx->output_height,
348  vkctx->output_format);
349  if (err < 0)
350  return err;
351 
352  /* For logging */
353  vkctx->class = y->class;
354 
355  outlink->hw_frames_ctx = av_buffer_ref(vkctx->frames_ref);
356  if (!outlink->hw_frames_ctx)
357  return AVERROR(ENOMEM);
358 
359  err = ff_yadif_config_output_common(outlink);
360  if (err < 0)
361  return err;
362 
363  y->csp = av_pix_fmt_desc_get(vkctx->frames->sw_format);
365 
366  if (AV_CEIL_RSHIFT(outlink->w, y->csp->log2_chroma_w) < 4 || AV_CEIL_RSHIFT(outlink->h, y->csp->log2_chroma_h) < 4) {
367  av_log(avctx, AV_LOG_ERROR, "Video with planes less than 4 columns or lines is not supported\n");
368  return AVERROR(EINVAL);
369  }
370 
371  return init_filter(avctx);
372 }
373 
374 static const AVClass bwdif_vulkan_class = {
375  .class_name = "bwdif_vulkan",
376  .item_name = av_default_item_name,
377  .option = ff_yadif_options,
378  .version = LIBAVUTIL_VERSION_INT,
379  .category = AV_CLASS_CATEGORY_FILTER,
380 };
381 
383  {
384  .name = "default",
385  .type = AVMEDIA_TYPE_VIDEO,
386  .filter_frame = ff_yadif_filter_frame,
387  .config_props = &bwdif_vulkan_config_input,
388  },
389 };
390 
392  {
393  .name = "default",
394  .type = AVMEDIA_TYPE_VIDEO,
395  .request_frame = ff_yadif_request_frame,
396  .config_props = &bwdif_vulkan_config_output,
397  },
398 };
399 
401  .name = "bwdif_vulkan",
402  .description = NULL_IF_CONFIG_SMALL("Deinterlace Vulkan frames via bwdif"),
403  .priv_size = sizeof(BWDIFVulkanContext),
409  .priv_class = &bwdif_vulkan_class,
410  .flags = AVFILTER_FLAG_HWDEVICE |
412  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
413 };
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:1843
FFVulkanContext::output_height
int output_height
Definition: vulkan.h:265
mix
static int mix(int c0, int c1)
Definition: 4xm.c:715
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:351
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:197
ff_vf_bwdif_vulkan
const AVFilter ff_vf_bwdif_vulkan
Definition: vf_bwdif_vulkan.c:400
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:224
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
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
ff_vk_filter_init
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.
Definition: vulkan_filter.c:221
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:387
FFVulkanContext::class
const AVClass * class
Definition: vulkan.h:229
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:1414
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:472
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:1872
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:1464
ff_vk_shader_set_compute_sizes
void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z)
Definition: vulkan.c:1372
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
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:3002
ff_yadif_config_output_common
int ff_yadif_config_output_common(AVFilterLink *outlink)
Definition: yadif_common.c:218
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:1142
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:422
fail
#define fail()
Definition: checkasm.h:179
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:24
FFVulkanContext::frames_ref
AVBufferRef * frames_ref
Definition: vulkan.h:256
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
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:304
FFVulkanContext::output_width
int output_width
Definition: vulkan.h:264
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
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
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
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:255
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
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:210
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:59
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
fbs
#define fbs(width, name, subs,...)
Definition: cbs_av1.c:478
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:415
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:1784
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:295
FFVulkanContext
Definition: vulkan.h:228
bwdif_vulkan_config_output
static int bwdif_vulkan_config_output(AVFilterLink *outlink)
Definition: vf_bwdif_vulkan.c:336
FFVulkanPipeline
Definition: vulkan.h:131
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:271
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:1346
main
int main(int argc, char **argv)
Definition: avio_http_serve_files.c:99
yadif.h
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
FFVulkanDescriptorSetBinding
Definition: vulkan.h:83
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:110
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:266
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:255
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:172
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
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:73
fb
#define fb(width, name)
Definition: cbs_av1.c:593
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:1206
YADIFContext
Definition: yadif.h:51
vulkan_spirv.h
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
GLSLF
#define GLSLF(N, S,...)
Definition: vulkan.h:54
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:115
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:231
FFVkExecPool
Definition: vulkan.h:210
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:374
bwdif_vulkan_outputs
static const AVFilterPad bwdif_vulkan_outputs[]
Definition: vf_bwdif_vulkan.c:391
random_seed.h
FFVkSPIRVShader
Definition: vulkan.h:75
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:184
bwdif_vulkan_inputs
static const AVFilterPad bwdif_vulkan_inputs[]
Definition: vf_bwdif_vulkan.c:382
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
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:75
GLSLC
#define GLSLC(N, S)
Definition: vulkan.h:44
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFVulkanContext::hwctx
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:253
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:70
planes
static const struct @386 planes[]
ff_yadif_uninit
void ff_yadif_uninit(AVFilterContext *ctx)
Definition: yadif_common.c:256
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:183
ff_vk_init_sampler
int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, int unnorm_coords, VkFilter filt)
Create a sampler.
Definition: vulkan.c:1162
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:1578
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:257
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd)
Definition: vulkan.c:1405
BWDIFVulkanContext::sampler
VkSampler sampler
Definition: vf_bwdif_vulkan.c:37
RET
#define RET(x)
Definition: vulkan.h:67
FFVulkanFunctions
Definition: vulkan_functions.h:226
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
ff_yadif_filter_frame
int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
Definition: yadif_common.c:104
min
float min
Definition: vorbis_enc_data.h:429