FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
vf_blackdetect_vulkan.c
Go to the documentation of this file.
1 /*
2  * Copyright 2025 (c) Niklas Haas
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <float.h>
22 #include "libavutil/vulkan_spirv.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/timestamp.h"
25 #include "vulkan_filter.h"
26 
27 #include "filters.h"
28 #include "video.h"
29 
30 typedef struct BlackDetectVulkanContext {
32 
38 
42  int alpha;
43 
46 
47 typedef struct BlackDetectPushData {
48  float threshold;
50 
51 typedef struct BlackDetectBuf {
52 #define SLICES 16
53  uint32_t slice_sum[SLICES];
55 
57 {
58  int err;
59  uint8_t *spv_data;
60  size_t spv_len;
61  void *spv_opaque = NULL;
63  FFVulkanContext *vkctx = &s->vkctx;
64  FFVulkanShader *shd;
65  FFVkSPIRVCompiler *spv;
67  const int plane = s->alpha ? 3 : 0;
68 
69  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->vkctx.input_format);
70  if (pixdesc->flags & AV_PIX_FMT_FLAG_RGB) {
71  av_log(ctx, AV_LOG_ERROR, "RGB inputs are not supported\n");
72  return AVERROR(ENOTSUP);
73  }
74 
75  spv = ff_vk_spirv_init();
76  if (!spv) {
77  av_log(ctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n");
78  return AVERROR_EXTERNAL;
79  }
80 
81  s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
82  if (!s->qf) {
83  av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
84  err = AVERROR(ENOTSUP);
85  goto fail;
86  }
87 
88  RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
89  RET(ff_vk_shader_init(vkctx, &s->shd, "blackdetect",
90  VK_SHADER_STAGE_COMPUTE_BIT,
91  (const char *[]) { "GL_KHR_shader_subgroup_ballot" }, 1,
92  32, 32, 1,
93  0));
94  shd = &s->shd;
95 
96  GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
97  GLSLC(1, float threshold; );
98  GLSLC(0, }; );
99 
101  VK_SHADER_STAGE_COMPUTE_BIT);
102 
104  {
105  .name = "input_img",
106  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
107  .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.input_format, FF_VK_REP_FLOAT),
108  .mem_quali = "readonly",
109  .dimensions = 2,
110  .elems = av_pix_fmt_count_planes(s->vkctx.input_format),
111  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
112  }, {
113  .name = "sum_buffer",
114  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
115  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
116  .buf_content = "uint slice_sum[];",
117  }
118  };
119 
120  RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
121 
122  GLSLC(0, shared uint wg_sum; );
123  GLSLC(0, );
124  GLSLC(0, void main() );
125  GLSLC(0, { );
126  GLSLC(1, wg_sum = 0u; );
127  GLSLC(1, barrier(); );
128  GLSLC(0, );
129  GLSLC(1, const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
130  GLSLF(1, if (!IS_WITHIN(pos, imageSize(input_img[%d]))) ,plane);
131  GLSLC(2, return; );
132  GLSLF(1, float value = imageLoad(input_img[%d], pos).x; ,plane);
133  GLSLC(1, uvec4 isblack = subgroupBallot(value <= threshold); );
134  GLSLC(1, if (subgroupElect()) );
135  GLSLC(2, atomicAdd(wg_sum, subgroupBallotBitCount(isblack)); );
136  GLSLC(1, barrier(); );
137  GLSLC(1, if (gl_LocalInvocationIndex == 0u) );
138  GLSLF(2, atomicAdd(slice_sum[gl_WorkGroupID.x %% %du], wg_sum); ,SLICES);
139  GLSLC(0, } );
140 
141  RET(spv->compile_shader(vkctx, spv, &s->shd, &spv_data, &spv_len, "main",
142  &spv_opaque));
143  RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main"));
144 
145  RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
146 
147  s->black_start = AV_NOPTS_VALUE;
148  s->initialized = 1;
149 
150 fail:
151  if (spv_opaque)
152  spv->free_shader(spv, &spv_opaque);
153  if (spv)
154  spv->uninit(&spv);
155 
156  return err;
157 }
158 
160 {
161  BlackDetectVulkanContext *s = ctx->priv;
162  const AVFilterLink *inlink = ctx->inputs[0];
163  if (s->black_start == AV_NOPTS_VALUE)
164  return;
165 
166  if ((black_end - s->black_start) >= s->black_min_duration_time / av_q2d(inlink->time_base)) {
168  "black_start:%s black_end:%s black_duration:%s\n",
169  av_ts2timestr(s->black_start, &inlink->time_base),
170  av_ts2timestr(black_end, &inlink->time_base),
171  av_ts2timestr(black_end - s->black_start, &inlink->time_base));
172  }
173 }
174 
175 static void evaluate(AVFilterLink *link, AVFrame *in,
176  const BlackDetectBuf *sum)
177 {
178  AVFilterContext *ctx = link->dst;
179  BlackDetectVulkanContext *s = ctx->priv;
181  uint64_t nb_black_pixels = 0;
182  double ratio;
183 
184  for (int i = 0; i < FF_ARRAY_ELEMS(sum->slice_sum); i++)
185  nb_black_pixels += sum->slice_sum[i];
186 
187  ratio = (double) nb_black_pixels / (link->w * link->h);
188 
190  "frame:%"PRId64" picture_black_ratio:%f pts:%s t:%s type:%c\n",
191  inl->frame_count_out, ratio,
192  av_ts2str(in->pts), av_ts2timestr(in->pts, &in->time_base),
194 
195  if (ratio >= s->picture_black_ratio_th) {
196  if (s->black_start == AV_NOPTS_VALUE) {
197  s->black_start = in->pts;
198  av_dict_set(&in->metadata, "lavfi.black_start",
199  av_ts2timestr(in->pts, &in->time_base), 0);
200  }
201  } else if (s->black_start != AV_NOPTS_VALUE) {
203  av_dict_set(&in->metadata, "lavfi.black_end",
204  av_ts2timestr(in->pts, &in->time_base), 0);
205  s->black_start = AV_NOPTS_VALUE;
206  }
207 }
208 
210 {
211  int err;
212  AVFilterContext *ctx = link->dst;
213  BlackDetectVulkanContext *s = ctx->priv;
214  AVFilterLink *outlink = ctx->outputs[0];
215 
216  VkImageView in_views[AV_NUM_DATA_POINTERS];
217  VkImageMemoryBarrier2 img_bar[4];
218  int nb_img_bar = 0;
219 
220  FFVulkanContext *vkctx = &s->vkctx;
221  FFVulkanFunctions *vk = &vkctx->vkfn;
222  FFVkExecContext *exec = NULL;
223  AVBufferRef *sum_buf = NULL;
224  FFVkBuffer *sum_vk;
225 
226  BlackDetectBuf *sum;
227  BlackDetectPushData push_data;
228 
229  if (in->color_range == AVCOL_RANGE_JPEG || s->alpha) {
230  push_data.threshold = s->pixel_black_th;
231  } else {
233  const int depth = desc->comp[0].depth;
234  const int ymin = 16 << (depth - 8);
235  const int ymax = 235 << (depth - 8);
236  const int imax = (1 << depth) - 1;
237  push_data.threshold = (s->pixel_black_th * (ymax - ymin) + ymin) / imax;
238  }
239 
240  if (!s->initialized)
241  RET(init_filter(ctx));
242 
243  err = ff_vk_get_pooled_buffer(vkctx, &s->sum_buf_pool, &sum_buf,
244  VK_BUFFER_USAGE_TRANSFER_DST_BIT |
245  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
246  NULL,
247  sizeof(BlackDetectBuf),
248  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
249  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
250  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
251  if (err < 0)
252  return err;
253  sum_vk = (FFVkBuffer *)sum_buf->data;
254  sum = (BlackDetectBuf *) sum_vk->mapped_mem;
255 
256  exec = ff_vk_exec_get(vkctx, &s->e);
257  ff_vk_exec_start(vkctx, exec);
258 
259  RET(ff_vk_exec_add_dep_frame(vkctx, exec, in,
260  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
261  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
262  RET(ff_vk_create_imageviews(vkctx, exec, in_views, in, FF_VK_REP_FLOAT));
263 
264  ff_vk_shader_update_img_array(vkctx, exec, &s->shd, in, in_views, 0, 0,
265  VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE);
266 
267  ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
268  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
269  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
270  VK_ACCESS_SHADER_READ_BIT,
271  VK_IMAGE_LAYOUT_GENERAL,
272  VK_QUEUE_FAMILY_IGNORED);
273 
274  /* zero sum buffer */
275  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
276  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
277  .pBufferMemoryBarriers = &(VkBufferMemoryBarrier2) {
278  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
279  .srcStageMask = VK_PIPELINE_STAGE_2_NONE,
280  .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
281  .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
282  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
283  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
284  .buffer = sum_vk->buf,
285  .size = sum_vk->size,
286  .offset = 0,
287  },
288  .bufferMemoryBarrierCount = 1,
289  });
290 
291  vk->CmdFillBuffer(exec->buf, sum_vk->buf, 0, sum_vk->size, 0x0);
292 
293  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
294  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
295  .pImageMemoryBarriers = img_bar,
296  .imageMemoryBarrierCount = nb_img_bar,
297  .pBufferMemoryBarriers = &(VkBufferMemoryBarrier2) {
298  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
299  .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
300  .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
301  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
302  .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
303  VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
304  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
305  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
306  .buffer = sum_vk->buf,
307  .size = sum_vk->size,
308  .offset = 0,
309  },
310  .bufferMemoryBarrierCount = 1,
311  });
312 
313  RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd, 0, 1, 0,
314  sum_vk, 0, sum_vk->size,
315  VK_FORMAT_UNDEFINED));
316 
317  ff_vk_exec_bind_shader(vkctx, exec, &s->shd);
318  ff_vk_shader_update_push_const(vkctx, exec, &s->shd, VK_SHADER_STAGE_COMPUTE_BIT,
319  0, sizeof(push_data), &push_data);
320 
321  vk->CmdDispatch(exec->buf,
322  FFALIGN(in->width, s->shd.lg_size[0]) / s->shd.lg_size[0],
323  FFALIGN(in->height, s->shd.lg_size[1]) / s->shd.lg_size[1],
324  s->shd.lg_size[2]);
325 
326  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
327  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
328  .pBufferMemoryBarriers = &(VkBufferMemoryBarrier2) {
329  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
330  .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
331  .dstStageMask = VK_PIPELINE_STAGE_2_HOST_BIT,
332  .srcAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
333  VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
334  .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
335  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
336  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
337  .buffer = sum_vk->buf,
338  .size = sum_vk->size,
339  .offset = 0,
340  },
341  .bufferMemoryBarrierCount = 1,
342  });
343 
344  RET(ff_vk_exec_submit(vkctx, exec));
345  ff_vk_exec_wait(vkctx, exec);
346  evaluate(link, in, sum);
347 
348  av_buffer_unref(&sum_buf);
349  return ff_filter_frame(outlink, in);
350 
351 fail:
352  if (exec)
353  ff_vk_exec_discard_deps(&s->vkctx, exec);
354  av_frame_free(&in);
355  av_buffer_unref(&sum_buf);
356  return err;
357 }
358 
360 {
361  BlackDetectVulkanContext *s = avctx->priv;
362  AVFilterLink *inlink = avctx->inputs[0];
364  FFVulkanContext *vkctx = &s->vkctx;
365 
366  report_black_region(avctx, inl->current_pts);
367 
368  ff_vk_exec_pool_free(vkctx, &s->e);
369  ff_vk_shader_free(vkctx, &s->shd);
370 
371  av_buffer_pool_uninit(&s->sum_buf_pool);
372 
373  ff_vk_uninit(&s->vkctx);
374 
375  s->initialized = 0;
376 }
377 
378 static int config_output(AVFilterLink *outlink)
379 {
380  AVFilterContext *ctx = outlink->src;
381  BlackDetectVulkanContext *s = ctx->priv;
382  FFVulkanContext *vkctx = &s->vkctx;
384 
385  if (s->alpha && !(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) {
386  av_log(ctx, AV_LOG_ERROR, "Input format %s does not have an alpha channel\n",
388  return AVERROR(EINVAL);
389  }
390 
391  if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_XYZ) ||
392  !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) {
393  av_log(ctx, AV_LOG_ERROR, "Input format %s is not planar YUV\n",
395  return AVERROR(EINVAL);
396  }
397 
398  return ff_vk_filter_config_output(outlink);
399 }
400 
401 #define OFFSET(x) offsetof(BlackDetectVulkanContext, x)
402 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
404  { "d", "set minimum detected black duration in seconds", OFFSET(black_min_duration_time), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX, FLAGS },
405  { "black_min_duration", "set minimum detected black duration in seconds", OFFSET(black_min_duration_time), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX, FLAGS },
406  { "picture_black_ratio_th", "set the picture black ratio threshold", OFFSET(picture_black_ratio_th), AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1, FLAGS },
407  { "pic_th", "set the picture black ratio threshold", OFFSET(picture_black_ratio_th), AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1, FLAGS },
408  { "pixel_black_th", "set the pixel black threshold", OFFSET(pixel_black_th), AV_OPT_TYPE_DOUBLE, {.dbl=.10}, 0, 1, FLAGS },
409  { "pix_th", "set the pixel black threshold", OFFSET(pixel_black_th), AV_OPT_TYPE_DOUBLE, {.dbl=.10}, 0, 1, FLAGS },
410  { "alpha", "check alpha instead of luma", OFFSET(alpha), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
411  { NULL }
412 };
413 
414 AVFILTER_DEFINE_CLASS(blackdetect_vulkan);
415 
417  {
418  .name = "default",
419  .type = AVMEDIA_TYPE_VIDEO,
420  .filter_frame = &blackdetect_vulkan_filter_frame,
421  .config_props = &ff_vk_filter_config_input,
422  },
423 };
424 
426  {
427  .name = "default",
428  .type = AVMEDIA_TYPE_VIDEO,
429  .config_props = &config_output,
430  },
431 };
432 
434  .p.name = "blackdetect_vulkan",
435  .p.description = NULL_IF_CONFIG_SMALL("Detect video intervals that are (almost) black."),
436  .p.priv_class = &blackdetect_vulkan_class,
437  .p.flags = AVFILTER_FLAG_HWDEVICE,
438  .priv_size = sizeof(BlackDetectVulkanContext),
444  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
445 };
init_filter
static av_cold int init_filter(AVFilterContext *ctx)
Definition: vf_blackdetect_vulkan.c:56
AVFrame::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:661
BlackDetectVulkanContext::shd
FFVulkanShader shd
Definition: vf_blackdetect_vulkan.c:36
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_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2921
BlackDetectVulkanContext::pixel_black_th
double pixel_black_th
Definition: vf_blackdetect_vulkan.c:41
ff_vk_shader_init
int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name, VkPipelineStageFlags stage, const char *extensions[], int nb_extensions, int lg_x, int lg_y, int lg_z, uint32_t required_subgroup_size)
Initialize a shader object, with a specific set of extensions, type+bind, local group size,...
Definition: vulkan.c:2054
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:88
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3341
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
RET
#define RET(x)
Definition: vulkan.h:66
ff_vk_exec_pool_init
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
Definition: vulkan.c:356
int64_t
long long int64_t
Definition: coverity.c:34
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
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
ff_vf_blackdetect_vulkan
const FFFilter ff_vf_blackdetect_vulkan
Definition: vf_blackdetect_vulkan.c:433
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:512
ff_vk_filter_init
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.
Definition: vulkan_filter.c:233
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:750
AVOption
AVOption.
Definition: opt.h:429
BlackDetectVulkanContext::initialized
int initialized
Definition: vf_blackdetect_vulkan.c:33
float.h
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:547
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2962
BlackDetectBuf
Definition: vf_blackdetect_vulkan.c:51
FFVkSPIRVCompiler::uninit
void(* uninit)(struct FFVkSPIRVCompiler **ctx)
Definition: vulkan_spirv.h:32
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:215
video.h
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_blackdetect_vulkan.c:378
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
ff_vk_exec_add_dep_frame
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition: vulkan.c:779
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3381
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:284
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:83
BlackDetectVulkanContext::qf
AVVulkanDeviceQueueFamily * qf
Definition: vf_blackdetect_vulkan.c:35
fail
#define fail()
Definition: checkasm.h:196
vulkan_filter.h
ff_vk_shader_update_img_array
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
Definition: vulkan.c:2798
ff_vk_shader_register_exec
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition: vulkan.c:2561
ff_vk_shader_add_descriptor_set
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, FFVulkanDescriptorSetBinding *desc, int nb, int singular, int print_to_shader_only)
Add descriptor to a shader.
Definition: vulkan.c:2426
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
GLSLC
#define GLSLC(N, S)
Definition: vulkan.h:43
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
main
int main
Definition: dovi_rpuenc.c:38
FFFilter
Definition: filters.h:265
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition: opt.h:267
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:552
filters.h
FF_VK_REP_FLOAT
@ FF_VK_REP_FLOAT
Definition: vulkan.h:408
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
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:49
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:287
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
link
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 link
Definition: filter_design.txt:23
BlackDetectPushData::threshold
float threshold
Definition: vf_blackdetect_vulkan.c:48
ff_vk_shader_rep_fmt
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt, enum FFVkShaderRepFormat rep_fmt)
Definition: vulkan.c:1588
NULL
#define NULL
Definition: coverity.c:32
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
BlackDetectVulkanContext::sum_buf_pool
AVBufferPool * sum_buf_pool
Definition: vf_blackdetect_vulkan.c:37
SLICES
#define SLICES
Definition: vf_blackdetect_vulkan.c:52
BlackDetectPushData
Definition: vf_blackdetect_vulkan.c:47
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:277
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:209
blackdetect_vulkan_uninit
static void blackdetect_vulkan_uninit(AVFilterContext *avctx)
Definition: vf_blackdetect_vulkan.c:359
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:100
FFVulkanContext
Definition: vulkan.h:274
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(blackdetect_vulkan)
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
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: filters.h:206
BlackDetectVulkanContext::black_min_duration_time
double black_min_duration_time
Definition: vf_blackdetect_vulkan.c:39
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:502
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
av_ts2timestr
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:83
BlackDetectVulkanContext::picture_black_ratio_th
double picture_black_ratio_th
Definition: vf_blackdetect_vulkan.c:40
ff_vk_shader_update_push_const
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Definition: vulkan.c:2877
FFVulkanDescriptorSetBinding
Definition: vulkan.h:74
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:94
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:136
BlackDetectBuf::slice_sum
uint32_t slice_sum[SLICES]
Definition: vf_blackdetect_vulkan.c:53
AVFILTER_FLAG_HWDEVICE
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition: avfilter.h:183
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:411
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
FFVulkanShader
Definition: vulkan.h:190
AVFrame::time_base
AVRational time_base
Time base for the timestamps in this frame.
Definition: frame.h:527
BlackDetectVulkanContext::black_start
int64_t black_start
Definition: vf_blackdetect_vulkan.c:44
FFVkSPIRVCompiler::compile_shader
int(* compile_shader)(FFVulkanContext *s, struct FFVkSPIRVCompiler *ctx, FFVulkanShader *shd, uint8_t **data, size_t *size, const char *entrypoint, void **opaque)
Definition: vulkan_spirv.h:28
OFFSET
#define OFFSET(x)
Definition: vf_blackdetect_vulkan.c:401
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
FFVkExecContext
Definition: vulkan.h:111
ff_vk_shader_update_desc_buffer
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
Definition: vulkan.c:2811
report_black_region
static void report_black_region(AVFilterContext *ctx, int64_t black_end)
Definition: vf_blackdetect_vulkan.c:159
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
FFVkSPIRVCompiler
Definition: vulkan_spirv.h:26
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
av_get_picture_type_char
char av_get_picture_type_char(enum AVPictureType pict_type)
Return a single letter to describe the given picture type pict_type.
Definition: utils.c:40
BlackDetectVulkanContext::alpha
int alpha
Definition: vf_blackdetect_vulkan.c:42
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:559
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_vk_frame_barrier
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage, VkAccessFlagBits new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition: vulkan.c:2011
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
ff_vk_shader_link
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, uint8_t *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition: vulkan.c:2351
BlackDetectVulkanContext::e
FFVkExecPool e
Definition: vf_blackdetect_vulkan.c:34
vulkan_spirv.h
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
blackdetect_vulkan_outputs
static const AVFilterPad blackdetect_vulkan_outputs[]
Definition: vf_blackdetect_vulkan.c:425
FFVkSPIRVCompiler::free_shader
void(* free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque)
Definition: vulkan_spirv.h:31
ff_vk_exec_bind_shader
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd)
Bind a shader.
Definition: vulkan.c:2887
blackdetect_vulkan_filter_frame
static int blackdetect_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_blackdetect_vulkan.c:209
ff_vk_create_imageviews
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
Definition: vulkan.c:1928
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:278
FFVkExecPool
Definition: vulkan.h:252
pos
unsigned int pos
Definition: spdifenc.c:414
ff_vk_shader_add_push_const
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition: vulkan.c:1458
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:274
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
FFVulkanContext::input_format
enum AVPixelFormat input_format
Definition: vulkan.h:320
AV_PIX_FMT_FLAG_XYZ
#define AV_PIX_FMT_FLAG_XYZ
The pixel format contains XYZ-like data (as opposed to YUV/RGB/grayscale).
Definition: pixdesc.h:163
blackdetect_vulkan_inputs
static const AVFilterPad blackdetect_vulkan_inputs[]
Definition: vf_blackdetect_vulkan.c:416
GLSLF
#define GLSLF(N, S,...)
Definition: vulkan.h:53
AVFrame::metadata
AVDictionary * metadata
metadata.
Definition: frame.h:688
AV_PIX_FMT_FLAG_PLANAR
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:132
evaluate
static void evaluate(AVFilterLink *link, AVFrame *in, const BlackDetectBuf *sum)
Definition: vf_blackdetect_vulkan.c:175
AVFilterContext
An instance of a filter.
Definition: avfilter.h:269
blackdetect_vulkan_options
static const AVOption blackdetect_vulkan_options[]
Definition: vf_blackdetect_vulkan.c:403
desc
const char * desc
Definition: libsvtav1.c:79
ff_vk_filter_config_input
int ff_vk_filter_config_input(AVFilterLink *inlink)
Definition: vulkan_filter.c:176
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
BlackDetectVulkanContext::vkctx
FFVulkanContext vkctx
Definition: vf_blackdetect_vulkan.c:31
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
atomicAdd
#define atomicAdd(a, b)
Definition: cuda_runtime.h:37
ff_vk_exec_discard_deps
void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:591
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
FLAGS
#define FLAGS
Definition: vf_blackdetect_vulkan.c:402
FFVkBuffer
Definition: vulkan.h:87
timestamp.h
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:904
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVVulkanDeviceQueueFamily
Definition: hwcontext_vulkan.h:33
av_ts2str
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:54
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: filters.h:252
FFVulkanFunctions
Definition: vulkan_functions.h:274
BlackDetectVulkanContext
Definition: vf_blackdetect_vulkan.c:30
ff_vk_get_pooled_buffer
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool, AVBufferRef **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition: vulkan.c:1254
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3261