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/opt.h"
22 #include "vulkan_filter.h"
23 #include "scale_eval.h"
24 #include "filters.h"
25 #include "colorspace.h"
26 #include "video.h"
27 #include "libswscale/swscale.h"
28 
29 extern const unsigned char ff_scale_comp_spv_data[];
30 extern const unsigned int ff_scale_comp_spv_len;
31 
32 extern const unsigned char ff_debayer_comp_spv_data[];
33 extern const unsigned int ff_debayer_comp_spv_len;
34 
35 enum ScalerFunc {
38 
40 };
41 
45 
47 };
48 
49 /* Output modes, must match scale.comp.glsl */
50 enum ScaleMode {
51  MODE_COPY = 0,
55 };
56 
57 typedef struct ScaleVulkanContext {
60 
65  VkSampler sampler;
66 
67  /* Push constants / options */
68  struct {
69  float yuv_matrix[4][4];
70  int crop_x;
71  int crop_y;
72  int crop_w;
73  int crop_h;
74  float in_dims[2];
75  } opts;
76 
78  char *w_expr;
79  char *h_expr;
80 
85 
87 {
88  int err;
89  VkFilter sampler_mode;
90  enum ScaleMode mode;
91  ScaleVulkanContext *s = ctx->priv;
92  FFVulkanContext *vkctx = &s->vkctx;
93  FFVulkanShader *shd = &s->shd;
94 
95  int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format);
96  int out_planes = av_pix_fmt_count_planes(s->vkctx.output_format);
97 
98  switch (s->scaler) {
99  case F_NEAREST:
100  sampler_mode = VK_FILTER_NEAREST;
101  break;
102  case F_BILINEAR:
103  sampler_mode = VK_FILTER_LINEAR;
104  break;
105  };
106 
107  if (s->vkctx.output_format == s->vkctx.input_format) {
108  mode = MODE_COPY;
109  } else {
110  switch (s->vkctx.output_format) {
111  case AV_PIX_FMT_NV12: mode = MODE_NV12; break;
112  case AV_PIX_FMT_YUV420P: mode = MODE_YUV420; break;
113  case AV_PIX_FMT_YUV444P: mode = MODE_YUV444; break;
114  default: return AVERROR(EINVAL);
115  }
116  }
117 
118  RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
119 
120  RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode));
121 
122  SPEC_LIST_CREATE(sl, 3, 3*sizeof(int32_t))
123  SPEC_LIST_ADD(sl, 0, 32, out_planes);
124  SPEC_LIST_ADD(sl, 1, 32, mode);
125  SPEC_LIST_ADD(sl, 2, 32, s->out_range == AVCOL_RANGE_JPEG);
126 
127  ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
128  (uint32_t []) { 32, 32, 1 }, 0);
129 
131  {
132  .name = "input_img",
133  .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
134  .elems = in_planes,
135  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
136  .samplers = DUP_SAMPLER(s->sampler),
137  },
138  {
139  .name = "output_img",
140  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
141  .elems = out_planes,
142  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
143  },
144  };
145 
146  ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0);
147 
148  ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
149  VK_SHADER_STAGE_COMPUTE_BIT);
150 
151  if (mode != MODE_COPY) {
152  const AVLumaCoefficients *lcoeffs;
153  double tmp_mat[3][3];
154 
156  if (!lcoeffs) {
157  av_log(ctx, AV_LOG_ERROR, "Unsupported colorspace\n");
158  err = AVERROR(EINVAL);
159  goto fail;
160  }
161 
162  ff_fill_rgb2yuv_table(lcoeffs, tmp_mat);
163 
164  for (int y = 0; y < 3; y++)
165  for (int x = 0; x < 3; x++)
166  s->opts.yuv_matrix[x][y] = tmp_mat[x][y];
167  s->opts.yuv_matrix[3][3] = 1.0;
168  }
169 
170  s->opts.in_dims[0] = in->width;
171  s->opts.in_dims[1] = in->height;
172 
173  RET(ff_vk_shader_link(vkctx, shd,
175  ff_scale_comp_spv_len, "main"));
176 
177  RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
178 
179  s->initialized = 1;
180 
181 fail:
182  return err;
183 }
184 
186 {
187  int err;
188  ScaleVulkanContext *s = ctx->priv;
189  FFVulkanContext *vkctx = &s->vkctx;
190  FFVulkanShader *shd = &s->shd;
191 
192  RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*2, 0, 0, 0, NULL));
193 
194  SPEC_LIST_CREATE(sl, 1, 1*sizeof(int32_t))
195  SPEC_LIST_ADD(sl, 0, 32, s->debayer);
196  ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
197  (uint32_t []) { 32, 32, 1 }, 0);
198 
199  ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
200  VK_SHADER_STAGE_COMPUTE_BIT);
201 
203  {
204  .name = "src",
205  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
206  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
207  },
208  {
209  .name = "dst",
210  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
211  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
212  },
213  };
214  ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0);
215 
216  RET(ff_vk_shader_link(vkctx, shd,
218  ff_debayer_comp_spv_len, "main"));
219 
220  RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
221 
222  shd->lg_size[0] <<= 1;
223  shd->lg_size[1] <<= 1;
224 
225  s->initialized = 1;
226 
227 fail:
228  return err;
229 }
230 
232 {
233  int err;
234  AVFilterContext *ctx = link->dst;
235  ScaleVulkanContext *s = ctx->priv;
236  AVFilterLink *outlink = ctx->outputs[0];
237 
238  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
239  if (!out) {
240  err = AVERROR(ENOMEM);
241  goto fail;
242  }
243 
244  s->opts.crop_x = in->crop_left;
245  s->opts.crop_y = in->crop_top;
246  s->opts.crop_w = in->width - (in->crop_left + in->crop_right);
247  s->opts.crop_h = in->height - (in->crop_top + in->crop_bottom);
248 
249  err = av_frame_copy_props(out, in);
250  if (err < 0)
251  goto fail;
252 
253  if (out->width != in->width || out->height != in->height) {
254  av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data,
256  }
257 
258  if (s->out_range != AVCOL_RANGE_UNSPECIFIED)
259  out->color_range = s->out_range;
260  if (s->vkctx.output_format != s->vkctx.input_format)
261  out->chroma_location = AVCHROMA_LOC_TOPLEFT;
262 
263  if (!s->sws) {
264  if (!s->initialized) {
265  s->qf = ff_vk_qf_find(&s->vkctx, VK_QUEUE_COMPUTE_BIT, 0);
266  if (!s->qf) {
267  av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
268  err = AVERROR(ENOTSUP);
269  goto fail;
270  }
271 
272  if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16)
273  RET(init_debayer(ctx, in));
274  else
275  RET(init_filter(ctx, in));
276  }
277 
278  RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
279  s->sampler, 1, &s->opts, sizeof(s->opts)));
280  } else {
281  err = sws_scale_frame(s->sws, out, in);
282  if (err < 0)
283  goto fail;
284  }
285 
286  av_frame_free(&in);
287 
288  return ff_filter_frame(outlink, out);
289 
290 fail:
291  av_frame_free(&in);
292  av_frame_free(&out);
293  return err;
294 }
295 
297 {
298  int err;
299  AVFilterContext *avctx = outlink->src;
300  ScaleVulkanContext *s = avctx->priv;
301  FFVulkanContext *vkctx = &s->vkctx;
302  AVFilterLink *inlink = outlink->src->inputs[0];
303 
304  err = ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
305  &vkctx->output_width,
306  &vkctx->output_height);
307  if (err < 0)
308  return err;
309 
311  SCALE_FORCE_OAR_DISABLE, 1, 1.f);
312  if (err < 0)
313  return err;
314 
315  outlink->w = vkctx->output_width;
316  outlink->h = vkctx->output_height;
317 
318  if (s->out_format_string) {
319  s->vkctx.output_format = av_get_pix_fmt(s->out_format_string);
320  if (s->vkctx.output_format == AV_PIX_FMT_NONE) {
321  av_log(avctx, AV_LOG_ERROR, "Invalid output format.\n");
322  return AVERROR(EINVAL);
323  }
324  } else {
325  s->vkctx.output_format = s->vkctx.input_format;
326  }
327 
328  if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16) {
329  if (s->vkctx.output_format == s->vkctx.input_format) {
330  s->vkctx.output_format = AV_PIX_FMT_RGBA64;
331  } else if (!ff_vk_mt_is_np_rgb(s->vkctx.output_format)) {
332  av_log(avctx, AV_LOG_ERROR, "Unsupported output format for debayer\n");
333  return AVERROR(EINVAL);
334  }
335  if (inlink->w != outlink->w || inlink->w != outlink->w) {
336  av_log(avctx, AV_LOG_ERROR, "Scaling is not supported with debayering\n");
337  return AVERROR_PATCHWELCOME;
338  }
339  } else if ((inlink->w == outlink->w || inlink->h == outlink->h) &&
340  (s->vkctx.input_format != s->vkctx.output_format)) {
341  s->sws = sws_alloc_context();
342  if (!s->sws)
343  return AVERROR(ENOMEM);
344  av_opt_set(s->sws, "sws_flags", "unstable", 0);
345  av_opt_set(s->sws, "scaler",
346  s->scaler == F_NEAREST ? "point" : "bilinear", 0);
347  } else if (s->vkctx.output_format != s->vkctx.input_format) {
348  if (!ff_vk_mt_is_np_rgb(s->vkctx.input_format)) {
349  av_log(avctx, AV_LOG_ERROR, "Unsupported input format for conversion\n");
350  return AVERROR(EINVAL);
351  }
352  if (s->vkctx.output_format != AV_PIX_FMT_NV12 &&
353  s->vkctx.output_format != AV_PIX_FMT_YUV420P &&
354  s->vkctx.output_format != AV_PIX_FMT_YUV444P) {
355  av_log(avctx, AV_LOG_ERROR, "Unsupported output format\n");
356  return AVERROR(EINVAL);
357  }
358  } else if (s->out_range != AVCOL_RANGE_UNSPECIFIED) {
359  av_log(avctx, AV_LOG_ERROR, "Cannot change range without converting format\n");
360  return AVERROR(EINVAL);
361  }
362 
363  return ff_vk_filter_config_output(outlink);
364 }
365 
367 {
368  ScaleVulkanContext *s = avctx->priv;
369  FFVulkanContext *vkctx = &s->vkctx;
370  FFVulkanFunctions *vk = &vkctx->vkfn;
371 
372  ff_vk_exec_pool_free(vkctx, &s->e);
373  ff_vk_shader_free(vkctx, &s->shd);
374  sws_free_context(&s->sws);
375 
376  if (s->sampler)
377  vk->DestroySampler(vkctx->hwctx->act_dev, s->sampler,
378  vkctx->hwctx->alloc);
379 
380  ff_vk_uninit(&s->vkctx);
381 
382  s->initialized = 0;
383 }
384 
385 #define OFFSET(x) offsetof(ScaleVulkanContext, x)
386 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
387 static const AVOption scale_vulkan_options[] = {
388  { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = FLAGS },
389  { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
390  { "scaler", "Scaler function", OFFSET(scaler), AV_OPT_TYPE_INT, {.i64 = F_BILINEAR}, 0, F_NB, .flags = FLAGS, .unit = "scaler" },
391  { "bilinear", "Bilinear interpolation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = F_BILINEAR}, 0, 0, .flags = FLAGS, .unit = "scaler" },
392  { "nearest", "Nearest (useful for pixel art)", 0, AV_OPT_TYPE_CONST, {.i64 = F_NEAREST}, 0, 0, .flags = FLAGS, .unit = "scaler" },
393  { "debayer", "Debayer algorithm to use", OFFSET(debayer), AV_OPT_TYPE_INT, {.i64 = DB_BILINEAR_HQ}, 0, DB_NB, .flags = FLAGS, .unit = "debayer" },
394  { "bilinear", "Bilinear debayering (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = DB_BILINEAR}, 0, 0, .flags = FLAGS, .unit = "debayer" },
395  { "bilinear_hq", "Bilinear debayering (high quality)", 0, AV_OPT_TYPE_CONST, {.i64 = DB_BILINEAR_HQ}, 0, 0, .flags = FLAGS, .unit = "debayer" },
396  { "format", "Output video format (software format of hardware frames)", OFFSET(out_format_string), AV_OPT_TYPE_STRING, .flags = FLAGS },
397  { "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" },
398  { "full", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
399  { "limited", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
400  { "jpeg", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
401  { "mpeg", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
402  { "tv", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
403  { "pc", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
404  { NULL },
405 };
406 
407 AVFILTER_DEFINE_CLASS(scale_vulkan);
408 
410  {
411  .name = "default",
412  .type = AVMEDIA_TYPE_VIDEO,
413  .filter_frame = &scale_vulkan_filter_frame,
414  .config_props = &ff_vk_filter_config_input,
415  },
416 };
417 
419  {
420  .name = "default",
421  .type = AVMEDIA_TYPE_VIDEO,
422  .config_props = &scale_vulkan_config_output,
423  },
424 };
425 
427  .p.name = "scale_vulkan",
428  .p.description = NULL_IF_CONFIG_SMALL("Scale Vulkan frames"),
429  .p.priv_class = &scale_vulkan_class,
430  .p.flags = AVFILTER_FLAG_HWDEVICE,
431  .priv_size = sizeof(ScaleVulkanContext),
437  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
438 };
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:89
init_debayer
static av_cold int init_debayer(AVFilterContext *ctx, AVFrame *in)
Definition: vf_scale_vulkan.c:185
FFVulkanContext::output_height
int output_height
Definition: vulkan.h:324
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
SCALE_FORCE_OAR_DISABLE
@ SCALE_FORCE_OAR_DISABLE
Definition: scale_eval.h:25
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2680
out
static FILE * out
Definition: movenc.c:55
ScaleVulkanContext::opts
struct ScaleVulkanContext::@450 opts
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1068
RET
#define RET(x)
Definition: vulkan.h:34
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:357
av_cold
#define av_cold
Definition: attributes.h:119
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
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:208
DB_NB
@ DB_NB
Definition: vf_scale_vulkan.c:46
ff_debayer_comp_spv_data
const unsigned char ff_debayer_comp_spv_data[]
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:734
mode
Definition: swscale.c:71
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
OFFSET
#define OFFSET(x)
Definition: vf_scale_vulkan.c:385
AVFrame::width
int width
Definition: frame.h:544
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:783
scale_vulkan_outputs
static const AVFilterPad scale_vulkan_outputs[]
Definition: vf_scale_vulkan.c:418
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
AVOption
AVOption.
Definition: opt.h:428
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: filters.h:254
DB_BILINEAR_HQ
@ DB_BILINEAR_HQ
Definition: vf_scale_vulkan.c:44
filters.h
scale_vulkan_options
static const AVOption scale_vulkan_options[]
Definition: vf_scale_vulkan.c:387
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:58
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:2704
SPEC_LIST_ADD
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition: vulkan.h:52
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:219
ScaleVulkanContext::sampler
VkSampler sampler
Definition: vf_scale_vulkan.c:65
video.h
ScaleVulkanContext::yuv_matrix
float yuv_matrix[4][4]
Definition: vf_scale_vulkan.c:69
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
ScaleVulkanContext::e
FFVkExecPool e
Definition: vf_scale_vulkan.c:62
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(scale_vulkan)
ScalerFunc
ScalerFunc
Definition: vf_scale_vulkan.c:35
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3500
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, uint32_t wgc_z, 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
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:288
MODE_NV12
@ MODE_NV12
Definition: vf_scale_vulkan.c:52
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:2473
DebayerFunc
DebayerFunc
Definition: vf_scale_vulkan.c:42
ScaleVulkanContext::in_dims
float in_dims[2]
Definition: vf_scale_vulkan.c:74
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:824
ff_scale_comp_spv_data
const unsigned char ff_scale_comp_spv_data[]
AV_SIDE_DATA_PROP_SIZE_DEPENDENT
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
Definition: frame.h:354
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:40
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FFFilter
Definition: filters.h:267
ff_scale_comp_spv_len
const unsigned int ff_scale_comp_spv_len
FFVulkanContext::output_width
int output_width
Definition: vulkan.h:323
F_NEAREST
@ F_NEAREST
Definition: vf_scale_vulkan.c:37
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:265
F_BILINEAR
@ F_BILINEAR
Definition: vf_scale_vulkan.c:36
MODE_YUV420
@ MODE_YUV420
Definition: vf_scale_vulkan.c:53
scale_vulkan_filter_frame
static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_scale_vulkan.c:231
ScaleVulkanContext::crop_x
int crop_x
Definition: vf_scale_vulkan.c:70
ff_vf_scale_vulkan
const FFFilter ff_vf_scale_vulkan
Definition: vf_scale_vulkan.c:426
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
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:299
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
fail
#define fail
Definition: test.h:478
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:535
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
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:599
DUP_SAMPLER
#define DUP_SAMPLER(x)
Definition: vulkan.h:70
scale_vulkan_uninit
static void scale_vulkan_uninit(AVFilterContext *avctx)
Definition: vf_scale_vulkan.c:366
ScaleVulkanContext::h_expr
char * h_expr
Definition: vf_scale_vulkan.c:79
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:806
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:281
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:209
ff_vk_shader_link
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition: vulkan.c:2333
ScaleVulkanContext::debayer
enum DebayerFunc debayer
Definition: vf_scale_vulkan.c:83
SPEC_LIST_CREATE
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition: vulkan.h:42
ScaleVulkanContext::crop_h
int crop_h
Definition: vf_scale_vulkan.c:73
FFVulkanContext
Definition: vulkan.h:275
ScaleVulkanContext::out_range
enum AVColorRange out_range
Definition: vf_scale_vulkan.c:82
F_NB
@ F_NB
Definition: vf_scale_vulkan.c:39
FLAGS
#define FLAGS
Definition: vf_scale_vulkan.c:386
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:749
ScaleVulkanContext::vkctx
FFVulkanContext vkctx
Definition: vf_scale_vulkan.c:58
AVFrame::crop_bottom
size_t crop_bottom
Definition: frame.h:796
AVFrame::crop_left
size_t crop_left
Definition: frame.h:797
ScaleVulkanContext::qf
AVVulkanDeviceQueueFamily * qf
Definition: vf_scale_vulkan.c:63
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
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:88
MODE_COPY
@ MODE_COPY
Definition: vf_scale_vulkan.c:51
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1032
AVFILTER_FLAG_HWDEVICE
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition: avfilter.h:187
FFVulkanShader
Definition: vulkan.h:191
ScaleVulkanContext::crop_y
int crop_y
Definition: vf_scale_vulkan.c:71
scale_eval.h
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:1569
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: side_data.c:123
ScaleVulkanContext::scaler
enum ScalerFunc scaler
Definition: vf_scale_vulkan.c:81
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:78
s
uint8_t s
Definition: llvidencdsp.c:39
MODE_YUV444
@ MODE_YUV444
Definition: vf_scale_vulkan.c:54
scale_vulkan_inputs
static const AVFilterPad scale_vulkan_inputs[]
Definition: vf_scale_vulkan.c:409
uninit
static av_cold void uninit(AVBitStreamFilterContext *ctx)
Definition: lcevc_merge.c:135
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:46
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:766
ff_vk_shader_add_descriptor_set
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
Definition: vulkan.c:2439
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:279
FFVkExecPool
Definition: vulkan.h:253
ScaleVulkanContext::shd
FFVulkanShader shd
Definition: vf_scale_vulkan.c:64
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:1509
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:264
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:286
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3392
AVFrame::height
int height
Definition: frame.h:544
ScaleVulkanContext::initialized
int initialized
Definition: vf_scale_vulkan.c:61
mode
mode
Definition: ebur128.h:83
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:258
ScaleVulkanContext::sws
SwsContext * sws
Definition: vf_scale_vulkan.c:59
FFVulkanShader::lg_size
uint32_t lg_size[3]
Definition: vulkan.h:200
ScaleVulkanContext::crop_w
int crop_w
Definition: vf_scale_vulkan.c:72
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:273
ScaleVulkanContext
Definition: vf_scale_vulkan.c:57
desc
const char * desc
Definition: libsvtav1.c:83
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:271
FFVulkanContext::hwctx
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:312
sws_scale_frame
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image dimensions or settings change in any way sws_scale_frame() is itself just a light-weight wrapper that runs ff_sws_graph_reinit() initially and on format changes
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:1520
AVFrame::crop_top
size_t crop_top
Definition: frame.h:795
sws_free_context
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
Definition: utils.c:2323
int32_t
int32_t
Definition: audioconvert.c:56
scale_vulkan_config_output
static int scale_vulkan_config_output(AVFilterLink *outlink)
Definition: vf_scale_vulkan.c:296
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVVulkanDeviceQueueFamily
Definition: hwcontext_vulkan.h:33
DB_BILINEAR
@ DB_BILINEAR
Definition: vf_scale_vulkan.c:43
init_filter
static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
Definition: vf_scale_vulkan.c:86
ScaleMode
ScaleMode
Definition: vf_scale_vulkan.c:50
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:275
AV_PIX_FMT_BAYER_RGGB16
#define AV_PIX_FMT_BAYER_RGGB16
Definition: pixfmt.h:578
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:748
SwsContext
Main external API structure.
Definition: swscale.h:227
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
FFVulkanFunctions
Definition: vulkan_functions.h:275
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, double w_adj)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition: scale_eval.c:123
ff_vk_shader_load
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
Definition: vulkan.c:2136
ScaleVulkanContext::out_format_string
char * out_format_string
Definition: vf_scale_vulkan.c:77
swscale.h
ff_debayer_comp_spv_len
const unsigned int ff_debayer_comp_spv_len