FFmpeg
vf_scale_vulkan.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) Lynne
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 "libavutil/random_seed.h"
22 #include "libavutil/opt.h"
23 #include "libavutil/vulkan_spirv.h"
24 #include "vulkan_filter.h"
25 #include "scale_eval.h"
26 #include "filters.h"
27 #include "colorspace.h"
28 #include "video.h"
29 
30 enum ScalerFunc {
33 
35 };
36 
37 typedef struct ScaleVulkanContext {
39 
44  VkSampler sampler;
45 
46  /* Push constants / options */
47  struct {
48  float yuv_matrix[4][4];
49  int crop_x;
50  int crop_y;
51  int crop_w;
52  int crop_h;
53  } opts;
54 
56  char *w_expr;
57  char *h_expr;
58 
62 
63 static const char scale_bilinear[] = {
64  C(0, vec4 scale_bilinear(int idx, ivec2 pos, vec2 crop_range, vec2 crop_off))
65  C(0, { )
66  C(1, vec2 npos = (vec2(pos) + 0.5f) / imageSize(output_img[idx]); )
67  C(1, npos *= crop_range; /* Reduce the range */ )
68  C(1, npos += crop_off; /* Offset the start */ )
69  C(1, return texture(input_img[idx], npos); )
70  C(0, } )
71 };
72 
73 static const char rgb2yuv[] = {
74  C(0, vec4 rgb2yuv(vec4 src, int fullrange) )
75  C(0, { )
76  C(1, src *= yuv_matrix; )
77  C(1, if (fullrange == 1) { )
78  C(2, src += vec4(0.0, 0.5, 0.5, 0.0); )
79  C(1, } else { )
80  C(2, src *= vec4(219.0 / 255.0, 224.0 / 255.0, 224.0 / 255.0, 1.0); )
81  C(2, src += vec4(16.0 / 255.0, 128.0 / 255.0, 128.0 / 255.0, 0.0); )
82  C(1, } )
83  C(1, return src; )
84  C(0, } )
85 };
86 
87 static const char write_nv12[] = {
88  C(0, void write_nv12(vec4 src, ivec2 pos) )
89  C(0, { )
90  C(1, imageStore(output_img[0], pos, vec4(src.r, 0.0, 0.0, 0.0)); )
91  C(1, pos /= ivec2(2); )
92  C(1, imageStore(output_img[1], pos, vec4(src.g, src.b, 0.0, 0.0)); )
93  C(0, } )
94 };
95 
96 static const char write_420[] = {
97  C(0, void write_420(vec4 src, ivec2 pos) )
98  C(0, { )
99  C(1, imageStore(output_img[0], pos, vec4(src.r, 0.0, 0.0, 0.0)); )
100  C(1, pos /= ivec2(2); )
101  C(1, imageStore(output_img[1], pos, vec4(src.g, 0.0, 0.0, 0.0)); )
102  C(1, imageStore(output_img[2], pos, vec4(src.b, 0.0, 0.0, 0.0)); )
103  C(0, } )
104 };
105 
106 static const char write_444[] = {
107  C(0, void write_444(vec4 src, ivec2 pos) )
108  C(0, { )
109  C(1, imageStore(output_img[0], pos, vec4(src.r, 0.0, 0.0, 0.0)); )
110  C(1, imageStore(output_img[1], pos, vec4(src.g, 0.0, 0.0, 0.0)); )
111  C(1, imageStore(output_img[2], pos, vec4(src.b, 0.0, 0.0, 0.0)); )
112  C(0, } )
113 };
114 
116 {
117  int err;
118  uint8_t *spv_data;
119  size_t spv_len;
120  void *spv_opaque = NULL;
121  VkFilter sampler_mode;
122  ScaleVulkanContext *s = ctx->priv;
123  FFVulkanContext *vkctx = &s->vkctx;
124  FFVulkanShader *shd = &s->shd;
125  FFVkSPIRVCompiler *spv;
127 
128  int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format);
129 
130  switch (s->scaler) {
131  case F_NEAREST:
132  sampler_mode = VK_FILTER_NEAREST;
133  break;
134  case F_BILINEAR:
135  sampler_mode = VK_FILTER_LINEAR;
136  break;
137  };
138 
139  spv = ff_vk_spirv_init();
140  if (!spv) {
141  av_log(ctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n");
142  return AVERROR_EXTERNAL;
143  }
144 
145  s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
146  if (!s->qf) {
147  av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
148  err = AVERROR(ENOTSUP);
149  goto fail;
150  }
151 
152  RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
153  RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode));
154  RET(ff_vk_shader_init(vkctx, &s->shd, "scale",
155  VK_SHADER_STAGE_COMPUTE_BIT,
156  NULL, 0,
157  32, 32, 1,
158  0));
159 
160  GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
161  GLSLC(1, mat4 yuv_matrix; );
162  GLSLC(1, int crop_x; );
163  GLSLC(1, int crop_y; );
164  GLSLC(1, int crop_w; );
165  GLSLC(1, int crop_h; );
166  GLSLC(0, }; );
167  GLSLC(0, );
168 
169  ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
170  VK_SHADER_STAGE_COMPUTE_BIT);
171 
173  {
174  .name = "input_img",
175  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
176  .dimensions = 2,
177  .elems = in_planes,
178  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
179  .samplers = DUP_SAMPLER(s->sampler),
180  },
181  {
182  .name = "output_img",
183  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
184  .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.output_format, FF_VK_REP_FLOAT),
185  .mem_quali = "writeonly",
186  .dimensions = 2,
187  .elems = av_pix_fmt_count_planes(s->vkctx.output_format),
188  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
189  },
190  };
191 
192  RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
193 
195 
196  if (s->vkctx.output_format != s->vkctx.input_format) {
197  GLSLD( rgb2yuv );
198  }
199 
200  switch (s->vkctx.output_format) {
201  case AV_PIX_FMT_NV12: GLSLD(write_nv12); break;
202  case AV_PIX_FMT_YUV420P: GLSLD( write_420); break;
203  case AV_PIX_FMT_YUV444P: GLSLD( write_444); break;
204  default: break;
205  }
206 
207  GLSLC(0, void main() );
208  GLSLC(0, { );
209  GLSLC(1, ivec2 size; );
210  GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
211  GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height);
212  GLSLC(1, vec2 c_r = vec2(crop_w, crop_h) / in_d; );
213  GLSLC(1, vec2 c_o = vec2(crop_x, crop_y) / in_d; );
214  GLSLC(0, );
215 
216  if (s->vkctx.output_format == s->vkctx.input_format) {
217  for (int i = 0; i < desc[1].elems; i++) {
218  GLSLF(1, size = imageSize(output_img[%i]); ,i);
219  GLSLC(1, if (IS_WITHIN(pos, size)) { );
220  switch (s->scaler) {
221  case F_NEAREST:
222  case F_BILINEAR:
223  GLSLF(2, vec4 res = scale_bilinear(%i, pos, c_r, c_o); ,i);
224  GLSLF(2, imageStore(output_img[%i], pos, res); ,i);
225  break;
226  };
227  GLSLC(1, } );
228  }
229  } else {
230  GLSLC(1, vec4 res = scale_bilinear(0, pos, c_r, c_o); );
231  GLSLF(1, res = rgb2yuv(res, %i); ,s->out_range == AVCOL_RANGE_JPEG);
232  switch (s->vkctx.output_format) {
233  case AV_PIX_FMT_NV12: GLSLC(1, write_nv12(res, pos); ); break;
234  case AV_PIX_FMT_YUV420P: GLSLC(1, write_420(res, pos); ); break;
235  case AV_PIX_FMT_YUV444P: GLSLC(1, write_444(res, pos); ); break;
236  default: return AVERROR(EINVAL);
237  }
238  }
239 
240  GLSLC(0, } );
241 
242  if (s->vkctx.output_format != s->vkctx.input_format) {
243  const AVLumaCoefficients *lcoeffs;
244  double tmp_mat[3][3];
245 
247  if (!lcoeffs) {
248  av_log(ctx, AV_LOG_ERROR, "Unsupported colorspace\n");
249  return AVERROR(EINVAL);
250  }
251 
252  ff_fill_rgb2yuv_table(lcoeffs, tmp_mat);
253 
254  for (int y = 0; y < 3; y++)
255  for (int x = 0; x < 3; x++)
256  s->opts.yuv_matrix[x][y] = tmp_mat[x][y];
257  s->opts.yuv_matrix[3][3] = 1.0;
258  }
259 
260  RET(spv->compile_shader(vkctx, spv, shd, &spv_data, &spv_len, "main",
261  &spv_opaque));
262  RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
263 
264  RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
265 
266  s->initialized = 1;
267 
268 fail:
269  if (spv_opaque)
270  spv->free_shader(spv, &spv_opaque);
271  if (spv)
272  spv->uninit(&spv);
273 
274  return err;
275 }
276 
278 {
279  int err;
280  AVFilterContext *ctx = link->dst;
281  ScaleVulkanContext *s = ctx->priv;
282  AVFilterLink *outlink = ctx->outputs[0];
283 
284  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
285  if (!out) {
286  err = AVERROR(ENOMEM);
287  goto fail;
288  }
289 
290  if (!s->initialized)
291  RET(init_filter(ctx, in));
292 
293  s->opts.crop_x = in->crop_left;
294  s->opts.crop_y = in->crop_top;
295  s->opts.crop_w = in->width - (in->crop_left + in->crop_right);
296  s->opts.crop_h = in->height - (in->crop_top + in->crop_bottom);
297 
298  RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
299  s->sampler, &s->opts, sizeof(s->opts)));
300 
301  err = av_frame_copy_props(out, in);
302  if (err < 0)
303  goto fail;
304 
305  if (out->width != in->width || out->height != in->height) {
306  av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data,
308  }
309 
310  if (s->out_range != AVCOL_RANGE_UNSPECIFIED)
311  out->color_range = s->out_range;
312  if (s->vkctx.output_format != s->vkctx.input_format)
313  out->chroma_location = AVCHROMA_LOC_TOPLEFT;
314 
315  av_frame_free(&in);
316 
317  return ff_filter_frame(outlink, out);
318 
319 fail:
320  av_frame_free(&in);
321  av_frame_free(&out);
322  return err;
323 }
324 
326 {
327  int err;
328  AVFilterContext *avctx = outlink->src;
329  ScaleVulkanContext *s = avctx->priv;
330  FFVulkanContext *vkctx = &s->vkctx;
331  AVFilterLink *inlink = outlink->src->inputs[0];
332 
333  err = ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
334  &vkctx->output_width,
335  &vkctx->output_height);
336  if (err < 0)
337  return err;
338 
340 
341  outlink->w = vkctx->output_width;
342  outlink->h = vkctx->output_height;
343 
344  if (s->out_format_string) {
345  s->vkctx.output_format = av_get_pix_fmt(s->out_format_string);
346  if (s->vkctx.output_format == AV_PIX_FMT_NONE) {
347  av_log(avctx, AV_LOG_ERROR, "Invalid output format.\n");
348  return AVERROR(EINVAL);
349  }
350  } else {
351  s->vkctx.output_format = s->vkctx.input_format;
352  }
353 
354  if (s->vkctx.output_format != s->vkctx.input_format) {
355  if (!ff_vk_mt_is_np_rgb(s->vkctx.input_format)) {
356  av_log(avctx, AV_LOG_ERROR, "Unsupported input format for conversion\n");
357  return AVERROR(EINVAL);
358  }
359  if (s->vkctx.output_format != AV_PIX_FMT_NV12 &&
360  s->vkctx.output_format != AV_PIX_FMT_YUV420P &&
361  s->vkctx.output_format != AV_PIX_FMT_YUV444P) {
362  av_log(avctx, AV_LOG_ERROR, "Unsupported output format\n");
363  return AVERROR(EINVAL);
364  }
365  } else if (s->out_range != AVCOL_RANGE_UNSPECIFIED) {
366  av_log(avctx, AV_LOG_ERROR, "Cannot change range without converting format\n");
367  return AVERROR(EINVAL);
368  }
369 
370  return ff_vk_filter_config_output(outlink);
371 }
372 
374 {
375  ScaleVulkanContext *s = avctx->priv;
376  FFVulkanContext *vkctx = &s->vkctx;
377  FFVulkanFunctions *vk = &vkctx->vkfn;
378 
379  ff_vk_exec_pool_free(vkctx, &s->e);
380  ff_vk_shader_free(vkctx, &s->shd);
381 
382  if (s->sampler)
383  vk->DestroySampler(vkctx->hwctx->act_dev, s->sampler,
384  vkctx->hwctx->alloc);
385 
386  ff_vk_uninit(&s->vkctx);
387 
388  s->initialized = 0;
389 }
390 
391 #define OFFSET(x) offsetof(ScaleVulkanContext, x)
392 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
393 static const AVOption scale_vulkan_options[] = {
394  { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = FLAGS },
395  { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
396  { "scaler", "Scaler function", OFFSET(scaler), AV_OPT_TYPE_INT, {.i64 = F_BILINEAR}, 0, F_NB, .flags = FLAGS, .unit = "scaler" },
397  { "bilinear", "Bilinear interpolation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = F_BILINEAR}, 0, 0, .flags = FLAGS, .unit = "scaler" },
398  { "nearest", "Nearest (useful for pixel art)", 0, AV_OPT_TYPE_CONST, {.i64 = F_NEAREST}, 0, 0, .flags = FLAGS, .unit = "scaler" },
399  { "format", "Output video format (software format of hardware frames)", OFFSET(out_format_string), AV_OPT_TYPE_STRING, .flags = FLAGS },
400  { "out_range", "Output colour range (from 0 to 2) (default 0)", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED}, AVCOL_RANGE_UNSPECIFIED, AVCOL_RANGE_JPEG, .flags = FLAGS, .unit = "range" },
401  { "full", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
402  { "limited", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
403  { "jpeg", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
404  { "mpeg", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
405  { "tv", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
406  { "pc", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
407  { NULL },
408 };
409 
410 AVFILTER_DEFINE_CLASS(scale_vulkan);
411 
413  {
414  .name = "default",
415  .type = AVMEDIA_TYPE_VIDEO,
416  .filter_frame = &scale_vulkan_filter_frame,
417  .config_props = &ff_vk_filter_config_input,
418  },
419 };
420 
422  {
423  .name = "default",
424  .type = AVMEDIA_TYPE_VIDEO,
425  .config_props = &scale_vulkan_config_output,
426  },
427 };
428 
430  .p.name = "scale_vulkan",
431  .p.description = NULL_IF_CONFIG_SMALL("Scale Vulkan frames"),
432  .p.priv_class = &scale_vulkan_class,
433  .p.flags = AVFILTER_FLAG_HWDEVICE,
434  .priv_size = sizeof(ScaleVulkanContext),
440  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
441 };
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:116
FFVulkanContext::output_height
int output_height
Definition: vulkan.h:307
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:2572
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:1715
out
FILE * out
Definition: movenc.c:55
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1078
RET
#define RET(x)
Definition: vulkan.h:67
ff_vk_filter_process_simple
int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f, VkSampler sampler, void *push_src, size_t push_size)
Submit a compute shader with a zero/one input and single out for execution.
Definition: vulkan_filter.c:242
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:296
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:163
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:708
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
OFFSET
#define OFFSET(x)
Definition: vf_scale_vulkan.c:391
AVFrame::width
int width
Definition: frame.h:482
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:728
scale_vulkan_outputs
static const AVFilterPad scale_vulkan_outputs[]
Definition: vf_scale_vulkan.c:421
av_csp_luma_coeffs_from_avcsp
const struct AVLumaCoefficients * av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp)
Retrieves the Luma coefficients necessary to construct a conversion matrix from an enum constant desc...
Definition: csp.c:58
ScaleVulkanContext::opts
struct ScaleVulkanContext::@355 opts
AVOption
AVOption.
Definition: opt.h:429
scale_vulkan_options
static const AVOption scale_vulkan_options[]
Definition: vf_scale_vulkan.c:393
rgb2yuv
static const char rgb2yuv[]
Definition: vf_scale_vulkan.c:73
write_nv12
static const char write_nv12[]
Definition: vf_scale_vulkan.c:87
ff_scale_eval_dimensions
int ff_scale_eval_dimensions(void *log_ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h)
Parse and evaluate string expressions for width and height.
Definition: scale_eval.c:57
AVLumaCoefficients
Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar calculations.
Definition: csp.h:48
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2611
FFVkSPIRVCompiler::uninit
void(* uninit)(struct FFVkSPIRVCompiler **ctx)
Definition: vulkan_spirv.h:32
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:203
ScaleVulkanContext::sampler
VkSampler sampler
Definition: vf_scale_vulkan.c:44
video.h
ScaleVulkanContext::yuv_matrix
float yuv_matrix[4][4]
Definition: vf_scale_vulkan.c:48
write_420
static const char write_420[]
Definition: vf_scale_vulkan.c:96
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
ScaleVulkanContext::e
FFVkExecPool e
Definition: vf_scale_vulkan.c:41
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(scale_vulkan)
ScalerFunc
ScalerFunc
Definition: vf_scale_vulkan.c:30
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3284
AVVulkanDeviceContext::alloc
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
Definition: hwcontext_vulkan.h:63
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:272
fail
#define fail()
Definition: checkasm.h:193
vulkan_filter.h
colorspace.h
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:2212
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:2079
AV_SIDE_DATA_PROP_SIZE_DEPENDENT
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
Definition: frame.h:292
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
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
GLSLC
#define GLSLC(N, S)
Definition: vulkan.h:44
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
av_cold
#define av_cold
Definition: attributes.h:90
main
int main
Definition: dovi_rpuenc.c:37
FFFilter
Definition: filters.h:265
FFVulkanContext::output_width
int output_width
Definition: vulkan.h:306
F_NEAREST
@ F_NEAREST
Definition: vf_scale_vulkan.c:32
s
#define s(width, name)
Definition: cbs_vp9.c:198
F_BILINEAR
@ F_BILINEAR
Definition: vf_scale_vulkan.c:31
scale_vulkan_filter_frame
static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_scale_vulkan.c:277
ScaleVulkanContext::crop_x
int crop_x
Definition: vf_scale_vulkan.c:49
ff_vf_scale_vulkan
const FFFilter ff_vf_scale_vulkan
Definition: vf_scale_vulkan.c:429
filters.h
FF_VK_REP_FLOAT
@ FF_VK_REP_FLOAT
Definition: vulkan.h:376
ctx
AVFormatContext * ctx
Definition: movenc.c:49
GLSLD
#define GLSLD(D)
Definition: vulkan.h:59
AVFrame::crop_right
size_t crop_right
Definition: frame.h:798
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:233
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
ff_vk_shader_rep_fmt
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt, enum FFVkShaderRepFormat rep_fmt)
Definition: vulkan.c:1322
NULL
#define NULL
Definition: coverity.c:32
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:726
DUP_SAMPLER
#define DUP_SAMPLER(x)
Definition: vulkan.h:73
scale_vulkan_uninit
static void scale_vulkan_uninit(AVFilterContext *avctx)
Definition: vf_scale_vulkan.c:373
ScaleVulkanContext::h_expr
char * h_expr
Definition: vf_scale_vulkan.c:57
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:751
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:265
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:209
ScaleVulkanContext::crop_h
int crop_h
Definition: vf_scale_vulkan.c:52
FFVulkanContext
Definition: vulkan.h:266
ScaleVulkanContext::out_range
enum AVColorRange out_range
Definition: vf_scale_vulkan.c:60
F_NB
@ F_NB
Definition: vf_scale_vulkan.c:34
FLAGS
#define FLAGS
Definition: vf_scale_vulkan.c:392
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:694
ScaleVulkanContext::vkctx
FFVulkanContext vkctx
Definition: vf_scale_vulkan.c:38
AVFrame::crop_bottom
size_t crop_bottom
Definition: frame.h:796
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
AVFrame::crop_left
size_t crop_left
Definition: frame.h:797
ScaleVulkanContext::qf
AVVulkanDeviceQueueFamily * qf
Definition: vf_scale_vulkan.c:42
f
f
Definition: af_crystalizer.c:122
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
FFVulkanDescriptorSetBinding
Definition: vulkan.h:75
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
AVFILTER_FLAG_HWDEVICE
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition: avfilter.h:171
size
int size
Definition: twinvq_data.h:10344
FFVulkanShader
Definition: vulkan.h:182
ScaleVulkanContext::crop_y
int crop_y
Definition: vf_scale_vulkan.c:50
scale_eval.h
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
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
ff_vk_mt_is_np_rgb
int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt)
Returns 1 if pixfmt is a usable RGB format.
Definition: vulkan.c:1301
av_frame_side_data_remove_by_props
void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, int props)
Remove and free all side data instances that match any of the given side data properties.
Definition: frame.c:963
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
ScaleVulkanContext::scaler
enum ScalerFunc scaler
Definition: vf_scale_vulkan.c:59
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
ff_fill_rgb2yuv_table
void ff_fill_rgb2yuv_table(const AVLumaCoefficients *coeffs, double rgb2yuv[3][3])
Definition: colorspace.c:125
ScaleVulkanContext::w_expr
char * w_expr
Definition: vf_scale_vulkan.c:56
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
scale_bilinear
static const char scale_bilinear[]
Definition: vf_scale_vulkan.c:63
write_444
static const char write_444[]
Definition: vf_scale_vulkan.c:106
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:2004
vulkan_spirv.h
scale_vulkan_inputs
static const AVFilterPad scale_vulkan_inputs[]
Definition: vf_scale_vulkan.c:412
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:711
FFVkSPIRVCompiler::free_shader
void(* free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque)
Definition: vulkan_spirv.h:31
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:270
FFVkExecPool
Definition: vulkan.h:244
pos
unsigned int pos
Definition: spdifenc.c:414
ScaleVulkanContext::shd
FFVulkanShader shd
Definition: vf_scale_vulkan.c:43
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:1231
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:220
ff_scale_adjust_dimensions
int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition: scale_eval.c:113
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3176
AVFrame::height
int height
Definition: frame.h:482
random_seed.h
ScaleVulkanContext::initialized
int initialized
Definition: vf_scale_vulkan.c:40
GLSLF
#define GLSLF(N, S,...)
Definition: vulkan.h:54
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
ScaleVulkanContext::crop_w
int crop_w
Definition: vf_scale_vulkan.c:51
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:257
ScaleVulkanContext
Definition: vf_scale_vulkan.c:37
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:201
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
FFVulkanContext::hwctx
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:295
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:84
ff_vk_init_sampler
int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, int unnorm_coords, VkFilter filt)
Create a sampler.
Definition: vulkan.c:1252
AVFrame::crop_top
size_t crop_top
Definition: frame.h:795
scale_vulkan_config_output
static int scale_vulkan_config_output(AVFilterLink *outlink)
Definition: vf_scale_vulkan.c:325
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVVulkanDeviceQueueFamily
Definition: hwcontext_vulkan.h:33
init_filter
static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
Definition: vf_scale_vulkan.c:115
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:693
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: filters.h:252
FFVulkanFunctions
Definition: vulkan_functions.h:263
ScaleVulkanContext::out_format_string
char * out_format_string
Definition: vf_scale_vulkan.c:55
src
#define src
Definition: vp8dsp.c:248