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_filter.h"
22 #include "internal.h"
23 #include "framesync.h"
24 
25 #define CGROUPS (int [3]){ 32, 32, 1 }
26 
27 typedef struct OverlayVulkanContext {
29 
36 
37  /* Shader updators, must be in the main filter struct */
38  VkDescriptorImageInfo main_images[3];
39  VkDescriptorImageInfo overlay_images[3];
40  VkDescriptorImageInfo output_images[3];
41  VkDescriptorBufferInfo params_desc;
42 
43  int overlay_x;
44  int overlay_y;
45  int overlay_w;
46  int overlay_h;
48 
49 static const char overlay_noalpha[] = {
50  C(0, void overlay_noalpha(int i, ivec2 pos) )
51  C(0, { )
52  C(1, if ((o_offset[i].x <= pos.x) && (o_offset[i].y <= pos.y) &&
53  (pos.x < (o_offset[i].x + o_size[i].x)) &&
54  (pos.y < (o_offset[i].y + o_size[i].y))) { )
55  C(2, vec4 res = texture(overlay_img[i], pos - o_offset[i]); )
56  C(2, imageStore(output_img[i], pos, res); )
57  C(1, } else { )
58  C(2, vec4 res = texture(main_img[i], pos); )
59  C(2, imageStore(output_img[i], pos, res); )
60  C(1, } )
61  C(0, } )
62 };
63 
64 static const char overlay_alpha[] = {
65  C(0, void overlay_alpha_opaque(int i, ivec2 pos) )
66  C(0, { )
67  C(1, vec4 res = texture(main_img[i], pos); )
68  C(1, if ((o_offset[i].x <= pos.x) && (o_offset[i].y <= pos.y) &&
69  (pos.x < (o_offset[i].x + o_size[i].x)) &&
70  (pos.y < (o_offset[i].y + o_size[i].y))) { )
71  C(2, vec4 ovr = texture(overlay_img[i], pos - o_offset[i]); )
72  C(2, res = ovr * ovr.a + res * (1.0f - ovr.a); )
73  C(2, res.a = 1.0f; )
74  C(2, imageStore(output_img[i], pos, res); )
75  C(1, } )
76  C(1, imageStore(output_img[i], pos, res); )
77  C(0, } )
78 };
79 
81 {
82  int err;
83  FFVkSampler *sampler;
84  OverlayVulkanContext *s = ctx->priv;
85  FFVulkanContext *vkctx = &s->vkctx;
86  const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
87 
88  ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT, 0);
89 
90  sampler = ff_vk_init_sampler(vkctx, 1, VK_FILTER_NEAREST);
91  if (!sampler)
92  return AVERROR_EXTERNAL;
93 
94  s->pl = ff_vk_create_pipeline(vkctx, &s->qf);
95  if (!s->pl)
96  return AVERROR(ENOMEM);
97 
98  { /* Create the shader */
99  const int ialpha = av_pix_fmt_desc_get(s->vkctx.input_format)->flags & AV_PIX_FMT_FLAG_ALPHA;
100 
101  FFVulkanDescriptorSetBinding desc_i[3] = {
102  {
103  .name = "main_img",
104  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
105  .dimensions = 2,
106  .elems = planes,
107  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
108  .updater = s->main_images,
109  .sampler = sampler,
110  },
111  {
112  .name = "overlay_img",
113  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
114  .dimensions = 2,
115  .elems = planes,
116  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
117  .updater = s->overlay_images,
118  .sampler = sampler,
119  },
120  {
121  .name = "output_img",
122  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
123  .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.output_format),
124  .mem_quali = "writeonly",
125  .dimensions = 2,
126  .elems = planes,
127  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
128  .updater = s->output_images,
129  },
130  };
131 
133  .name = "params",
134  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
135  .mem_quali = "readonly",
136  .mem_layout = "std430",
137  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
138  .updater = &s->params_desc,
139  .buf_content = "ivec2 o_offset[3], o_size[3];",
140  };
141 
142  FFVkSPIRVShader *shd = ff_vk_init_shader(s->pl, "overlay_compute",
143  VK_SHADER_STAGE_COMPUTE_BIT);
144  if (!shd)
145  return AVERROR(ENOMEM);
146 
148 
149  RET(ff_vk_add_descriptor_set(vkctx, s->pl, shd, desc_i, FF_ARRAY_ELEMS(desc_i), 0)); /* set 0 */
150  RET(ff_vk_add_descriptor_set(vkctx, s->pl, shd, &desc_b, 1, 0)); /* set 1 */
151 
153  GLSLD( overlay_alpha );
154  GLSLC(0, void main() );
155  GLSLC(0, { );
156  GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
157  GLSLF(1, int planes = %i; ,planes);
158  GLSLC(1, for (int i = 0; i < planes; i++) { );
159  if (ialpha)
160  GLSLC(2, overlay_alpha_opaque(i, pos); );
161  else
162  GLSLC(2, overlay_noalpha(i, pos); );
163  GLSLC(1, } );
164  GLSLC(0, } );
165 
166  RET(ff_vk_compile_shader(vkctx, shd, "main"));
167  }
168 
169  RET(ff_vk_init_pipeline_layout(vkctx, s->pl));
170  RET(ff_vk_init_compute_pipeline(vkctx, s->pl));
171 
172  { /* Create and update buffer */
173  const AVPixFmtDescriptor *desc;
174 
175  /* NOTE: std430 requires the same identical struct layout, padding and
176  * alignment as C, so we're allowed to do this, as this will map
177  * exactly to what the shader recieves */
178  struct {
179  int32_t o_offset[2*3];
180  int32_t o_size[2*3];
181  } *par;
182 
183  err = ff_vk_create_buf(vkctx, &s->params_buf,
184  sizeof(*par),
185  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
186  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
187  if (err)
188  return err;
189 
190  err = ff_vk_map_buffers(vkctx, &s->params_buf, (uint8_t **)&par, 1, 0);
191  if (err)
192  return err;
193 
194  desc = av_pix_fmt_desc_get(s->vkctx.output_format);
195 
196  par->o_offset[0] = s->overlay_x;
197  par->o_offset[1] = s->overlay_y;
198  par->o_offset[2] = par->o_offset[0] >> desc->log2_chroma_w;
199  par->o_offset[3] = par->o_offset[1] >> desc->log2_chroma_h;
200  par->o_offset[4] = par->o_offset[0] >> desc->log2_chroma_w;
201  par->o_offset[5] = par->o_offset[1] >> desc->log2_chroma_h;
202 
203  par->o_size[0] = s->overlay_w;
204  par->o_size[1] = s->overlay_h;
205  par->o_size[2] = par->o_size[0] >> desc->log2_chroma_w;
206  par->o_size[3] = par->o_size[1] >> desc->log2_chroma_h;
207  par->o_size[4] = par->o_size[0] >> desc->log2_chroma_w;
208  par->o_size[5] = par->o_size[1] >> desc->log2_chroma_h;
209 
210  err = ff_vk_unmap_buffers(vkctx, &s->params_buf, 1, 1);
211  if (err)
212  return err;
213 
214  s->params_desc.buffer = s->params_buf.buf;
215  s->params_desc.range = VK_WHOLE_SIZE;
216 
217  ff_vk_update_descriptor_set(vkctx, s->pl, 1);
218  }
219 
220  /* Execution context */
221  RET(ff_vk_create_exec_ctx(vkctx, &s->exec, &s->qf));
222 
223  s->initialized = 1;
224 
225  return 0;
226 
227 fail:
228  return err;
229 }
230 
231 static int process_frames(AVFilterContext *avctx, AVFrame *out_f,
232  AVFrame *main_f, AVFrame *overlay_f)
233 {
234  int err;
235  VkCommandBuffer cmd_buf;
236  OverlayVulkanContext *s = avctx->priv;
237  FFVulkanContext *vkctx = &s->vkctx;
238  FFVulkanFunctions *vk = &vkctx->vkfn;
239  int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
240 
241  AVVkFrame *out = (AVVkFrame *)out_f->data[0];
242  AVVkFrame *main = (AVVkFrame *)main_f->data[0];
243  AVVkFrame *overlay = (AVVkFrame *)overlay_f->data[0];
244 
246  AVHWFramesContext *overlay_fc = (AVHWFramesContext*)overlay_f->hw_frames_ctx->data;
247 
248  const VkFormat *output_formats = av_vkfmt_from_pixfmt(s->vkctx.output_format);
249  const VkFormat *main_sw_formats = av_vkfmt_from_pixfmt(main_fc->sw_format);
250  const VkFormat *overlay_sw_formats = av_vkfmt_from_pixfmt(overlay_fc->sw_format);
251 
252  /* Update descriptors and init the exec context */
253  ff_vk_start_exec_recording(vkctx, s->exec);
254  cmd_buf = ff_vk_get_exec_buf(s->exec);
255 
256  for (int i = 0; i < planes; i++) {
257  RET(ff_vk_create_imageview(vkctx, s->exec,
258  &s->main_images[i].imageView, main->img[i],
259  main_sw_formats[i],
261 
262  RET(ff_vk_create_imageview(vkctx, s->exec,
263  &s->overlay_images[i].imageView, overlay->img[i],
264  overlay_sw_formats[i],
266 
267  RET(ff_vk_create_imageview(vkctx, s->exec,
268  &s->output_images[i].imageView, out->img[i],
269  output_formats[i],
271 
272  s->main_images[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
273  s->overlay_images[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
274  s->output_images[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
275  }
276 
277  ff_vk_update_descriptor_set(vkctx, s->pl, 0);
278 
279  for (int i = 0; i < planes; i++) {
280  VkImageMemoryBarrier bar[3] = {
281  {
282  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
283  .srcAccessMask = 0,
284  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
285  .oldLayout = main->layout[i],
286  .newLayout = s->main_images[i].imageLayout,
287  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
288  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
289  .image = main->img[i],
290  .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
291  .subresourceRange.levelCount = 1,
292  .subresourceRange.layerCount = 1,
293  },
294  {
295  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
296  .srcAccessMask = 0,
297  .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
298  .oldLayout = overlay->layout[i],
299  .newLayout = s->overlay_images[i].imageLayout,
300  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
301  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
302  .image = overlay->img[i],
303  .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
304  .subresourceRange.levelCount = 1,
305  .subresourceRange.layerCount = 1,
306  },
307  {
308  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
309  .srcAccessMask = 0,
310  .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
311  .oldLayout = out->layout[i],
312  .newLayout = s->output_images[i].imageLayout,
313  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
314  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
315  .image = out->img[i],
316  .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
317  .subresourceRange.levelCount = 1,
318  .subresourceRange.layerCount = 1,
319  },
320  };
321 
322  vk->CmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
323  VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0,
324  0, NULL, 0, NULL, FF_ARRAY_ELEMS(bar), bar);
325 
326  main->layout[i] = bar[0].newLayout;
327  main->access[i] = bar[0].dstAccessMask;
328 
329  overlay->layout[i] = bar[1].newLayout;
330  overlay->access[i] = bar[1].dstAccessMask;
331 
332  out->layout[i] = bar[2].newLayout;
333  out->access[i] = bar[2].dstAccessMask;
334  }
335 
336  ff_vk_bind_pipeline_exec(vkctx, s->exec, s->pl);
337 
338  vk->CmdDispatch(cmd_buf,
339  FFALIGN(s->vkctx.output_width, CGROUPS[0])/CGROUPS[0],
340  FFALIGN(s->vkctx.output_height, CGROUPS[1])/CGROUPS[1], 1);
341 
342  ff_vk_add_exec_dep(vkctx, s->exec, main_f, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
343  ff_vk_add_exec_dep(vkctx, s->exec, overlay_f, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
344  ff_vk_add_exec_dep(vkctx, s->exec, out_f, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
345 
346  err = ff_vk_submit_exec_queue(vkctx, s->exec);
347  if (err)
348  return err;
349 
350  ff_vk_qf_rotate(&s->qf);
351 
352  return err;
353 
354 fail:
355  ff_vk_discard_exec_deps(s->exec);
356  return err;
357 }
358 
360 {
361  int err;
362  AVFilterContext *ctx = fs->parent;
363  OverlayVulkanContext *s = ctx->priv;
364  AVFilterLink *outlink = ctx->outputs[0];
365  AVFrame *input_main, *input_overlay, *out;
366 
367  err = ff_framesync_get_frame(fs, 0, &input_main, 0);
368  if (err < 0)
369  goto fail;
370  err = ff_framesync_get_frame(fs, 1, &input_overlay, 0);
371  if (err < 0)
372  goto fail;
373 
374  if (!input_main || !input_overlay)
375  return 0;
376 
377  if (!s->initialized) {
378  AVHWFramesContext *main_fc = (AVHWFramesContext*)input_main->hw_frames_ctx->data;
379  AVHWFramesContext *overlay_fc = (AVHWFramesContext*)input_overlay->hw_frames_ctx->data;
380  if (main_fc->sw_format != overlay_fc->sw_format) {
381  av_log(ctx, AV_LOG_ERROR, "Mismatching sw formats!\n");
382  return AVERROR(EINVAL);
383  }
384 
385  s->overlay_w = input_overlay->width;
386  s->overlay_h = input_overlay->height;
387 
388  RET(init_filter(ctx));
389  }
390 
391  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
392  if (!out) {
393  err = AVERROR(ENOMEM);
394  goto fail;
395  }
396 
397  RET(process_frames(ctx, out, input_main, input_overlay));
398 
399  err = av_frame_copy_props(out, input_main);
400  if (err < 0)
401  goto fail;
402 
403  return ff_filter_frame(outlink, out);
404 
405 fail:
406  av_frame_free(&out);
407  return err;
408 }
409 
411 {
412  int err;
413  AVFilterContext *avctx = outlink->src;
414  OverlayVulkanContext *s = avctx->priv;
415 
416  err = ff_vk_filter_config_output(outlink);
417  if (err < 0)
418  return err;
419 
420  err = ff_framesync_init_dualinput(&s->fs, avctx);
421  if (err < 0)
422  return err;
423 
424  return ff_framesync_configure(&s->fs);
425 }
426 
428 {
429  OverlayVulkanContext *s = avctx->priv;
430 
431  return ff_framesync_activate(&s->fs);
432 }
433 
435 {
436  OverlayVulkanContext *s = avctx->priv;
437 
438  s->fs.on_event = &overlay_vulkan_blend;
439 
440  return ff_vk_filter_init(avctx);
441 }
442 
444 {
445  OverlayVulkanContext *s = avctx->priv;
446 
447  ff_vk_free_buf(&s->vkctx, &s->params_buf);
448  ff_vk_uninit(&s->vkctx);
449  ff_framesync_uninit(&s->fs);
450 
451  s->initialized = 0;
452 }
453 
454 #define OFFSET(x) offsetof(OverlayVulkanContext, x)
455 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
457  { "x", "Set horizontal offset", OFFSET(overlay_x), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },
458  { "y", "Set vertical offset", OFFSET(overlay_y), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },
459  { NULL },
460 };
461 
462 AVFILTER_DEFINE_CLASS(overlay_vulkan);
463 
465  {
466  .name = "main",
467  .type = AVMEDIA_TYPE_VIDEO,
468  .config_props = &ff_vk_filter_config_input,
469  },
470  {
471  .name = "overlay",
472  .type = AVMEDIA_TYPE_VIDEO,
473  .config_props = &ff_vk_filter_config_input,
474  },
475 };
476 
478  {
479  .name = "default",
480  .type = AVMEDIA_TYPE_VIDEO,
481  .config_props = &overlay_vulkan_config_output,
482  },
483 };
484 
486  .name = "overlay_vulkan",
487  .description = NULL_IF_CONFIG_SMALL("Overlay a source on top of another"),
488  .priv_size = sizeof(OverlayVulkanContext),
495  .priv_class = &overlay_vulkan_class,
496  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
497 };
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:101
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:134
OverlayVulkanContext::params_desc
VkDescriptorBufferInfo params_desc
Definition: vf_overlay_vulkan.c:41
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_comp_identity_map
const VkComponentMapping ff_comp_identity_map
Definition: vulkan.c:51
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:304
out
FILE * out
Definition: movenc.c:54
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:370
ff_vk_create_buf
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Create a VkBuffer with the specified parameters.
Definition: vulkan.c:193
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1009
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2858
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
ff_framesync_get_frame
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition: framesync.c:267
overlay_noalpha
static const char overlay_noalpha[]
Definition: vf_overlay_vulkan.c:49
ff_vk_bind_pipeline_exec
void ff_vk_bind_pipeline_exec(FFVulkanContext *s, FFVkExecContext *e, FFVulkanPipeline *pl)
Add a command to bind the completed pipeline and its descriptor sets.
Definition: vulkan.c:1264
OverlayVulkanContext::params_buf
FFVkBuffer params_buf
Definition: vf_overlay_vulkan.c:35
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:116
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
AVFrame::width
int width
Definition: frame.h:397
ff_vk_filter_init
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.
Definition: vulkan_filter.c:184
AVOption
AVOption.
Definition: opt.h:251
overlay_vulkan_activate
static int overlay_vulkan_activate(AVFilterContext *avctx)
Definition: vf_overlay_vulkan.c:427
ff_vk_compile_shader
int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, const char *entrypoint)
Compiles the shader, entrypoint must be set to "main".
Definition: vulkan.c:849
overlay_vulkan_config_output
static int overlay_vulkan_config_output(AVFilterLink *outlink)
Definition: vf_overlay_vulkan.c:410
overlay_vulkan_outputs
static const AVFilterPad overlay_vulkan_outputs[]
Definition: vf_overlay_vulkan.c:477
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees the main Vulkan context.
Definition: vulkan.c:1379
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:175
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
overlay_vulkan_blend
static int overlay_vulkan_blend(FFFrameSync *fs)
Definition: vf_overlay_vulkan.c:359
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:376
FFVkSampler
Definition: vulkan.h:74
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:346
ff_vk_add_exec_dep
int ff_vk_add_exec_dep(FFVulkanContext *s, FFVkExecContext *e, AVFrame *frame, VkPipelineStageFlagBits in_wait_dst_flag)
Adds a frame as a queue dependency.
Definition: vulkan.c:509
OverlayVulkanContext::exec
FFVkExecContext * exec
Definition: vf_overlay_vulkan.c:32
ff_vk_get_exec_buf
VkCommandBuffer ff_vk_get_exec_buf(FFVkExecContext *e)
Gets the command buffer to use for this submission from the exe context.
Definition: vulkan.c:504
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2898
AVVkFrame::img
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Definition: hwcontext_vulkan.h:217
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:430
fail
#define fail()
Definition: checkasm.h:134
vulkan_filter.h
ff_vf_overlay_vulkan
const AVFilter ff_vf_overlay_vulkan
Definition: vf_overlay_vulkan.c:485
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
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
ff_vk_qf_init
void ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf, VkQueueFlagBits dev_family, int nb_queues)
Initialize a queue family with a specific number of queues.
Definition: vulkan.c:96
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
ff_vk_create_imageview
int ff_vk_create_imageview(FFVulkanContext *s, FFVkExecContext *e, VkImageView *v, VkImage img, VkFormat fmt, const VkComponentMapping map)
Create an imageview.
Definition: vulkan.c:742
OverlayVulkanContext::overlay_x
int overlay_x
Definition: vf_overlay_vulkan.c:43
s
#define s(width, name)
Definition: cbs_vp9.c:256
FLAGS
#define FLAGS
Definition: vf_overlay_vulkan.c:455
OverlayVulkanContext::overlay_images
VkDescriptorImageInfo overlay_images[3]
Definition: vf_overlay_vulkan.c:39
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:363
ff_vk_init_shader
FFVkSPIRVShader * ff_vk_init_shader(FFVulkanPipeline *pl, const char *name, VkShaderStageFlags stage)
Inits a shader for a specific pipeline.
Definition: vulkan.c:795
AV_PIX_FMT_FLAG_ALPHA
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:147
ctx
AVFormatContext * ctx
Definition: movenc.c:48
process_frames
static int process_frames(AVFilterContext *avctx, AVFrame *out_f, AVFrame *main_f, AVFrame *overlay_f)
Definition: vf_overlay_vulkan.c:231
overlay_vulkan_options
static const AVOption overlay_vulkan_options[]
Definition: vf_overlay_vulkan.c:456
OFFSET
#define OFFSET(x)
Definition: vf_overlay_vulkan.c:454
planes
static const struct @345 planes[]
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:190
ff_vk_update_descriptor_set
void ff_vk_update_descriptor_set(FFVulkanContext *s, FFVulkanPipeline *pl, int set_id)
Updates a descriptor set via the updaters defined.
Definition: vulkan.c:1080
ff_vk_start_exec_recording
int ff_vk_start_exec_recording(FFVulkanContext *s, FFVkExecContext *e)
Begin recording to the command buffer.
Definition: vulkan.c:463
init_filter
static av_cold int init_filter(AVFilterContext *ctx)
Definition: vf_overlay_vulkan.c:80
main
int main(int argc, char *argv[])
Definition: avio_list_dir.c:112
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_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:603
GLSLD
#define GLSLD(D)
Definition: vulkan.h:47
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:258
overlay_vulkan_inputs
static const AVFilterPad overlay_vulkan_inputs[]
Definition: vf_overlay_vulkan.c:464
OverlayVulkanContext::overlay_w
int overlay_w
Definition: vf_overlay_vulkan.c:45
activate
filter_frame For filters that do not use the activate() callback
ff_vk_create_exec_ctx
int ff_vk_create_exec_ctx(FFVulkanContext *s, FFVkExecContext **ctx, FFVkQueueFamilyCtx *qf)
Init an execution context for command recording and queue submission.
Definition: vulkan.c:385
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:133
ff_vk_qf_rotate
void ff_vk_qf_rotate(FFVkQueueFamilyCtx *qf)
Rotate through the queues in a queue family.
Definition: vulkan.c:132
FFVulkanContext
Definition: vulkan.h:188
OverlayVulkanContext::main_images
VkDescriptorImageInfo main_images[3]
Definition: vf_overlay_vulkan.c:38
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
FFVulkanPipeline
Definition: vulkan.h:104
ff_vk_discard_exec_deps
void ff_vk_discard_exec_deps(FFVkExecContext *e)
Discards all queue dependencies.
Definition: vulkan.c:447
overlay_vulkan_init
static av_cold int overlay_vulkan_init(AVFilterContext *avctx)
Definition: vf_overlay_vulkan.c:434
ff_vk_unmap_buffers
int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer *buf, int nb_buffers, int flush)
Unmaps the buffer from userspace.
Definition: vulkan.c:307
AVVkFrame::access
VkAccessFlagBits access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
Definition: hwcontext_vulkan.h:240
FFVulkanDescriptorSetBinding
Definition: vulkan.h:78
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:115
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:372
AVVkFrame
Definition: hwcontext_vulkan.h:213
ff_vk_init_pipeline_layout
int ff_vk_init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl)
Initializes the pipeline layout after all shaders and descriptor sets have been finished.
Definition: vulkan.c:1116
FFVkQueueFamilyCtx
Definition: vulkan.h:97
OverlayVulkanContext
Definition: vf_overlay_vulkan.c:27
ff_vk_submit_exec_queue
int ff_vk_submit_exec_queue(FFVulkanContext *s, FFVkExecContext *e)
Submits a command buffer to the queue for execution.
Definition: vulkan.c:590
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
FFVkExecContext
Definition: vulkan.h:154
FFVulkanDescriptorSetBinding::name
const char * name
Definition: vulkan.h:79
internal.h
av_vkfmt_from_pixfmt
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.
Definition: hwcontext_stub.c:30
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: internal.h:180
ff_vk_init_compute_pipeline
int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl)
Initializes a compute pipeline.
Definition: vulkan.c:1229
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
overlay_alpha
static const char overlay_alpha[]
Definition: vf_overlay_vulkan.c:64
VkFormat
enum VkFormat VkFormat
Definition: hwcontext_stub.c:25
CGROUPS
#define CGROUPS
Definition: vf_overlay_vulkan.c:25
ff_vk_shader_rep_fmt
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt)
Gets the glsl format string for a pixel format.
Definition: vulkan.c:721
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
OverlayVulkanContext::vkctx
FFVulkanContext vkctx
Definition: vf_overlay_vulkan.c:28
GLSLF
#define GLSLF(N, S,...)
Definition: vulkan.h:46
ff_vk_create_pipeline
FFVulkanPipeline * ff_vk_create_pipeline(FFVulkanContext *s, FFVkQueueFamilyCtx *qf)
Inits a pipeline.
Definition: vulkan.c:1220
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Frees a buffer.
Definition: vulkan.c:349
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(overlay_vulkan)
AVFilter
Filter definition.
Definition: avfilter.h:171
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:191
pos
unsigned int pos
Definition: spdifenc.c:412
OverlayVulkanContext::pl
FFVulkanPipeline * pl
Definition: vf_overlay_vulkan.c:33
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:664
ff_vk_add_descriptor_set
int ff_vk_add_descriptor_set(FFVulkanContext *s, FFVulkanPipeline *pl, FFVkSPIRVShader *shd, FFVulkanDescriptorSetBinding *desc, int num, int only_print_to_shader)
Adds a descriptor set to the shader and registers them in the pipeline.
Definition: vulkan.c:923
AVFrame::height
int height
Definition: frame.h:397
random_seed.h
framesync.h
FFVkSPIRVShader
Definition: vulkan.h:58
OverlayVulkanContext::fs
FFFrameSync fs
Definition: vf_overlay_vulkan.c:34
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
overlay_vulkan_uninit
static void overlay_vulkan_uninit(AVFilterContext *avctx)
Definition: vf_overlay_vulkan.c:443
ff_vk_init_sampler
FFVkSampler * ff_vk_init_sampler(FFVulkanContext *s, int unnorm_coords, VkFilter filt)
Create a Vulkan sampler, will be auto-freed in ff_vk_filter_uninit()
Definition: vulkan.c:670
AVFilterContext
An instance of a filter.
Definition: avfilter.h:415
OverlayVulkanContext::output_images
VkDescriptorImageInfo output_images[3]
Definition: vf_overlay_vulkan.c:40
desc
const char * desc
Definition: libsvtav1.c:83
GLSLC
#define GLSLC(N, S)
Definition: vulkan.h:44
ff_vk_filter_config_input
int ff_vk_filter_config_input(AVFilterLink *inlink)
Definition: vulkan_filter.c:52
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:241
ff_vk_map_buffers
int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer *buf, uint8_t *mem[], int nb_buffers, int invalidate)
Maps the buffer to userspace.
Definition: vulkan.c:258
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:191
ff_vk_set_compute_shader_sizes
void ff_vk_set_compute_shader_sizes(FFVkSPIRVShader *shd, int local_size[3])
Writes the workgroup size for a shader.
Definition: vulkan.c:816
FFVkBuffer
Definition: vulkan.h:91
int32_t
int32_t
Definition: audioconvert.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:285
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:355
OverlayVulkanContext::initialized
int initialized
Definition: vf_overlay_vulkan.c:30
RET
#define RET(x)
Definition: vulkan.h:52
FFVulkanFunctions
Definition: vulkan_functions.h:175
OverlayVulkanContext::overlay_y
int overlay_y
Definition: vf_overlay_vulkan.c:44
OverlayVulkanContext::overlay_h
int overlay_h
Definition: vf_overlay_vulkan.c:46
OverlayVulkanContext::qf
FFVkQueueFamilyCtx qf
Definition: vf_overlay_vulkan.c:31