FFmpeg
Loading...
Searching...
No Matches
vulkan_apv.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025 Lynne <dev@lynne.ee>
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 "vulkan_decode.h"
22#include "hwaccel_internal.h"
23
24#include "apv_decode.h"
25#include "libavutil/mem.h"
26
27extern const unsigned char ff_apv_decode_comp_spv_data[];
28extern const unsigned int ff_apv_decode_comp_spv_len;
29
30extern const unsigned char ff_apv_idct_comp_spv_data[];
31extern const unsigned int ff_apv_idct_comp_spv_len;
32
34 .codec_id = AV_CODEC_ID_APV,
35 .queue_flags = VK_QUEUE_COMPUTE_BIT,
36};
37
45
46typedef struct APVVulkanDecodeContext {
49
51
52 /* Flat per-frame coefficient buffer: entropy writes it, the iDCT reads it,
53 * instead of bouncing coefficients through the output image. */
55 size_t coeff_size;
57
58typedef struct DecodePushData {
59 VkDeviceAddress tile_data;
60 int tile_count[2];
65
67 const AVBufferRef *buffer_ref,
68 av_unused const uint8_t *buffer,
69 av_unused uint32_t size)
70{
71 int err;
72 APVDecodeContext *apv = avctx->priv_data;
75 APVVulkanDecodeContext *apvvk = ctx->sd_ctx;
76
78 FFVulkanDecodePicture *vp = &apvvp->vp;
79
80 /* Host map the input tile data if supported */
81 if (ctx->s.extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY)
82 ff_vk_host_map_buffer(&ctx->s, &vp->slices_buf, buffer_ref->data,
83 VK_WHOLE_SIZE, buffer_ref,
84 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
85 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
86
87 /* Allocate frame data buffer */
88 int fd_size = (2*4*APV_MAX_TILE_COUNT)*APV_MAX_NUM_COMP +
91
93 &apvvp->frame_data_buf,
94 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
95 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
96 NULL, fd_size,
97 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
98 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
99 if (err < 0)
100 return err;
101
102 /* Frame data */
104 uint8_t *fd = frame_data->mapped_mem;
105
106 fd += 2*4*APV_MAX_TILE_COUNT*APV_MAX_NUM_COMP; /* Tile offsets go first */
107
108 /* per-component qmatrix and QPs */
109 for (int i = 0; i < APV_MAX_NUM_COMP; i++)
110 memcpy(fd + 64*i,
112 64);
113 fd += 64*APV_MAX_NUM_COMP;
114
115 for (int i = 0; i < APV_MAX_NUM_COMP; i++) {
116 for (int j = 0; j < APV_MAX_TILE_COUNT; j++)
117 fd[j] = apv->cur_raw_frame->tile[j].tile_header.tile_qp[i];
118 fd += APV_MAX_TILE_COUNT;
119 }
120
121 /* tile col/row offset */
122 memcpy(fd, apv->tile_info.col_starts, (APV_MAX_TILE_COLS+1)*2);
123 fd += (APV_MAX_TILE_COLS+1)*2;
124 memcpy(fd, apv->tile_info.row_starts, (APV_MAX_TILE_ROWS+1)*2);
125
126 return 0;
127}
128
130 const uint8_t *data,
131 uint32_t size)
132{
133 APVDecodeContext *apv = avctx->priv_data;
134
136 FFVulkanDecodePicture *vp = &apvvp->vp;
137
139 FFVkBuffer *slices_buf = vp->slices_buf;
140
141 if (slices_buf && slices_buf->host_ref) {
142 AV_WN32(frame_data->mapped_mem + (2*apvvp->tile_num + 0)*sizeof(uint32_t),
143 data - slices_buf->mapped_mem);
144 AV_WN32(frame_data->mapped_mem + (2*apvvp->tile_num + 1)*sizeof(uint32_t),
145 size);
146
147 apvvp->tile_num++;
148 } else {
149 int err = ff_vk_decode_add_slice(avctx, vp, data, size, 0,
150 &apvvp->tile_num,
151 (const uint32_t **)&apvvp->frame_data);
152 if (err < 0)
153 return err;
154
155 AV_WN32(frame_data->mapped_mem + (2*(apvvp->tile_num - 1) + 0)*sizeof(uint32_t),
156 apvvp->frame_data[apvvp->tile_num - 1]);
157 AV_WN32(frame_data->mapped_mem + (2*(apvvp->tile_num - 1) + 1)*sizeof(uint32_t),
158 size);
159 }
160
161 return 0;
162}
163
165{
166 int err;
167 APVDecodeContext *apv = avctx->priv_data;
168 const CodedBitstreamAPVContext *apv_cbc = apv->cbc->priv_data;
171 APVVulkanDecodeContext *apvvk = ctx->sd_ctx;
172 FFVulkanFunctions *vk = &ctx->s.vkfn;
173
175 FFVulkanDecodePicture *vp = &apvvp->vp;
176
177 FFVkBuffer *slices_buf = vp->slices_buf;
178 FFVkBuffer *frame_data_buf = apvvp->frame_data_buf;
179 FFVkBuffer *coeff_buf = NULL;
180
182 enum AVPixelFormat sw_format = hwfc->sw_format;
183 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(sw_format);
184
185 VkImageMemoryBarrier2 img_bar[8];
186 int nb_img_bar = 0;
187 VkBufferMemoryBarrier2 buf_bar[2];
188 int nb_buf_bar = 0;
189
190 FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
191 err = ff_vk_exec_start(&ctx->s, exec);
192 if (err < 0)
193 return err;
194
195 /* Make sure the buffer is flushed */
196 RET(ff_vk_flush_buffer(&ctx->s, frame_data_buf, 0, frame_data_buf->size, 1));
197
198 /* Prepare deps */
200 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
201 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
202
203 /* Exec-owned output views: freed on exec recycle, so releasing a picture
204 * needs no blocking wait. No mirror_sem: nothing consumes vp->sem here. */
205 VkImageView views[AV_NUM_DATA_POINTERS];
206 RET(ff_vk_create_imageviews(&ctx->s, exec, views, apv->output_frame,
208
211
212 AVVkFrame *vkf = (AVVkFrame *)apv->output_frame->data[0];
213 vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
214 vkf->access[0] = VK_ACCESS_2_NONE;
215
216 ff_vk_frame_barrier(&ctx->s, exec, apv->output_frame,
217 img_bar, &nb_img_bar,
218 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
219 VK_PIPELINE_STAGE_2_CLEAR_BIT,
220 VK_ACCESS_2_TRANSFER_WRITE_BIT,
221 VK_IMAGE_LAYOUT_GENERAL,
222 VK_QUEUE_FAMILY_IGNORED);
223 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
224 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
225 .pImageMemoryBarriers = img_bar,
226 .imageMemoryBarrierCount = nb_img_bar,
227 });
228 nb_img_bar = 0;
229
230 /* Zero frame */
231 for (int i = 0; i < ff_vk_count_images(vkf); i++)
232 vk->CmdClearColorImage(exec->buf, vkf->img[i],
233 VK_IMAGE_LAYOUT_GENERAL,
234 &((VkClearColorValue) { 0 }),
235 1, &((VkImageSubresourceRange) {
236 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
237 .levelCount = 1,
238 .layerCount = 1,
239 }));
240
241 /* Wait for the frame to get zeroed out before continuing */
242 ff_vk_frame_barrier(&ctx->s, exec, apv->output_frame, img_bar, &nb_img_bar,
243 VK_PIPELINE_STAGE_2_CLEAR_BIT,
244 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
245 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
246 VK_IMAGE_LAYOUT_GENERAL,
247 VK_QUEUE_FAMILY_IGNORED);
248 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
249 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
250 .pImageMemoryBarriers = img_bar,
251 .imageMemoryBarrierCount = nb_img_bar,
252 });
253 nb_img_bar = 0;
254
255 /* Zero-filled first, since entropy writes only the nonzero coefficients. */
256 err = ff_vk_get_pooled_buffer(&ctx->s, &apvvk->coeff_pool, &coeff_buf,
257 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
258 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
259 NULL, apvvk->coeff_size,
260 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
261 if (err < 0)
262 return err;
263 vk->CmdFillBuffer(exec->buf, coeff_buf->buf, 0, VK_WHOLE_SIZE, 0);
264
265 buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
266 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
267 .srcStageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
268 .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
269 .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
270 .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT |
271 VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
272 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
273 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
274 .buffer = coeff_buf->buf,
275 .size = VK_WHOLE_SIZE,
276 };
277 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
278 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
279 .pBufferMemoryBarriers = buf_bar,
280 .bufferMemoryBarrierCount = nb_buf_bar,
281 });
282 nb_buf_bar = 0;
283
284 /* Setup push data */
286 .tile_data = slices_buf->address,
287 .tile_count = { apv->tile_info.tile_cols, apv->tile_info.tile_rows },
288 .log2_chroma_sub = { desc->log2_chroma_w, desc->log2_chroma_h },
289 .components = desc->nb_components,
290 .bit_depth = apv_cbc->bit_depth,
291 };
292
293 /* Decoding */
294 ff_vk_shader_update_img_array(&ctx->s, exec, &apvvk->decode,
295 apv->output_frame, views,
296 0, 0,
297 VK_IMAGE_LAYOUT_GENERAL,
298 VK_NULL_HANDLE);
299 ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->decode,
300 0, 1, 0,
301 frame_data_buf,
302 0, frame_data_buf->size,
303 VK_FORMAT_UNDEFINED);
304 ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->decode,
305 0, 2, 0,
306 coeff_buf, 0, coeff_buf->size,
307 VK_FORMAT_UNDEFINED);
308
309 ff_vk_exec_bind_shader(&ctx->s, exec, &apvvk->decode);
310 ff_vk_shader_update_push_const(&ctx->s, exec, &apvvk->decode,
311 VK_SHADER_STAGE_COMPUTE_BIT,
312 0, sizeof(pd), &pd);
313
314 vk->CmdDispatch(exec->buf,
316 desc->nb_components);
317
318 /* Wait for the coefficient writes before the iDCT reads them */
319 buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
320 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
321 .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
322 .srcAccessMask = VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
323 .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
324 .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
325 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
326 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
327 .buffer = coeff_buf->buf,
328 .size = VK_WHOLE_SIZE,
329 };
330 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
331 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
332 .pBufferMemoryBarriers = buf_bar,
333 .bufferMemoryBarrierCount = nb_buf_bar,
334 });
335 nb_buf_bar = 0;
336
337 /* iDCT */
338 ff_vk_shader_update_img_array(&ctx->s, exec, &apvvk->idct,
339 apv->output_frame, views,
340 0, 0,
341 VK_IMAGE_LAYOUT_GENERAL,
342 VK_NULL_HANDLE);
343 ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->idct,
344 0, 1, 0,
345 frame_data_buf,
346 0, frame_data_buf->size,
347 VK_FORMAT_UNDEFINED);
348 ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->idct,
349 0, 2, 0,
350 coeff_buf, 0, coeff_buf->size,
351 VK_FORMAT_UNDEFINED);
352
353 ff_vk_exec_bind_shader(&ctx->s, exec, &apvvk->idct);
354 ff_vk_shader_update_push_const(&ctx->s, exec, &apvvk->idct,
355 VK_SHADER_STAGE_COMPUTE_BIT,
356 0, sizeof(pd), &pd);
357
358 /* one workgroup per group of 8 horizontally adjacent transform blocks,
359 * in the luma basis coords, in case a block is OOB writes/reads are ignored */
360 int idct_cx = 0, idct_by = 0;
361 for (int comp = 0; comp < desc->nb_components; comp++) {
362 int sw = (comp == 0) ? 0 : desc->log2_chroma_w;
363 int sh = (comp == 0) ? 0 : desc->log2_chroma_h;
364 int bx = (avctx->coded_width + (1 << (3 + sw)) - 1) >> (3 + sw);
365 int by = (avctx->coded_height + (1 << (3 + sh)) - 1) >> (3 + sh);
366 idct_cx = FFMAX(idct_cx, (bx + 7) >> 3);
367 idct_by = FFMAX(idct_by, by);
368 }
369 vk->CmdDispatch(exec->buf, idct_cx, idct_by, desc->nb_components);
370
371 ff_vk_exec_move_dep_refstruct(&ctx->s, exec, &coeff_buf);
372 err = ff_vk_exec_submit(&ctx->s, exec);
373 if (err < 0)
374 return err;
375
376 return 0;
377
378fail:
379 ff_vk_exec_discard(&ctx->s, exec);
380 av_refstruct_unref(&coeff_buf);
381 return err;
382}
383
385 FFVkExecPool *pool, FFVulkanShader *shd)
386{
387 int err;
388 AVHWFramesContext *dec_frames_ctx;
389 dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
390
391 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
392 (uint32_t []) { 1, 1, 1 }, 0);
394 VK_SHADER_STAGE_COMPUTE_BIT);
395
396 const FFVulkanDescriptorSetBinding desc_set[] = {
397 {
398 .name = "dst",
399 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
400 .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
401 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
402 },
403 {
404 .name = "frame_data_buf",
405 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
406 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
407 },
408 {
409 .name = "coeffs_out_buf",
410 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
411 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
412 }
413 };
414 ff_vk_shader_add_descriptor_set(s, shd, desc_set, 3, 0);
415
419
420 RET(ff_vk_shader_register_exec(s, pool, shd));
421
422fail:
423 return err;
424}
425
427 FFVkExecPool *pool, FFVulkanShader *shd)
428{
429 int err;
430 AVHWFramesContext *dec_frames_ctx;
431 dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
432
433 SPEC_LIST_CREATE(sl, 1 + 64, (1 + 64)*sizeof(uint32_t))
434 SPEC_LIST_ADD(sl, 16, 32, 8); /* nb_blocks per workgroup */
435
436 const double idct_8_scales[8] = {
437 cos(4.0*M_PI/16.0) / 2.0, cos(1.0*M_PI/16.0) / 2.0,
438 cos(2.0*M_PI/16.0) / 2.0, cos(3.0*M_PI/16.0) / 2.0,
439 cos(4.0*M_PI/16.0) / 2.0, cos(5.0*M_PI/16.0) / 2.0,
440 cos(6.0*M_PI/16.0) / 2.0, cos(7.0*M_PI/16.0) / 2.0,
441 };
442 for (int i = 0; i < 64; i++)
443 SPEC_LIST_ADD(sl, 18 + i, 32,
444 av_float2int(idct_8_scales[i >> 3]*idct_8_scales[i & 7]));
445
446 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
447 (uint32_t []) { 32, 2, 1 }, 0);
449 VK_SHADER_STAGE_COMPUTE_BIT);
450
451 FFVulkanDescriptorSetBinding desc_set[] = {
452 {
453 .name = "dst",
454 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
455 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
456 .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
457 },
458 {
459 .name = "frame_data_buf",
460 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
461 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
462 },
463 {
464 .name = "coeffs_in_buf",
465 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
466 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
467 },
468 };
469 ff_vk_shader_add_descriptor_set(s, shd, desc_set, 3, 0);
470
473 ff_apv_idct_comp_spv_len, "main"));
474
475 RET(ff_vk_shader_register_exec(s, pool, shd));
476
477fail:
478 return err;
479}
480
482{
483 APVVulkanDecodeContext *apvvk = ctx->sd_ctx;
484
485 ff_vk_shader_free(&ctx->s, &apvvk->decode);
486 ff_vk_shader_free(&ctx->s, &apvvk->idct);
487
490
491 av_freep(&apvvk);
492}
493
495{
496 int err;
498
499 err = ff_vk_decode_init(avctx);
500 if (err < 0)
501 return err;
502
504 APVVulkanDecodeContext *apvvk = ctx->sd_ctx = av_mallocz(sizeof(*apvvk));
505 if (!apvvk) {
506 err = AVERROR(ENOMEM);
507 goto fail;
508 }
509
510 ctx->sd_ctx_free = &vk_decode_apv_uninit;
511
512 /* Size the flat coefficient buffer: one int16 per sample of the
513 * MB-aligned coded area, summed over components. */
514 {
515 const AVPixFmtDescriptor *pd =
517 int cw = FFALIGN(avctx->coded_width, 16);
518 int ch = FFALIGN(avctx->coded_height, 16);
519 apvvk->coeff_size = 0;
520 for (int i = 0; i < pd->nb_components; i++) {
521 int sx = (i == 1 || i == 2) ? pd->log2_chroma_w : 0;
522 int sy = (i == 1 || i == 2) ? pd->log2_chroma_h : 0;
523 apvvk->coeff_size += (size_t)(cw >> sx) * (ch >> sy);
524 }
525 apvvk->coeff_size *= sizeof(int16_t);
526 }
527
528 RET(init_decode_shader(avctx, &ctx->s, &ctx->exec_pool,
529 &apvvk->decode));
530
531 RET(init_idct_shader(avctx, &ctx->s, &ctx->exec_pool,
532 &apvvk->idct));
533
534fail:
535 return err;
536}
537
539{
540 AVHWDeviceContext *dev_ctx = _hwctx.nc;
541
543 FFVulkanDecodePicture *vp = &apvvp->vp;
544
545 ff_vk_decode_free_frame(dev_ctx, vp);
546
548}
549
551 .p.name = "apv_vulkan",
552 .p.type = AVMEDIA_TYPE_VIDEO,
553 .p.id = AV_CODEC_ID_APV,
554 .p.pix_fmt = AV_PIX_FMT_VULKAN,
555 .start_frame = &vk_apv_start_frame,
556 .decode_slice = &vk_apv_decode_slice,
557 .end_frame = &vk_apv_end_frame,
558 .free_frame_priv = &vk_apv_free_frame_priv,
559 .frame_priv_data_size = sizeof(APVVulkanDecodePicture),
561 .update_thread_context = &ff_vk_update_thread_context,
563 .frame_params = &ff_vk_frame_params,
564 .priv_data_size = sizeof(FFVulkanDecodeContext),
566};
static AVFormatContext * ctx
#define APV_MAX_NUM_COMP
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition eamad.c:79
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
Definition ffmpeg.c:491
#define AV_NUM_DATA_POINTERS
Definition frame.h:473
#define fail
Definition test.h:479
@ AV_CODEC_ID_APV
Definition codec_id.h:323
#define AVERROR(e)
Definition error.h:45
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
#define HWACCEL_CAP_THREAD_SAFE
const struct FFHWAccel ff_apv_vulkan_hwaccel
Definition vulkan_apv.c:550
static av_always_inline uint32_t av_float2int(float f)
Reinterpret a float as a 32-bit integer.
Definition intfloat.h:50
#define AV_WN32(p, v)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
@ APV_MAX_TILE_COUNT
Definition apv.h:77
@ APV_MAX_TILE_COLS
Definition apv.h:75
@ APV_MAX_TILE_ROWS
Definition apv.h:76
#define av_unused
Definition attributes.h:164
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:2719
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:2240
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:2550
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1613
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition vulkan.c:2197
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition vulkan.c:660
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:2128
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2791
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2584
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition vulkan.c:622
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:969
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition vulkan.c:2768
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition vulkan.c:786
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:2732
int ff_vk_host_map_buffer(FFVulkanContext *s, FFVkBuffer **dst, uint8_t *src_data, VkDeviceSize size, const AVBufferRef *src_buf, VkBufferUsageFlags usage)
Maps a system RAM buffer into a Vulkan buffer.
Definition vulkan.c:1522
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition vulkan.c:1426
int ff_vk_flush_buffer(FFVulkanContext *s, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize mem_size, int flush)
Flush or invalidate a single buffer, with a given size and offset.
Definition vulkan.c:1327
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:763
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:2444
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition vulkan.c:867
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:2758
const char * desc
Definition libsvtav1.c:83
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
#define M_PI
Definition mathematics.h:67
Memory handling functions.
const char data[16]
Definition mxf.c:149
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:120
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition refstruct.h:292
APVRawFrame * cur_raw_frame
Definition apv_decode.h:104
CodedBitstreamContext * cbc
Definition apv_decode.h:99
APVDerivedTileInfo tile_info
Definition apv_decode.h:103
void * hwaccel_picture_private
Definition apv_decode.h:108
AVFrame * output_frame
Definition apv_decode.h:107
uint16_t col_starts[APV_MAX_TILE_COLS+1]
Definition apv_decode.h:94
uint16_t row_starts[APV_MAX_TILE_ROWS+1]
Definition apv_decode.h:95
APVRawQuantizationMatrix quantization_matrix
Definition cbs_apv.h:78
APVRawFrameHeader frame_header
Definition cbs_apv.h:103
APVRawTile tile[APV_MAX_TILE_COUNT]
Definition cbs_apv.h:105
uint8_t q_matrix[APV_MAX_NUM_COMP][APV_TR_SIZE][APV_TR_SIZE]
Definition cbs_apv.h:57
uint8_t tile_qp[APV_MAX_NUM_COMP]
Definition cbs_apv.h:89
APVRawTileHeader tile_header
Definition cbs_apv.h:94
FFVulkanShader decode
Definition vulkan_apv.c:47
AVRefStructPool * coeff_pool
Definition vulkan_apv.c:54
AVRefStructPool * frame_data_pool
Definition vulkan_apv.c:50
FFVulkanShader idct
Definition vulkan_apv.c:48
FFVulkanDecodePicture vp
Definition vulkan_apv.c:39
FFVkBuffer * frame_data_buf
Definition vulkan_apv.c:41
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1471
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition avcodec.h:619
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
void * priv_data
Definition avcodec.h:470
void * hwaccel_priv_data
hwaccel-specific private data
Definition internal.h:130
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
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
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition refstruct.c:183
VkImageLayout layout[AV_NUM_DATA_POINTERS]
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
void * priv_data
Internal codec-specific data.
Definition cbs.h:247
VkDeviceAddress tile_data
Definition vulkan_apv.c:59
int tile_count[2]
Definition vulkan_apv.c:60
int log2_chroma_sub[2]
Definition vulkan_apv.c:61
VkBuffer buf
Definition vulkan.h:95
VkDeviceAddress address
Definition vulkan.h:99
size_t size
Definition vulkan.h:98
AVBufferRef * host_ref
Definition vulkan.h:111
uint8_t * mapped_mem
Definition vulkan.h:103
VkCommandBuffer buf
Definition vulkan.h:142
FFVulkanDecodeShared * shared_ctx
#define av_mallocz(s)
#define av_freep(p)
static char buffer[20]
Definition seek.c:32
int size
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition refstruct.h:58
@ FF_VK_REP_NATIVE
Definition vulkan.h:439
#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
static int ff_vk_count_images(AVVkFrame *f)
Definition vulkan.h:356
const unsigned char ff_apv_decode_comp_spv_data[]
static int vk_apv_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
Definition vulkan_apv.c:129
static void vk_decode_apv_uninit(FFVulkanDecodeShared *ctx)
Definition vulkan_apv.c:481
const unsigned char ff_apv_idct_comp_spv_data[]
static int vk_decode_apv_init(AVCodecContext *avctx)
Definition vulkan_apv.c:494
static int init_idct_shader(AVCodecContext *avctx, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Definition vulkan_apv.c:426
const FFVulkanDecodeDescriptor ff_vk_dec_apv_desc
Definition vulkan_apv.c:33
static void vk_apv_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
Definition vulkan_apv.c:538
static int init_decode_shader(AVCodecContext *avctx, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Definition vulkan_apv.c:384
static int vk_apv_start_frame(AVCodecContext *avctx, const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition vulkan_apv.c:66
static int vk_apv_end_frame(AVCodecContext *avctx)
Definition vulkan_apv.c:164
const unsigned int ff_apv_idct_comp_spv_len
const unsigned int ff_apv_decode_comp_spv_len
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Initialize hw_frames_ctx with the parameters needed to decode the stream using the parameters from av...
int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp, const uint8_t *data, size_t size, int add_startcode, uint32_t *nb_slices, const uint32_t **offsets)
Add slice data to frame.
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY