FFmpeg
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 
27 extern const unsigned char ff_apv_decode_comp_spv_data[];
28 extern const unsigned int ff_apv_decode_comp_spv_len;
29 
30 extern const unsigned char ff_apv_idct_comp_spv_data[];
31 extern const unsigned int ff_apv_idct_comp_spv_len;
32 
35  .queue_flags = VK_QUEUE_COMPUTE_BIT,
36 };
37 
38 typedef struct APVVulkanDecodePicture {
40 
42  uint32_t *frame_data;
43  int tile_num;
45 
46 typedef 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 
58 typedef struct DecodePushData {
59  VkDeviceAddress tile_data;
60  int tile_count[2];
63  int bit_depth;
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 
92  err = ff_vk_get_pooled_buffer(&ctx->s, &apvvk->frame_data_pool,
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  ff_vk_exec_start(&ctx->s, exec);
192 
193  /* Make sure the buffer is flushed */
194  RET(ff_vk_flush_buffer(&ctx->s, frame_data_buf, 0, frame_data_buf->size, 1));
195 
196  /* Prepare deps */
198  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
199  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
200 
201  /* Exec-owned output views: freed on exec recycle, so releasing a picture
202  * needs no blocking wait. No mirror_sem: nothing consumes vp->sem here. */
203  VkImageView views[AV_NUM_DATA_POINTERS];
204  RET(ff_vk_create_imageviews(&ctx->s, exec, views, apv->output_frame,
206 
209 
210  AVVkFrame *vkf = (AVVkFrame *)apv->output_frame->data[0];
211  vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
212  vkf->access[0] = VK_ACCESS_2_NONE;
213 
214  ff_vk_frame_barrier(&ctx->s, exec, apv->output_frame,
215  img_bar, &nb_img_bar,
216  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
217  VK_PIPELINE_STAGE_2_CLEAR_BIT,
218  VK_ACCESS_2_TRANSFER_WRITE_BIT,
219  VK_IMAGE_LAYOUT_GENERAL,
220  VK_QUEUE_FAMILY_IGNORED);
221  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
222  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
223  .pImageMemoryBarriers = img_bar,
224  .imageMemoryBarrierCount = nb_img_bar,
225  });
226  nb_img_bar = 0;
227 
228  /* Zero frame */
229  for (int i = 0; i < ff_vk_count_images(vkf); i++)
230  vk->CmdClearColorImage(exec->buf, vkf->img[i],
231  VK_IMAGE_LAYOUT_GENERAL,
232  &((VkClearColorValue) { 0 }),
233  1, &((VkImageSubresourceRange) {
234  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
235  .levelCount = 1,
236  .layerCount = 1,
237  }));
238 
239  /* Wait for the frame to get zeroed out before continuing */
240  ff_vk_frame_barrier(&ctx->s, exec, apv->output_frame, img_bar, &nb_img_bar,
241  VK_PIPELINE_STAGE_2_CLEAR_BIT,
242  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
243  VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
244  VK_IMAGE_LAYOUT_GENERAL,
245  VK_QUEUE_FAMILY_IGNORED);
246  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
247  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
248  .pImageMemoryBarriers = img_bar,
249  .imageMemoryBarrierCount = nb_img_bar,
250  });
251  nb_img_bar = 0;
252 
253  /* Zero-filled first, since entropy writes only the nonzero coefficients. */
254  err = ff_vk_get_pooled_buffer(&ctx->s, &apvvk->coeff_pool, &coeff_buf,
255  VK_BUFFER_USAGE_TRANSFER_DST_BIT |
256  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
257  NULL, apvvk->coeff_size,
258  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
259  if (err < 0)
260  return err;
261  vk->CmdFillBuffer(exec->buf, coeff_buf->buf, 0, VK_WHOLE_SIZE, 0);
262 
263  buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
264  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
265  .srcStageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
266  .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
267  .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
268  .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT |
269  VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
270  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
271  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
272  .buffer = coeff_buf->buf,
273  .size = VK_WHOLE_SIZE,
274  };
275  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
276  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
277  .pBufferMemoryBarriers = buf_bar,
278  .bufferMemoryBarrierCount = nb_buf_bar,
279  });
280  nb_buf_bar = 0;
281 
282  /* Setup push data */
284  .tile_data = slices_buf->address,
285  .tile_count = { apv->tile_info.tile_cols, apv->tile_info.tile_rows },
286  .log2_chroma_sub = { desc->log2_chroma_w, desc->log2_chroma_h },
287  .components = desc->nb_components,
288  .bit_depth = apv_cbc->bit_depth,
289  };
290 
291  /* Decoding */
292  ff_vk_shader_update_img_array(&ctx->s, exec, &apvvk->decode,
293  apv->output_frame, views,
294  0, 0,
295  VK_IMAGE_LAYOUT_GENERAL,
296  VK_NULL_HANDLE);
297  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->decode,
298  0, 1, 0,
299  frame_data_buf,
300  0, frame_data_buf->size,
301  VK_FORMAT_UNDEFINED);
302  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->decode,
303  0, 2, 0,
304  coeff_buf, 0, coeff_buf->size,
305  VK_FORMAT_UNDEFINED);
306 
307  ff_vk_exec_bind_shader(&ctx->s, exec, &apvvk->decode);
308  ff_vk_shader_update_push_const(&ctx->s, exec, &apvvk->decode,
309  VK_SHADER_STAGE_COMPUTE_BIT,
310  0, sizeof(pd), &pd);
311 
312  vk->CmdDispatch(exec->buf,
314  desc->nb_components);
315 
316  /* Wait for the coefficient writes before the iDCT reads them */
317  buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
318  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
319  .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
320  .srcAccessMask = VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
321  .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
322  .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
323  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
324  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
325  .buffer = coeff_buf->buf,
326  .size = VK_WHOLE_SIZE,
327  };
328  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
329  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
330  .pBufferMemoryBarriers = buf_bar,
331  .bufferMemoryBarrierCount = nb_buf_bar,
332  });
333  nb_buf_bar = 0;
334 
335  /* iDCT */
336  ff_vk_shader_update_img_array(&ctx->s, exec, &apvvk->idct,
337  apv->output_frame, views,
338  0, 0,
339  VK_IMAGE_LAYOUT_GENERAL,
340  VK_NULL_HANDLE);
341  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->idct,
342  0, 1, 0,
343  frame_data_buf,
344  0, frame_data_buf->size,
345  VK_FORMAT_UNDEFINED);
346  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &apvvk->idct,
347  0, 2, 0,
348  coeff_buf, 0, coeff_buf->size,
349  VK_FORMAT_UNDEFINED);
350 
351  ff_vk_exec_bind_shader(&ctx->s, exec, &apvvk->idct);
352  ff_vk_shader_update_push_const(&ctx->s, exec, &apvvk->idct,
353  VK_SHADER_STAGE_COMPUTE_BIT,
354  0, sizeof(pd), &pd);
355 
356  /* one workgroup per group of 8 horizontally adjacent transform blocks,
357  * in the luma basis coords, in case a block is OOB writes/reads are ignored */
358  int idct_cx = 0, idct_by = 0;
359  for (int comp = 0; comp < desc->nb_components; comp++) {
360  int sw = (comp == 0) ? 0 : desc->log2_chroma_w;
361  int sh = (comp == 0) ? 0 : desc->log2_chroma_h;
362  int bx = (avctx->coded_width + (1 << (3 + sw)) - 1) >> (3 + sw);
363  int by = (avctx->coded_height + (1 << (3 + sh)) - 1) >> (3 + sh);
364  idct_cx = FFMAX(idct_cx, (bx + 7) >> 3);
365  idct_by = FFMAX(idct_by, by);
366  }
367  vk->CmdDispatch(exec->buf, idct_cx, idct_by, desc->nb_components);
368 
369  ff_vk_exec_move_dep_refstruct(&ctx->s, exec, &coeff_buf);
370  err = ff_vk_exec_submit(&ctx->s, exec);
371 
372 fail:
373  av_refstruct_unref(&coeff_buf);
374  return err < 0 ? err : 0;
375 }
376 
378  FFVkExecPool *pool, FFVulkanShader *shd)
379 {
380  int err;
381  AVHWFramesContext *dec_frames_ctx;
382  dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
383 
384  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
385  (uint32_t []) { 1, 1, 1 }, 0);
387  VK_SHADER_STAGE_COMPUTE_BIT);
388 
389  const FFVulkanDescriptorSetBinding desc_set[] = {
390  {
391  .name = "dst",
392  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
393  .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
394  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
395  },
396  {
397  .name = "frame_data_buf",
398  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
399  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
400  },
401  {
402  .name = "coeffs_out_buf",
403  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
404  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
405  }
406  };
407  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 3, 0);
408 
409  RET(ff_vk_shader_link(s, shd,
411  ff_apv_decode_comp_spv_len, "main"));
412 
413  RET(ff_vk_shader_register_exec(s, pool, shd));
414 
415 fail:
416  return err;
417 }
418 
420  FFVkExecPool *pool, FFVulkanShader *shd)
421 {
422  int err;
423  AVHWFramesContext *dec_frames_ctx;
424  dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
425 
426  SPEC_LIST_CREATE(sl, 1 + 64, (1 + 64)*sizeof(uint32_t))
427  SPEC_LIST_ADD(sl, 16, 32, 8); /* nb_blocks per workgroup */
428 
429  const double idct_8_scales[8] = {
430  cos(4.0*M_PI/16.0) / 2.0, cos(1.0*M_PI/16.0) / 2.0,
431  cos(2.0*M_PI/16.0) / 2.0, cos(3.0*M_PI/16.0) / 2.0,
432  cos(4.0*M_PI/16.0) / 2.0, cos(5.0*M_PI/16.0) / 2.0,
433  cos(6.0*M_PI/16.0) / 2.0, cos(7.0*M_PI/16.0) / 2.0,
434  };
435  for (int i = 0; i < 64; i++)
436  SPEC_LIST_ADD(sl, 18 + i, 32,
437  av_float2int(idct_8_scales[i >> 3]*idct_8_scales[i & 7]));
438 
439  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
440  (uint32_t []) { 32, 2, 1 }, 0);
442  VK_SHADER_STAGE_COMPUTE_BIT);
443 
444  FFVulkanDescriptorSetBinding desc_set[] = {
445  {
446  .name = "dst",
447  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
448  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
449  .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
450  },
451  {
452  .name = "frame_data_buf",
453  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
454  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
455  },
456  {
457  .name = "coeffs_in_buf",
458  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
459  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
460  },
461  };
462  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 3, 0);
463 
464  RET(ff_vk_shader_link(s, shd,
466  ff_apv_idct_comp_spv_len, "main"));
467 
468  RET(ff_vk_shader_register_exec(s, pool, shd));
469 
470 fail:
471  return err;
472 }
473 
475 {
476  APVVulkanDecodeContext *apvvk = ctx->sd_ctx;
477 
478  ff_vk_shader_free(&ctx->s, &apvvk->decode);
479  ff_vk_shader_free(&ctx->s, &apvvk->idct);
480 
483 
484  av_freep(&apvvk);
485 }
486 
488 {
489  int err;
491 
492  err = ff_vk_decode_init(avctx);
493  if (err < 0)
494  return err;
495 
497  APVVulkanDecodeContext *apvvk = ctx->sd_ctx = av_mallocz(sizeof(*apvvk));
498  if (!apvvk) {
499  err = AVERROR(ENOMEM);
500  goto fail;
501  }
502 
503  ctx->sd_ctx_free = &vk_decode_apv_uninit;
504 
505  /* Size the flat coefficient buffer: one int16 per sample of the
506  * MB-aligned coded area, summed over components. */
507  {
508  const AVPixFmtDescriptor *pd =
510  int cw = FFALIGN(avctx->coded_width, 16);
511  int ch = FFALIGN(avctx->coded_height, 16);
512  apvvk->coeff_size = 0;
513  for (int i = 0; i < pd->nb_components; i++) {
514  int sx = (i == 1 || i == 2) ? pd->log2_chroma_w : 0;
515  int sy = (i == 1 || i == 2) ? pd->log2_chroma_h : 0;
516  apvvk->coeff_size += (size_t)(cw >> sx) * (ch >> sy);
517  }
518  apvvk->coeff_size *= sizeof(int16_t);
519  }
520 
521  RET(init_decode_shader(avctx, &ctx->s, &ctx->exec_pool,
522  &apvvk->decode));
523 
524  RET(init_idct_shader(avctx, &ctx->s, &ctx->exec_pool,
525  &apvvk->idct));
526 
527 fail:
528  return err;
529 }
530 
532 {
533  AVHWDeviceContext *dev_ctx = _hwctx.nc;
534 
535  APVVulkanDecodePicture *apvvp = data;
536  FFVulkanDecodePicture *vp = &apvvp->vp;
537 
538  ff_vk_decode_free_frame(dev_ctx, vp);
539 
541 }
542 
544  .p.name = "apv_vulkan",
545  .p.type = AVMEDIA_TYPE_VIDEO,
546  .p.id = AV_CODEC_ID_APV,
547  .p.pix_fmt = AV_PIX_FMT_VULKAN,
548  .start_frame = &vk_apv_start_frame,
549  .decode_slice = &vk_apv_decode_slice,
550  .end_frame = &vk_apv_end_frame,
551  .free_frame_priv = &vk_apv_free_frame_priv,
552  .frame_priv_data_size = sizeof(APVVulkanDecodePicture),
556  .frame_params = &ff_vk_frame_params,
557  .priv_data_size = sizeof(FFVulkanDecodeContext),
559 };
ff_vk_dec_apv_desc
const FFVulkanDecodeDescriptor ff_vk_dec_apv_desc
Definition: vulkan_apv.c:33
DecodePushData::log2_chroma_sub
int log2_chroma_sub[2]
Definition: vulkan_apv.c:61
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
APVDerivedTileInfo::tile_cols
uint8_t tile_cols
Definition: apv_decode.h:89
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
CodedBitstreamContext::priv_data
void * priv_data
Internal codec-specific data.
Definition: cbs.h:247
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2614
APVDecodeContext::output_frame
AVFrame * output_frame
Definition: apv_decode.h:107
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:79
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3460
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FFVulkanDecodeContext::shared_ctx
FFVulkanDecodeShared * shared_ctx
Definition: vulkan_decode.h:55
RET
#define RET(x)
Definition: vulkan.h:37
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
APVDecodeContext
Definition: apv_decode.h:98
vk_apv_decode_slice
static int vk_apv_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
Definition: vulkan_apv.c:129
AVRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
FFVkBuffer::host_ref
AVBufferRef * host_ref
Definition: vulkan.h:111
apv_decode.h
APVRawFrame::tile
APVRawTile tile[APV_MAX_TILE_COUNT]
Definition: cbs_apv.h:105
APVVulkanDecodeContext::frame_data_pool
AVRefStructPool * frame_data_pool
Definition: vulkan_apv.c:50
data
const char data[16]
Definition: mxf.c:149
FFVulkanDecodeDescriptor::codec_id
enum AVCodecID codec_id
Definition: vulkan_decode.h:30
ff_vk_flush_buffer
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:1157
FFVkBuffer::address
VkDeviceAddress address
Definition: vulkan.h:99
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:571
FF_VK_REP_NATIVE
@ FF_VK_REP_NATIVE
Definition: vulkan.h:429
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
SPEC_LIST_ADD
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition: vulkan.h:55
av_float2int
static av_always_inline uint32_t av_float2int(float f)
Reinterpret a float as a 32-bit integer.
Definition: intfloat.h:50
ff_vk_exec_bind_shader
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition: vulkan.c:2591
FFVulkanDecodeContext
Definition: vulkan_decode.h:54
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
ff_vk_exec_add_dep_frame
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition: vulkan.c:777
APVDecodeContext::tile_info
APVDerivedTileInfo tile_info
Definition: apv_decode.h:103
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:493
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:95
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3500
FFHWAccel
Definition: hwaccel_internal.h:34
APVVulkanDecodeContext::coeff_size
size_t coeff_size
Definition: vulkan_apv.c:55
AVVkFrame::img
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Definition: hwcontext_vulkan.h:266
ff_vk_shader_update_img_array
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
Definition: vulkan.c:2542
ff_vk_frame_barrier
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:2027
HWACCEL_CAP_THREAD_SAFE
#define HWACCEL_CAP_THREAD_SAFE
Definition: hwaccel_internal.h:32
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:2407
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
FFVulkanDecodeShared
Definition: vulkan_decode.h:38
av_unused
#define av_unused
Definition: attributes.h:164
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
DecodePushData::bit_depth
int bit_depth
Definition: vulkan_apv.c:63
ff_apv_decode_comp_spv_len
const unsigned int ff_apv_decode_comp_spv_len
FFVulkanDecodePicture::slices_buf
FFVkBuffer * slices_buf
Definition: vulkan_decode.h:101
vk_apv_free_frame_priv
static void vk_apv_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
Definition: vulkan_apv.c:531
APVRawFrame::frame_header
APVRawFrameHeader frame_header
Definition: cbs_apv.h:103
FFVulkanDecodePicture
Definition: vulkan_decode.h:73
init_idct_shader
static int init_idct_shader(AVCodecContext *avctx, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Definition: vulkan_apv.c:419
APVVulkanDecodeContext::idct
FFVulkanShader idct
Definition: vulkan_apv.c:48
init_decode_shader
static int init_decode_shader(AVCodecContext *avctx, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Definition: vulkan_apv.c:377
APV_MAX_TILE_COUNT
@ APV_MAX_TILE_COUNT
Definition: apv.h:77
AVRefStructPool
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition: refstruct.c:183
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
DecodePushData
Definition: vulkan_apv.c:58
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
APVDecodeContext::cur_raw_frame
APVRawFrame * cur_raw_frame
Definition: apv_decode.h:104
ff_vk_exec_move_dep_refstruct
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition: vulkan.c:694
ff_vk_get_pooled_buffer
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:1256
fail
#define fail
Definition: test.h:479
ff_apv_decode_comp_spv_data
const unsigned char ff_apv_decode_comp_spv_data[]
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
APV_MAX_TILE_COLS
@ APV_MAX_TILE_COLS
Definition: apv.h:75
hwaccel_internal.h
ff_vk_decode_free_frame
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
Definition: vulkan_decode.c:639
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:478
CodedBitstreamAPVContext::bit_depth
int bit_depth
Definition: cbs_apv.h:191
APVRawQuantizationMatrix::q_matrix
uint8_t q_matrix[APV_MAX_NUM_COMP][APV_TR_SIZE][APV_TR_SIZE]
Definition: cbs_apv.h:57
ff_vk_decode_uninit
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
Definition: vulkan_decode.c:1220
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:2267
FFVkBuffer::size
size_t size
Definition: vulkan.h:98
SPEC_LIST_CREATE
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition: vulkan.h:45
AVVkFrame::access
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
Definition: hwcontext_vulkan.h:290
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:103
FFVulkanContext
Definition: vulkan.h:290
ff_vk_frame_params
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...
Definition: vulkan_decode.c:1083
DecodePushData::tile_count
int tile_count[2]
Definition: vulkan_apv.c:60
APVRawTile::tile_header
APVRawTileHeader tile_header
Definition: cbs_apv.h:94
vk_decode_apv_init
static int vk_decode_apv_init(AVCodecContext *avctx)
Definition: vulkan_apv.c:487
vk_apv_end_frame
static int vk_apv_end_frame(AVCodecContext *avctx)
Definition: vulkan_apv.c:164
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
ff_apv_vulkan_hwaccel
const FFHWAccel ff_apv_vulkan_hwaccel
Definition: vulkan_apv.c:543
APVVulkanDecodeContext::decode
FFVulkanShader decode
Definition: vulkan_apv.c:47
ff_vk_shader_update_push_const
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Definition: vulkan.c:2581
FFVulkanDescriptorSetBinding
Definition: vulkan.h:81
AV_WN32
#define AV_WN32(p, v)
Definition: intreadwrite.h:372
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:130
AVVkFrame
Definition: hwcontext_vulkan.h:261
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
size
int size
Definition: twinvq_data.h:10344
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:473
APVVulkanDecodePicture::frame_data_buf
FFVkBuffer * frame_data_buf
Definition: vulkan_apv.c:41
FFVulkanShader
Definition: vulkan.h:206
APVVulkanDecodeContext
Definition: vulkan_apv.c:46
APVRawFrameHeader::quantization_matrix
APVRawQuantizationMatrix quantization_matrix
Definition: cbs_apv.h:78
frame_data
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
Definition: ffmpeg.c:487
CodedBitstreamAPVContext
Definition: cbs_apv.h:190
FFVkExecContext
Definition: vulkan.h:128
ff_vk_shader_update_desc_buffer
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
Definition: vulkan.c:2555
FFVulkanDescriptorSetBinding::name
const char * name
Definition: vulkan.h:82
M_PI
#define M_PI
Definition: mathematics.h:67
av_refstruct_unref
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
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:1954
DecodePushData::tile_data
VkDeviceAddress tile_data
Definition: vulkan_apv.c:59
FF_VK_EXT_EXTERNAL_HOST_MEMORY
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY
Definition: vulkan_functions.h:36
APVDerivedTileInfo::row_starts
uint16_t row_starts[APV_MAX_TILE_ROWS+1]
Definition: apv_decode.h:95
vk_decode_apv_uninit
static void vk_decode_apv_uninit(FFVulkanDecodeShared *ctx)
Definition: vulkan_apv.c:474
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:599
s
uint8_t s
Definition: llvidencdsp.c:39
uninit
static av_cold void uninit(AVBitStreamFilterContext *ctx)
Definition: lcevc_merge.c:135
vk_apv_start_frame
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
ff_apv_idct_comp_spv_data
const unsigned char ff_apv_idct_comp_spv_data[]
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1471
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
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:2373
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:323
APVVulkanDecodePicture::tile_num
int tile_num
Definition: vulkan_apv.c:43
ff_vk_create_imageviews
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
Definition: vulkan.c:1958
FFVkExecPool
Definition: vulkan.h:268
ff_vk_decode_add_slice
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.
Definition: vulkan_decode.c:258
APVRawTileHeader::tile_qp
uint8_t tile_qp[APV_MAX_NUM_COMP]
Definition: cbs_apv.h:89
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:1443
APVDerivedTileInfo::tile_rows
uint8_t tile_rows
Definition: apv_decode.h:90
ff_apv_idct_comp_spv_len
const unsigned int ff_apv_idct_comp_spv_len
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:139
AVCodecContext
main external API structure.
Definition: avcodec.h:443
APV_MAX_NUM_COMP
@ APV_MAX_NUM_COMP
Definition: apv.h:39
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
update_thread_context
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have update_thread_context() run it in the next thread. Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little speed gain at this point but it should work. Use ff_thread_get_buffer()(or ff_progress_frame_get_buffer() in case you have inter-frame dependencies and use the ProgressFrame API) to allocate frame buffers. Call ff_progress_frame_report() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
APVDerivedTileInfo::col_starts
uint16_t col_starts[APV_MAX_TILE_COLS+1]
Definition: apv_decode.h:94
FFVulkanDecodeDescriptor
Definition: vulkan_decode.h:29
APVVulkanDecodePicture
Definition: vulkan_apv.c:38
APVVulkanDecodePicture::vp
FFVulkanDecodePicture vp
Definition: vulkan_apv.c:39
APV_MAX_TILE_ROWS
@ APV_MAX_TILE_ROWS
Definition: apv.h:76
ff_vk_update_thread_context
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
Definition: vulkan_decode.c:142
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:291
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
vulkan_decode.h
DecodePushData::components
int components
Definition: vulkan_apv.c:62
APVDecodeContext::cbc
CodedBitstreamContext * cbc
Definition: apv_decode.h:99
av_refstruct_pool_uninit
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
ff_vk_count_images
static int ff_vk_count_images(AVVkFrame *f)
Definition: vulkan.h:346
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFVkBuffer
Definition: vulkan.h:94
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:881
APVDecodeContext::hwaccel_picture_private
void * hwaccel_picture_private
Definition: apv_decode.h:108
ff_vk_decode_init
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
Definition: vulkan_decode.c:1231
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
APVVulkanDecodePicture::frame_data
uint32_t * frame_data
Definition: vulkan_apv.c:42
APVVulkanDecodeContext::coeff_pool
AVRefStructPool * coeff_pool
Definition: vulkan_apv.c:54
ff_vk_host_map_buffer
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:1352
FFVulkanFunctions
Definition: vulkan_functions.h:276
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:2070
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89