FFmpeg
Loading...
Searching...
No Matches
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 "formats.h"
26#include "colorspace.h"
27#include "video.h"
28#include "libswscale/swscale.h"
29
30extern const unsigned char ff_scale_comp_spv_data[];
31extern const unsigned int ff_scale_comp_spv_len;
32
33extern const unsigned char ff_debayer_comp_spv_data[];
34extern const unsigned int ff_debayer_comp_spv_len;
35
42
49
50/* Output modes, must match scale.comp.glsl */
57
88
90{
91 int err;
92 VkFilter sampler_mode;
93 enum ScaleMode mode;
94 ScaleVulkanContext *s = ctx->priv;
95 FFVulkanContext *vkctx = &s->vkctx;
96 FFVulkanShader *shd = &s->shd;
97 const AVPixFmtDescriptor *in_desc = av_pix_fmt_desc_get(s->vkctx.input_format);
98 int chroma_planes = 0;
99
100 int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format);
101 int out_planes = av_pix_fmt_count_planes(s->vkctx.output_format);
103
104 switch (s->scaler) {
105 case F_NEAREST:
106 sampler_mode = VK_FILTER_NEAREST;
107 break;
108 case F_BILINEAR:
109 sampler_mode = VK_FILTER_LINEAR;
110 break;
111 };
112
113 if (s->vkctx.output_format == s->vkctx.input_format) {
114 mode = MODE_COPY;
115 if (in_desc->log2_chroma_w || in_desc->log2_chroma_h)
116 chroma_planes = (1 << in_desc->comp[1].plane) | (1 << in_desc->comp[2].plane);
117 } else {
118 switch (s->vkctx.output_format) {
119 case AV_PIX_FMT_NV12: mode = MODE_NV12; break;
120 case AV_PIX_FMT_YUV420P: mode = MODE_YUV420; break;
121 case AV_PIX_FMT_YUV444P: mode = MODE_YUV444; break;
122 default: return AVERROR(EINVAL);
123 }
124 }
125
126 RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, FF_VK_DEFAULT_EXEC_CONTEXTS, 0, 0, 0, NULL));
127
128 RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode));
129
130 SPEC_LIST_CREATE(sl, 6, 6*sizeof(int32_t))
131 SPEC_LIST_ADD(sl, 0, 32, out_planes);
132 SPEC_LIST_ADD(sl, 1, 32, mode);
133 SPEC_LIST_ADD(sl, 2, 32, s->out_range == AVCOL_RANGE_JPEG);
134 SPEC_LIST_ADD(sl, 3, 32, chroma_planes);
135 SPEC_LIST_ADD(sl, 4, 32, in_desc->log2_chroma_w);
136 SPEC_LIST_ADD(sl, 5, 32, in_desc->log2_chroma_h);
137
138 ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
139 (uint32_t []) { 32, 32, 1 }, 0);
140
142 {
143 .name = "input_img",
144 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
145 .elems = in_planes,
146 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
147 .samplers = DUP_SAMPLER(s->sampler),
148 },
149 {
150 .name = "output_img",
151 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
152 .elems = out_planes,
153 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
154 },
155 };
156
157 ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0);
158
159 ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
160 VK_SHADER_STAGE_COMPUTE_BIT);
161
162 if (mode != MODE_COPY) {
163 const AVLumaCoefficients *lcoeffs;
164 double tmp_mat[3][3];
165
167 if (!lcoeffs) {
168 av_log(ctx, AV_LOG_ERROR, "Unsupported colorspace\n");
169 err = AVERROR(EINVAL);
170 goto fail;
171 }
172
173 ff_fill_rgb2yuv_table(lcoeffs, tmp_mat);
174
175 for (int y = 0; y < 3; y++)
176 for (int x = 0; x < 3; x++)
177 s->opts.yuv_matrix[x][y] = tmp_mat[x][y];
178 s->opts.yuv_matrix[3][3] = 1.0;
179 }
180
181 /* Normalized texture coordinates include hardware frame padding. */
182 s->opts.in_dims[0] = frames->width;
183 s->opts.in_dims[1] = frames->height;
184
185 RET(ff_vk_shader_link(vkctx, shd,
187 ff_scale_comp_spv_len, "main"));
188
189 RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
190
191 s->initialized = 1;
192
193fail:
194 return err;
195}
196
198{
199 int err;
200 ScaleVulkanContext *s = ctx->priv;
201 FFVulkanContext *vkctx = &s->vkctx;
202 FFVulkanShader *shd = &s->shd;
203
204 RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, FF_VK_DEFAULT_EXEC_CONTEXTS, 0, 0, 0, NULL));
205
206 SPEC_LIST_CREATE(sl, 1, 1*sizeof(int32_t))
207 SPEC_LIST_ADD(sl, 0, 32, s->debayer);
208 ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
209 (uint32_t []) { 32, 32, 1 }, 0);
210
211 ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
212 VK_SHADER_STAGE_COMPUTE_BIT);
213
215 {
216 .name = "src",
217 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
218 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
219 },
220 {
221 .name = "dst",
222 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
223 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
224 },
225 };
226 ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0);
227
228 RET(ff_vk_shader_link(vkctx, shd,
230 ff_debayer_comp_spv_len, "main"));
231
232 RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
233
234 shd->lg_size[0] <<= 1;
235 shd->lg_size[1] <<= 1;
236
237 s->initialized = 1;
238
239fail:
240 return err;
241}
242
243static void chroma_loc_offset(float offset[2], enum AVChromaLocation loc,
245{
246 int x, y;
247
248 if (loc == AVCHROMA_LOC_UNSPECIFIED)
251 offset[0] = x * ((1 << desc->log2_chroma_w) - 1) / 256.0f;
252 offset[1] = y * ((1 << desc->log2_chroma_h) - 1) / 256.0f;
253}
254
256{
257 int err;
258 AVFilterContext *ctx = link->dst;
259 ScaleVulkanContext *s = ctx->priv;
260 AVFilterLink *outlink = ctx->outputs[0];
261 const AVPixFmtDescriptor *in_desc = av_pix_fmt_desc_get(s->vkctx.input_format);
262 const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(s->vkctx.output_format);
263
264 AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
265 if (!out) {
266 err = AVERROR(ENOMEM);
267 goto fail;
268 }
269
270 s->opts.crop_x = in->crop_left;
271 s->opts.crop_y = in->crop_top;
272 s->opts.crop_w = in->width - (in->crop_left + in->crop_right);
273 s->opts.crop_h = in->height - (in->crop_top + in->crop_bottom);
274
275 err = av_frame_copy_props(out, in);
276 if (err < 0)
277 goto fail;
278
279 if (out->width != in->width || out->height != in->height) {
280 av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data,
282 }
283
284 if (s->out_range != AVCOL_RANGE_UNSPECIFIED)
285 out->color_range = s->out_range;
287 out->chroma_location = outlink->chroma_location;
288 else if (s->vkctx.output_format != s->vkctx.input_format &&
289 !in_desc->log2_chroma_w && !in_desc->log2_chroma_h)
290 out->chroma_location = AVCHROMA_LOC_TOPLEFT;
291
292 if (!s->sws) {
293 if (!s->initialized) {
294 s->qf = ff_vk_qf_find(&s->vkctx, VK_QUEUE_COMPUTE_BIT, 0);
295 if (!s->qf) {
296 av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
297 err = AVERROR(ENOTSUP);
298 goto fail;
299 }
300
301 if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16)
302 RET(init_debayer(ctx, in));
303 else
304 RET(init_filter(ctx, in));
305 }
306
307 /* Input without a chroma location is assumed to be sited like the output. */
308 chroma_loc_offset(s->opts.in_chroma_loc,
310 in->chroma_location : out->chroma_location, in_desc);
311 chroma_loc_offset(s->opts.out_chroma_loc, out->chroma_location, out_desc);
312
313 RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
314 s->sampler, 1, &s->opts, sizeof(s->opts)));
315 } else {
316 err = sws_scale_frame(s->sws, out, in);
317 if (err < 0)
318 goto fail;
319 }
320
321 av_frame_free(&in);
322
323 return ff_filter_frame(outlink, out);
324
325fail:
326 av_frame_free(&in);
328 return err;
329}
330
332{
333 int err;
334 AVFilterContext *avctx = outlink->src;
335 ScaleVulkanContext *s = avctx->priv;
336 FFVulkanContext *vkctx = &s->vkctx;
337 AVFilterLink *inlink = outlink->src->inputs[0];
338
339 err = ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
340 &vkctx->output_width,
341 &vkctx->output_height);
342 if (err < 0)
343 return err;
344
345 err = ff_scale_adjust_dimensions(inlink, &vkctx->output_width, &vkctx->output_height,
347 if (err < 0)
348 return err;
349
350 outlink->w = vkctx->output_width;
351 outlink->h = vkctx->output_height;
352
353 if (s->out_format_string) {
354 s->vkctx.output_format = av_get_pix_fmt(s->out_format_string);
355 if (s->vkctx.output_format == AV_PIX_FMT_NONE) {
356 av_log(avctx, AV_LOG_ERROR, "Invalid output format.\n");
357 return AVERROR(EINVAL);
358 }
359 } else {
360 s->vkctx.output_format = s->vkctx.input_format;
361 }
362
363 if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16) {
364 if (s->vkctx.output_format == s->vkctx.input_format) {
365 s->vkctx.output_format = AV_PIX_FMT_RGBA64;
366 } else if (!ff_vk_mt_is_np_rgb(s->vkctx.output_format)) {
367 av_log(avctx, AV_LOG_ERROR, "Unsupported output format for debayer\n");
368 return AVERROR(EINVAL);
369 }
370 if (inlink->w != outlink->w || inlink->w != outlink->w) {
371 av_log(avctx, AV_LOG_ERROR, "Scaling is not supported with debayering\n");
373 }
374 } else if ((inlink->w == outlink->w || inlink->h == outlink->h) &&
375 (s->vkctx.input_format != s->vkctx.output_format)) {
376 s->sws = sws_alloc_context();
377 if (!s->sws)
378 return AVERROR(ENOMEM);
379 av_opt_set(s->sws, "sws_flags", "unstable", 0);
380 av_opt_set(s->sws, "scaler",
381 s->scaler == F_NEAREST ? "point" : "bilinear", 0);
382 } else if (s->vkctx.output_format != s->vkctx.input_format) {
383 if (!ff_vk_mt_is_np_rgb(s->vkctx.input_format)) {
384 av_log(avctx, AV_LOG_ERROR, "Unsupported input format for conversion\n");
385 return AVERROR(EINVAL);
386 }
387 if (s->vkctx.output_format != AV_PIX_FMT_NV12 &&
388 s->vkctx.output_format != AV_PIX_FMT_YUV420P &&
389 s->vkctx.output_format != AV_PIX_FMT_YUV444P) {
390 av_log(avctx, AV_LOG_ERROR, "Unsupported output format\n");
391 return AVERROR(EINVAL);
392 }
393 } else if (s->out_range != AVCOL_RANGE_UNSPECIFIED) {
394 av_log(avctx, AV_LOG_ERROR, "Cannot change range without converting format\n");
395 return AVERROR(EINVAL);
396 }
397
398 return ff_vk_filter_config_output(outlink);
399}
400
402 AVFilterFormatsConfig **cfg_in,
403 AVFilterFormatsConfig **cfg_out)
404{
405 int err;
406
407 err = ff_set_common_formats2(avctx, cfg_in, cfg_out,
409 if (err < 0)
410 return err;
411
412 err = ff_formats_ref(ff_all_chroma_locations(), &cfg_in[0]->chroma_locations);
413 if (err < 0)
414 return err;
415
416 return ff_formats_ref(ff_all_chroma_locations(), &cfg_out[0]->chroma_locations);
417}
418
420{
421 ScaleVulkanContext *s = avctx->priv;
422 FFVulkanContext *vkctx = &s->vkctx;
423 FFVulkanFunctions *vk = &vkctx->vkfn;
424
425 ff_vk_exec_pool_free(vkctx, &s->e);
426 ff_vk_shader_free(vkctx, &s->shd);
427 sws_free_context(&s->sws);
428
429 if (s->sampler)
430 vk->DestroySampler(vkctx->hwctx->act_dev, s->sampler,
431 vkctx->hwctx->alloc);
432
433 ff_vk_uninit(&s->vkctx);
434
435 s->initialized = 0;
436}
437
438#define OFFSET(x) offsetof(ScaleVulkanContext, x)
439#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
441 { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = FLAGS },
442 { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
443 { "scaler", "Scaler function", OFFSET(scaler), AV_OPT_TYPE_INT, {.i64 = F_BILINEAR}, 0, F_NB, .flags = FLAGS, .unit = "scaler" },
444 { "bilinear", "Bilinear interpolation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = F_BILINEAR}, 0, 0, .flags = FLAGS, .unit = "scaler" },
445 { "nearest", "Nearest (useful for pixel art)", 0, AV_OPT_TYPE_CONST, {.i64 = F_NEAREST}, 0, 0, .flags = FLAGS, .unit = "scaler" },
446 { "debayer", "Debayer algorithm to use", OFFSET(debayer), AV_OPT_TYPE_INT, {.i64 = DB_BILINEAR_HQ}, 0, DB_NB, .flags = FLAGS, .unit = "debayer" },
447 { "bilinear", "Bilinear debayering (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = DB_BILINEAR}, 0, 0, .flags = FLAGS, .unit = "debayer" },
448 { "bilinear_hq", "Bilinear debayering (high quality)", 0, AV_OPT_TYPE_CONST, {.i64 = DB_BILINEAR_HQ}, 0, 0, .flags = FLAGS, .unit = "debayer" },
449 { "format", "Output video format (software format of hardware frames)", OFFSET(out_format_string), AV_OPT_TYPE_STRING, .flags = FLAGS },
450 { "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" },
451 { "full", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
452 { "limited", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
453 { "jpeg", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
454 { "mpeg", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
455 { "tv", "Limited range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, .unit = "range" },
456 { "pc", "Full range", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, .unit = "range" },
457 { NULL },
458};
459
461
463 {
464 .name = "default",
465 .type = AVMEDIA_TYPE_VIDEO,
466 .filter_frame = &scale_vulkan_filter_frame,
467 .config_props = &ff_vk_filter_config_input,
468 },
469};
470
472 {
473 .name = "default",
474 .type = AVMEDIA_TYPE_VIDEO,
475 .config_props = &scale_vulkan_config_output,
476 },
477};
478
480 .p.name = "scale_vulkan",
481 .p.description = NULL_IF_CONFIG_SMALL("Scale Vulkan frames"),
482 .p.priv_class = &scale_vulkan_class,
483 .p.flags = AVFILTER_FLAG_HWDEVICE,
484 .priv_size = sizeof(ScaleVulkanContext),
490 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
491};
const FFFilter ff_vf_scale_vulkan
static FILE * out
static int frames
static AVFormatContext * ctx
static AVDictionary * opts
int32_t
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1073
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:596
#define NULL
Definition coverity.c:32
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add ref as a new reference to formats.
Definition formats.c:776
AVFilterFormats * ff_make_formats_list_singleton(int fmt)
Equivalent to ff_make_format_list({const int[]}{ fmt, -1 })
Definition formats.c:605
int ff_set_common_formats2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, AVFilterFormats *formats)
Definition formats.c:1200
AVFilterFormats * ff_all_chroma_locations(void)
Construct an AVFilterFormats representing all possible chroma locations.
Definition formats.c:744
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ 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
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition avfilter.h:193
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR(e)
Definition error.h:45
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:124
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
Definition frame.h:361
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
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
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Scale source data from src and write the output to dst.
Definition swscale.c:1405
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition utils.c:1051
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
Definition utils.c:2374
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:891
static av_cold void uninit(AVBitStreamFilterContext *ctx)
unsigned offset
Definition libaomenc.c:763
void ff_fill_rgb2yuv_table(const AVLumaCoefficients *coeffs, double rgb2yuv[3][3])
Definition colorspace.c:125
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#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
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define FILTER_QUERY_FUNC2(func)
Definition filters.h:241
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
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:2262
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:2521
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:335
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:399
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1631
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2779
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2757
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2555
int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, int unnorm_coords, VkFilter filt)
Create a sampler.
Definition vulkan.c:1642
int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt)
Returns 1 if pixfmt is a usable RGB format.
Definition vulkan.c:1692
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:320
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:2425
const char * desc
Definition libsvtav1.c:83
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition pixdesc.c:3392
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
int av_chroma_location_enum_to_pos(int *xpos, int *ypos, enum AVChromaLocation pos)
Converts AVChromaLocation to swscale x/y chroma position.
Definition pixdesc.c:3902
AVChromaLocation
Location of chroma samples.
Definition pixfmt.h:802
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition pixfmt.h:806
@ AVCHROMA_LOC_CENTER
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
Definition pixfmt.h:805
@ AVCHROMA_LOC_UNSPECIFIED
Definition pixfmt.h:803
AVColorRange
Visual content value range.
Definition pixfmt.h:748
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_RGBA64
Definition pixfmt.h:535
#define AV_PIX_FMT_BAYER_RGGB16
Definition pixfmt.h:578
@ 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
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
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
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
@ SCALE_FORCE_OAR_DISABLE
Definition scale_eval.h:25
uint8_t * data
The data buffer.
Definition buffer.h:90
int plane
Which of the 4 planes contains the component.
Definition pixdesc.h:34
An instance of a filter.
Definition avfilter.h:279
AVFilterLink ** inputs
array of pointers to input links
Definition avfilter.h:287
void * priv
private data for use by the filter
Definition avfilter.h:294
Lists of formats / etc.
Definition avfilter.h:120
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
size_t crop_right
Definition frame.h:805
enum AVChromaLocation chroma_location
Definition frame.h:743
int width
Definition frame.h:551
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition frame.h:776
int height
Definition frame.h:551
size_t crop_top
Definition frame.h:802
enum AVColorSpace colorspace
YUV colorspace type.
Definition frame.h:741
size_t crop_left
Definition frame.h:804
size_t crop_bottom
Definition frame.h:803
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar calculations.
Definition csp.h:48
AVOption.
Definition opt.h:428
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition pixdesc.h:105
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition pixdesc.h:80
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition pixdesc.h:89
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
VkDevice act_dev
Active device.
int output_height
Definition vulkan.h:352
AVVulkanDeviceContext * hwctx
Definition vulkan.h:340
FFVulkanFunctions vkfn
Definition vulkan.h:296
uint32_t lg_size[3]
Definition vulkan.h:219
enum DebayerFunc debayer
enum AVColorRange out_range
FFVulkanContext vkctx
enum ScalerFunc scaler
AVVulkanDeviceQueueFamily * qf
FFVulkanShader shd
Main external API structure.
Definition swscale.h:227
Definition swscale.c:71
external API header
#define av_log(a,...)
static int scale_vulkan_query_formats(const AVFilterContext *avctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
const unsigned int ff_debayer_comp_spv_len
static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
static const AVFilterPad scale_vulkan_outputs[]
static int scale_vulkan_config_output(AVFilterLink *outlink)
static const AVFilterPad scale_vulkan_inputs[]
ScaleMode
@ MODE_YUV444
@ MODE_YUV420
@ MODE_NV12
const unsigned char ff_debayer_comp_spv_data[]
static av_cold int init_debayer(AVFilterContext *ctx, AVFrame *in)
const unsigned char ff_scale_comp_spv_data[]
const unsigned int ff_scale_comp_spv_len
static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ScalerFunc
@ F_BILINEAR
@ F_NEAREST
@ F_NB
#define OFFSET(x)
static void scale_vulkan_uninit(AVFilterContext *avctx)
static const AVOption scale_vulkan_options[]
DebayerFunc
@ DB_BILINEAR_HQ
@ DB_BILINEAR
@ DB_NB
static void chroma_loc_offset(float offset[2], enum AVChromaLocation loc, const AVPixFmtDescriptor *desc)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:90
#define MODE_COPY
Definition vp3.c:93
#define FF_VK_DEFAULT_EXEC_CONTEXTS
Definition vulkan.h:121
#define RET(x)
Definition vulkan.h:37
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition vulkan.h:55
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition vulkan.h:45
#define DUP_SAMPLER(x)
Definition vulkan.h:73
int ff_vk_filter_config_input(AVFilterLink *inlink)
int ff_vk_filter_config_output(AVFilterLink *outlink)
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.
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.