FFmpeg
vf_overlay_vulkan.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/random_seed.h"
20 #include "libavutil/opt.h"
21 #include "vulkan.h"
22 #include "internal.h"
23 #include "framesync.h"
24 
25 #define CGROUPS (int [3]){ 32, 32, 1 }
26 
27 typedef struct OverlayVulkanContext {
29 
35 
36  /* Shader updators, must be in the main filter struct */
37  VkDescriptorImageInfo main_images[3];
38  VkDescriptorImageInfo overlay_images[3];
39  VkDescriptorImageInfo output_images[3];
40  VkDescriptorBufferInfo params_desc;
41 
42  int overlay_x;
43  int overlay_y;
44  int overlay_w;
45  int overlay_h;
47 
48 static const char overlay_noalpha[] = {
49  C(0, void overlay_noalpha(int i, ivec2 pos) )
50  C(0, { )
51  C(1, if ((o_offset[i].x <= pos.x) && (o_offset[i].y <= pos.y) &&
52  (pos.x < (o_offset[i].x + o_size[i].x)) &&
53  (pos.y < (o_offset[i].y + o_size[i].y))) { )
54  C(2, vec4 res = texture(overlay_img[i], pos - o_offset[i]); )
55  C(2, imageStore(output_img[i], pos, res); )
56  C(1, } else { )
57  C(2, vec4 res = texture(main_img[i], pos); )
58  C(2, imageStore(output_img[i], pos, res); )
59  C(1, } )
60  C(0, } )
61 };
62 
63 static const char overlay_alpha[] = {
64  C(0, void overlay_alpha_opaque(int i, ivec2 pos) )
65  C(0, { )
66  C(1, vec4 res = texture(main_img[i], pos); )
67  C(1, if ((o_offset[i].x <= pos.x) && (o_offset[i].y <= pos.y) &&
68  (pos.x < (o_offset[i].x + o_size[i].x)) &&
69  (pos.y < (o_offset[i].y + o_size[i].y))) { )
70  C(2, vec4 ovr = texture(overlay_img[i], pos - o_offset[i]); )
71  C(2, res = ovr * ovr.a + res * (1.0f - ovr.a); )
72  C(2, res.a = 1.0f; )
73  C(2, imageStore(output_img[i], pos, res); )
74  C(1, } )
75  C(1, imageStore(output_img[i], pos, res); )
76  C(0, } )
77 };
78 
80 {
81  int err;
82  OverlayVulkanContext *s = ctx->priv;
83  VkSampler *sampler = ff_vk_init_sampler(ctx, 1, VK_FILTER_NEAREST);
84  if (!sampler)
85  return AVERROR_EXTERNAL;
86 
87  s->pl = ff_vk_create_pipeline(ctx);
88  if (!s->pl)
89  return AVERROR(ENOMEM);
90 
92  s->vkctx.queue_count = GET_QUEUE_COUNT(s->vkctx.hwctx, 0, 1, 0);
94 
95  { /* Create the shader */
98 
99  VulkanDescriptorSetBinding desc_i[3] = {
100  {
101  .name = "main_img",
102  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
103  .dimensions = 2,
104  .elems = planes,
105  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
106  .updater = s->main_images,
107  .samplers = DUP_SAMPLER_ARRAY4(*sampler),
108  },
109  {
110  .name = "overlay_img",
111  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
112  .dimensions = 2,
113  .elems = planes,
114  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
115  .updater = s->overlay_images,
116  .samplers = DUP_SAMPLER_ARRAY4(*sampler),
117  },
118  {
119  .name = "output_img",
120  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
121  .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.output_format),
122  .mem_quali = "writeonly",
123  .dimensions = 2,
124  .elems = planes,
125  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
126  .updater = s->output_images,
127  },
128  };
129 
130  VulkanDescriptorSetBinding desc_b = {
131  .name = "params",
132  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
133  .mem_quali = "readonly",
134  .mem_layout = "std430",
135  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
136  .updater = &s->params_desc,
137  .buf_content = "ivec2 o_offset[3], o_size[3];",
138  };
139 
140  SPIRVShader *shd = ff_vk_init_shader(ctx, s->pl, "overlay_compute",
141  VK_SHADER_STAGE_COMPUTE_BIT);
142  if (!shd)
143  return AVERROR(ENOMEM);
144 
146 
147  RET(ff_vk_add_descriptor_set(ctx, s->pl, shd, desc_i, 3, 0)); /* set 0 */
148  RET(ff_vk_add_descriptor_set(ctx, s->pl, shd, &desc_b, 1, 0)); /* set 1 */
149 
151  GLSLD( overlay_alpha );
152  GLSLC(0, void main() );
153  GLSLC(0, { );
154  GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
155  GLSLF(1, int planes = %i; ,planes);
156  GLSLC(1, for (int i = 0; i < planes; i++) { );
157  if (ialpha)
158  GLSLC(2, overlay_alpha_opaque(i, pos); );
159  else
160  GLSLC(2, overlay_noalpha(i, pos); );
161  GLSLC(1, } );
162  GLSLC(0, } );
163 
164  RET(ff_vk_compile_shader(ctx, shd, "main"));
165  }
166 
169 
170  { /* Create and update buffer */
171  const AVPixFmtDescriptor *desc;
172 
173  /* NOTE: std430 requires the same identical struct layout, padding and
174  * alignment as C, so we're allowed to do this, as this will map
175  * exactly to what the shader recieves */
176  struct {
177  int32_t o_offset[2*3];
178  int32_t o_size[2*3];
179  } *par;
180 
181  err = ff_vk_create_buf(ctx, &s->params_buf,
182  sizeof(*par),
183  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
184  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
185  if (err)
186  return err;
187 
188  err = ff_vk_map_buffers(ctx, &s->params_buf, (uint8_t **)&par, 1, 0);
189  if (err)
190  return err;
191 
193 
194  par->o_offset[0] = s->overlay_x;
195  par->o_offset[1] = s->overlay_y;
196  par->o_offset[2] = par->o_offset[0] >> desc->log2_chroma_w;
197  par->o_offset[3] = par->o_offset[1] >> desc->log2_chroma_h;
198  par->o_offset[4] = par->o_offset[0] >> desc->log2_chroma_w;
199  par->o_offset[5] = par->o_offset[1] >> desc->log2_chroma_h;
200 
201  par->o_size[0] = s->overlay_w;
202  par->o_size[1] = s->overlay_h;
203  par->o_size[2] = par->o_size[0] >> desc->log2_chroma_w;
204  par->o_size[3] = par->o_size[1] >> desc->log2_chroma_h;
205  par->o_size[4] = par->o_size[0] >> desc->log2_chroma_w;
206  par->o_size[5] = par->o_size[1] >> desc->log2_chroma_h;
207 
208  err = ff_vk_unmap_buffers(ctx, &s->params_buf, 1, 1);
209  if (err)
210  return err;
211 
212  s->params_desc.buffer = s->params_buf.buf;
213  s->params_desc.range = VK_WHOLE_SIZE;
214 
215  ff_vk_update_descriptor_set(ctx, s->pl, 1);
216  }
217 
218  /* Execution context */
219  RET(ff_vk_create_exec_ctx(ctx, &s->exec));
220 
221  s->initialized = 1;
222 
223  return 0;
224 
225 fail:
226  return err;
227 }
228 
229 static int process_frames(AVFilterContext *avctx, AVFrame *out_f,
230  AVFrame *main_f, AVFrame *overlay_f)
231 {
232  int err;
233  VkCommandBuffer cmd_buf;
234  OverlayVulkanContext *s = avctx->priv;
236 
237  AVVkFrame *out = (AVVkFrame *)out_f->data[0];
238  AVVkFrame *main = (AVVkFrame *)main_f->data[0];
239  AVVkFrame *overlay = (AVVkFrame *)overlay_f->data[0];
240 
242  AVHWFramesContext *overlay_fc = (AVHWFramesContext*)overlay_f->hw_frames_ctx->data;
243 
244  /* Update descriptors and init the exec context */
245  ff_vk_start_exec_recording(avctx, s->exec);
246  cmd_buf = ff_vk_get_exec_buf(avctx, s->exec);
247 
248  for (int i = 0; i < planes; i++) {
249  RET(ff_vk_create_imageview(avctx, s->exec, &s->main_images[i].imageView,
250  main->img[i],
251  av_vkfmt_from_pixfmt(main_fc->sw_format)[i],
253 
254  RET(ff_vk_create_imageview(avctx, s->exec, &s->overlay_images[i].imageView,
255  overlay->img[i],
256  av_vkfmt_from_pixfmt(overlay_fc->sw_format)[i],
258 
259  RET(ff_vk_create_imageview(avctx, s->exec, &s->output_images[i].imageView,
260  out->img[i],
263 
264  s->main_images[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
265  s->overlay_images[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
266  s->output_images[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
267  }
268 
269  ff_vk_update_descriptor_set(avctx, s->pl, 0);
270 
271  for (int i = 0; i < planes; i++) {
272  VkImageMemoryBarrier bar[3] = {
273  {
274  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
275  .srcAccessMask = 0,
276  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
277  .oldLayout = main->layout[i],
278  .newLayout = s->main_images[i].imageLayout,
279  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
280  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
281  .image = main->img[i],
282  .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
283  .subresourceRange.levelCount = 1,
284  .subresourceRange.layerCount = 1,
285  },
286  {
287  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
288  .srcAccessMask = 0,
289  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
290  .oldLayout = overlay->layout[i],
291  .newLayout = s->overlay_images[i].imageLayout,
292  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
293  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
294  .image = overlay->img[i],
295  .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
296  .subresourceRange.levelCount = 1,
297  .subresourceRange.layerCount = 1,
298  },
299  {
300  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
301  .srcAccessMask = 0,
302  .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
303  .oldLayout = out->layout[i],
304  .newLayout = s->output_images[i].imageLayout,
305  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
306  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
307  .image = out->img[i],
308  .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
309  .subresourceRange.levelCount = 1,
310  .subresourceRange.layerCount = 1,
311  },
312  };
313 
314  vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
315  VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0,
316  0, NULL, 0, NULL, FF_ARRAY_ELEMS(bar), bar);
317 
318  main->layout[i] = bar[0].newLayout;
319  main->access[i] = bar[0].dstAccessMask;
320 
321  overlay->layout[i] = bar[1].newLayout;
322  overlay->access[i] = bar[1].dstAccessMask;
323 
324  out->layout[i] = bar[2].newLayout;
325  out->access[i] = bar[2].dstAccessMask;
326  }
327 
328  ff_vk_bind_pipeline_exec(avctx, s->exec, s->pl);
329 
330  vkCmdDispatch(cmd_buf,
332  FFALIGN(s->vkctx.output_height, CGROUPS[1])/CGROUPS[1], 1);
333 
334  ff_vk_add_exec_dep(avctx, s->exec, main_f, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
335  ff_vk_add_exec_dep(avctx, s->exec, overlay_f, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
336  ff_vk_add_exec_dep(avctx, s->exec, out_f, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
337 
338  err = ff_vk_submit_exec_queue(avctx, s->exec);
339  if (err)
340  return err;
341 
342  return err;
343 
344 fail:
345  ff_vk_discard_exec_deps(avctx, s->exec);
346  return err;
347 }
348 
350 {
351  int err;
352  AVFilterContext *ctx = fs->parent;
353  OverlayVulkanContext *s = ctx->priv;
354  AVFilterLink *outlink = ctx->outputs[0];
355  AVFrame *input_main, *input_overlay, *out;
356 
357  err = ff_framesync_get_frame(fs, 0, &input_main, 0);
358  if (err < 0)
359  goto fail;
360  err = ff_framesync_get_frame(fs, 1, &input_overlay, 0);
361  if (err < 0)
362  goto fail;
363 
364  if (!input_main || !input_overlay)
365  return 0;
366 
367  if (!s->initialized) {
368  AVHWFramesContext *main_fc = (AVHWFramesContext*)input_main->hw_frames_ctx->data;
369  AVHWFramesContext *overlay_fc = (AVHWFramesContext*)input_overlay->hw_frames_ctx->data;
370  if (main_fc->sw_format != overlay_fc->sw_format) {
371  av_log(ctx, AV_LOG_ERROR, "Mismatching sw formats!\n");
372  return AVERROR(EINVAL);
373  }
374 
375  s->overlay_w = input_overlay->width;
376  s->overlay_h = input_overlay->height;
377 
378  RET(init_filter(ctx));
379  }
380 
381  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
382  if (!out) {
383  err = AVERROR(ENOMEM);
384  goto fail;
385  }
386 
387  RET(process_frames(ctx, out, input_main, input_overlay));
388 
389  err = av_frame_copy_props(out, input_main);
390  if (err < 0)
391  goto fail;
392 
393  return ff_filter_frame(outlink, out);
394 
395 fail:
396  av_frame_free(&out);
397  return err;
398 }
399 
401 {
402  int err;
403  AVFilterContext *avctx = outlink->src;
404  OverlayVulkanContext *s = avctx->priv;
405 
406  err = ff_vk_filter_config_output(outlink);
407  if (err < 0)
408  return err;
409 
410  err = ff_framesync_init_dualinput(&s->fs, avctx);
411  if (err < 0)
412  return err;
413 
414  return ff_framesync_configure(&s->fs);
415 }
416 
418 {
419  OverlayVulkanContext *s = avctx->priv;
420 
421  return ff_framesync_activate(&s->fs);
422 }
423 
425 {
426  OverlayVulkanContext *s = avctx->priv;
427 
429 
430  return ff_vk_filter_init(avctx);
431 }
432 
434 {
435  OverlayVulkanContext *s = avctx->priv;
436 
437  ff_vk_filter_uninit(avctx);
438  ff_framesync_uninit(&s->fs);
439 
440  ff_vk_free_buf(avctx, &s->params_buf);
441 
442  s->initialized = 0;
443 }
444 
445 #define OFFSET(x) offsetof(OverlayVulkanContext, x)
446 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
448  { "x", "Set horizontal offset", OFFSET(overlay_x), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },
449  { "y", "Set vertical offset", OFFSET(overlay_y), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },
450  { NULL },
451 };
452 
453 AVFILTER_DEFINE_CLASS(overlay_vulkan);
454 
456  {
457  .name = "main",
458  .type = AVMEDIA_TYPE_VIDEO,
459  .config_props = &ff_vk_filter_config_input,
460  },
461  {
462  .name = "overlay",
463  .type = AVMEDIA_TYPE_VIDEO,
464  .config_props = &ff_vk_filter_config_input,
465  },
466  { NULL }
467 };
468 
470  {
471  .name = "default",
472  .type = AVMEDIA_TYPE_VIDEO,
473  .config_props = &overlay_vulkan_config_output,
474  },
475  { NULL }
476 };
477 
479  .name = "overlay_vulkan",
480  .description = NULL_IF_CONFIG_SMALL("Overlay a source on top of another"),
481  .priv_size = sizeof(OverlayVulkanContext),
486  .inputs = overlay_vulkan_inputs,
487  .outputs = overlay_vulkan_outputs,
488  .priv_class = &overlay_vulkan_class,
489  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
490 };
static int overlay_vulkan_config_output(AVFilterLink *outlink)
#define NULL
Definition: coverity.c:32
int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e, AVFrame *frame, VkPipelineStageFlagBits in_wait_dst_flag)
Adds a frame as a queue dependency.
Definition: vulkan.c:464
#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:369
VulkanPipeline * pl
VkBuffer buf
Definition: vulkan.h:87
int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl)
Initializes the pipeline layout after all shaders and descriptor sets have been finished.
Definition: vulkan.c:1180
static const AVFilterPad overlay_vulkan_outputs[]
int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, SPIRVShader *shd, VulkanDescriptorSetBinding *desc, int num, int only_print_to_shader)
Adds a descriptor set to the shader and registers them in the pipeline.
Definition: vulkan.c:1020
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
This structure describes decoded (raw) audio or video data.
Definition: frame.h:308
void ff_vk_filter_uninit(AVFilterContext *avctx)
Definition: vulkan.c:1415
AVOption.
Definition: opt.h:248
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt)
Gets the glsl format string for a pixel format.
Definition: vulkan.c:817
const char * name
Definition: vulkan.h:74
FFVkExecContext * exec
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
const char * desc
Definition: nvenc.c:87
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int ff_vk_init_compute_pipeline(AVFilterContext *avctx, VulkanPipeline *pl)
Initializes a compute pipeline.
Definition: vulkan.c:1281
int ff_vk_create_imageview(AVFilterContext *avctx, FFVkExecContext *e, VkImageView *v, VkImage img, VkFormat fmt, const VkComponentMapping map)
Create an imageview.
Definition: vulkan.c:836
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan.c:705
int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e)
Begin recording to the command buffer.
Definition: vulkan.c:417
VkDescriptorImageInfo output_images[3]
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:124
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
const VkFormat * av_vkfmt_from_pixfmt(enum AVPixelFormat p)
Returns the format of each image up to the number of planes for a given sw_format.
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
Definition: frame.h:647
const char * name
Pad name.
Definition: internal.h:60
AVFilterContext * parent
Parent filter context.
Definition: framesync.h:152
#define FLAGS
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1091
uint8_t
#define av_cold
Definition: attributes.h:88
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:177
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AVOptions.
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:358
filter_frame For filters that do not use the activate() callback
void ff_vk_set_compute_shader_sizes(AVFilterContext *avctx, SPIRVShader *shd, int local_size[3])
Writes the workgroup size for a shader.
Definition: vulkan.c:909
static int overlay_vulkan_blend(FFFrameSync *fs)
int queue_family_comp_index
Queue family index for compute ops, and the amount of queues enabled.
int ff_vk_filter_init(AVFilterContext *avctx)
Definition: vulkan.c:756
static const AVOption overlay_vulkan_options[]
VulkanFilterContext vkctx
static int process_frames(AVFilterContext *avctx, AVFrame *out_f, AVFrame *main_f, AVFrame *overlay_f)
#define OFFSET(x)
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
int ff_vk_unmap_buffers(AVFilterContext *avctx, FFVkBuffer *buf, int nb_buffers, int flush)
Unmaps the buffer from userspace.
Definition: vulkan.c:264
int ff_vk_filter_query_formats(AVFilterContext *avctx)
General lavfi IO functions.
Definition: vulkan.c:592
enum AVPixelFormat input_format
Definition: vulkan.h:176
int width
Definition: frame.h:366
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:290
Frame sync structure.
Definition: framesync.h:146
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
void * priv
private data for use by the filter
Definition: avfilter.h:353
unsigned int pos
Definition: spdifenc.c:410
int ff_vk_create_buf(AVFilterContext *avctx, FFVkBuffer *buf, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Create a VkBuffer with the specified parameters.
Definition: vulkan.c:150
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter&#39;s input and try to produce output.
Definition: framesync.c:341
int(* on_event)(struct FFFrameSync *fs)
Callback called when a frame event is ready.
Definition: framesync.h:172
#define fail()
Definition: checkasm.h:123
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
static av_cold int overlay_vulkan_init(AVFilterContext *avctx)
VkSampler * ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords, VkFilter filt)
Create a Vulkan sampler, will be auto-freed in ff_vk_filter_uninit()
Definition: vulkan.c:769
int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx)
Init an execution context for command recording and queue submission.
Definition: vulkan.c:339
static const AVFilterPad overlay_vulkan_inputs[]
static av_cold int init_filter(AVFilterContext *ctx)
VkAccessFlagBits access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e)
Submits a command buffer to the queue for execution.
Definition: vulkan.c:522
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
#define GLSLF(N, S,...)
Definition: vulkan.h:40
#define s(width, name)
Definition: cbs_vp9.c:257
void ff_vk_free_buf(AVFilterContext *avctx, FFVkBuffer *buf)
Frees a buffer.
Definition: vulkan.c:306
VkDescriptorBufferInfo params_desc
int main(int argc, char *argv[])
#define GLSLC(N, S)
Definition: vulkan.h:38
void ff_vk_bind_pipeline_exec(AVFilterContext *avctx, FFVkExecContext *e, VulkanPipeline *pl)
Add a command to bind the completed pipeline and its descriptor sets.
Definition: vulkan.c:1316
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define FF_ARRAY_ELEMS(a)
static const struct @316 planes[]
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
VkDescriptorImageInfo overlay_images[3]
const VkComponentMapping ff_comp_identity_map
Definition: vulkan.c:44
#define CGROUPS
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
int ff_vk_compile_shader(AVFilterContext *avctx, SPIRVShader *shd, const char *entrypoint)
Compiles the shader, entrypoint must be set to "main".
Definition: vulkan.c:942
uint8_t * data
The data buffer.
Definition: buffer.h:89
SPIRVShader * ff_vk_init_shader(AVFilterContext *avctx, VulkanPipeline *pl, const char *name, VkShaderStageFlags stage)
Inits a shader for a specific pipeline.
Definition: vulkan.c:888
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:165
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Filter definition.
Definition: avfilter.h:144
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
VulkanPipeline * ff_vk_create_pipeline(AVFilterContext *avctx)
Inits a pipeline.
Definition: vulkan.c:1276
const char * name
Filter name.
Definition: avfilter.h:148
VkCommandBuffer ff_vk_get_exec_buf(AVFilterContext *avctx, FFVkExecContext *e)
Gets the command buffer to use for this submission from the exe context.
Definition: vulkan.c:458
#define GET_QUEUE_COUNT(hwctx, graph, comp, tx)
Definition: vulkan.h:53
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
void ff_vk_discard_exec_deps(AVFilterContext *avctx, FFVkExecContext *e)
Discards all queue dependencies.
Definition: vulkan.c:400
static void overlay_vulkan_uninit(AVFilterContext *avctx)
AVFilter ff_vf_overlay_vulkan
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:322
static int query_formats(AVFilterContext *ctx)
Definition: aeval.c:244
static const char overlay_alpha[]
AVFILTER_DEFINE_CLASS(overlay_vulkan)
enum AVPixelFormat output_format
Definition: vulkan.h:175
int ff_vk_map_buffers(AVFilterContext *avctx, FFVkBuffer *buf, uint8_t *mem[], int nb_buffers, int invalidate)
Maps the buffer to userspace.
Definition: vulkan.c:215
#define GLSLD(D)
Definition: vulkan.h:41
VkDescriptorImageInfo main_images[3]
int ff_vk_filter_config_input(AVFilterLink *inlink)
Definition: vulkan.c:635
An instance of a filter.
Definition: avfilter.h:338
VkImageLayout layout[AV_NUM_DATA_POINTERS]
#define RET(x)
Definition: vulkan.h:46
int height
Definition: frame.h:366
FILE * out
Definition: movenc.c:54
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:120
#define DUP_SAMPLER_ARRAY4(x)
Definition: vulkan.h:64
internal API functions
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
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition: framesync.c:253
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:222
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
static const char overlay_noalpha[]
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:659
int i
Definition: input.c:406
static int overlay_vulkan_activate(AVFilterContext *avctx)
void ff_vk_update_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, int set_id)
Updates a descriptor set via the updaters defined.
Definition: vulkan.c:1160