FFmpeg
apv_encode_vulkan.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2026 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 <math.h>
22 #include <stdlib.h>
23 
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavutil/vulkan.h"
28 
29 #include "avcodec.h"
30 #include "codec_internal.h"
31 #include "encode.h"
32 #include "hwconfig.h"
33 #include "internal.h"
34 
35 #include "apv.h"
36 #include "cbs.h"
37 #include "cbs_apv.h"
38 
39 extern const unsigned char ff_apv_encode_dct_comp_spv_data[];
40 extern const unsigned int ff_apv_encode_dct_comp_spv_len;
41 
42 extern const unsigned char ff_apv_encode_tiles_comp_spv_data[];
43 extern const unsigned int ff_apv_encode_tiles_comp_spv_len;
44 
45 extern const unsigned char ff_seg_gather_comp_spv_data[];
46 extern const unsigned int ff_seg_gather_comp_spv_len;
47 
48 #define APV_DEFAULT_QMAT 16
49 #define APV_MAX_NUM_COMP 4
50 
51 typedef struct DCTPushData {
52  int frame_dim[2];
53  int tile_count[2];
54  int tile_mb_dim[2];
56  int num_comp;
57  int bit_depth;
58  float qf[APV_MAX_NUM_COMP]; /* per-component fact/(level_scale*2^qp_shift) */
59  uint8_t qmat[64]; /* quantisation matrix, raster order */
60 } DCTPushData;
61 
62 typedef struct EntropyPushData {
63  VkDeviceAddress bytestream;
64  int tile_count[2];
65  int num_comp;
66  uint32_t slot_size;
67  uint32_t comp_base; /* component index this dispatch's z=0 maps to */
68  uint32_t blocks_per_tile; /* uniform coeff stride, in blocks */
69  int frame_mb[2]; /* frame size in MBs (luma basis) */
70  int tile_mb_dim[2]; /* full-tile size in MBs */
71  uint32_t blocks_per_mb; /* blocks per MB of this dispatch's components */
73 
74 typedef struct CompactPushData {
75  VkDeviceAddress sparse;
76  VkDeviceAddress compacted;
77  uint32_t slot_size;
79 
80 typedef struct VulkanEncodeAPVFrameData {
85 
88  void *frame_opaque;
90  int flags;
92 
93 typedef struct VulkanEncodeAPVContext {
94  const AVClass *class;
95 
99 
101  FFVulkanShader shd_entropy[2]; /* [0] luma-sized, [1] chroma-sized */
103 
104  /* Per-frame buffer pools */
110 
111  /* DCT/quantize push constants -- encoder-constant, built once at init. */
113 
114  /* CBS used to assemble the output packet */
117 
119 
120  /* Async machinery */
124 
125  /* Derived per-encoder state */
126  int frame_mb_x, frame_mb_y; /* MBs in the frame (luma basis) */
128  int tile_mb_w, tile_mb_h; /* MBs per tile (luma basis) */
130  int blocks_per_mb; /* luma; always 4 */
131  int chroma_blocks_per_mb; /* 4 for 4:4:4, 2 for 4:2:2 */
132  int num_comp;
135 
138  int band_idc;
140 
141  size_t coeffs_size; /* total size of coeffs buffer */
142  size_t bytestream_size; /* total size of bytestream buffer */
143  size_t slot_size; /* per-tile-component bytestream slot size */
144  size_t sizes_size; /* total size of sizes buffer */
145 
146  /* User options */
149  int qp_y;
150  int qp_c;
151  int qmatrix; /* APV_QMATRIX_*: quantisation matrix select */
152 
153  /* Benchmark knob (env APV_VULKAN_HEADERS_ONLY): the GPU still encodes,
154  * but the tiles are never downloaded and packets carry headers only. */
156 
157  /* Benchmark knob (env APV_VULKAN_SKIP_ENTROPY): skip the entropy
158  * dispatch to isolate the DCT pass. Implies headers_only. */
161 
162 /*
163  * HEVC default 8x8 intra scaling list (ITU-T H.265, Table 7-6): flat through
164  * the low-frequency core, a gentle ramp toward the high-frequency corner.
165  * Raster order; the matrix is symmetric, so APV's [y][x]/[x][y] indexing is
166  * immaterial. APV and HEVC share the "16 = neutral" convention, so the list
167  * transfers without rescaling.
168  */
169 static const uint8_t apv_qmat_hevc_intra[64] = {
170  16, 16, 16, 16, 17, 18, 21, 24,
171  16, 16, 16, 16, 17, 19, 22, 25,
172  16, 16, 17, 18, 20, 22, 25, 29,
173  16, 16, 18, 21, 24, 27, 31, 36,
174  17, 17, 20, 24, 30, 35, 41, 47,
175  18, 19, 22, 27, 35, 44, 54, 65,
176  21, 22, 25, 31, 41, 54, 70, 88,
177  24, 25, 29, 36, 47, 65, 88, 115,
178 };
179 
180 enum {
181  APV_QMATRIX_FLAT = 0, /* uniform 16 (the spec default) */
182  APV_QMATRIX_HEVC = 1, /* HEVC default intra scaling list */
183 };
184 
185 /*
186  * The active quantisation-matrix value at raster index i. Both the q_matrix
187  * signalled in the frame header and the encoder's pf table are derived from
188  * this single accessor, so they cannot disagree -- a mismatch would quantise
189  * against a different matrix than the decoder dequantises with.
190  */
191 static int apv_qmatrix_value(int qmatrix, int i)
192 {
193  return qmatrix == APV_QMATRIX_HEVC ? apv_qmat_hevc_intra[i]
195 }
196 
197 static const uint8_t apv_level_scale[6] = { 40, 45, 51, 57, 64, 71 };
198 
200 {
201  switch (sw_fmt) {
204  return APV_CHROMA_FORMAT_422;
207  return APV_CHROMA_FORMAT_444;
208  case AV_PIX_FMT_GRAY10:
209  case AV_PIX_FMT_GRAY12:
210  return APV_CHROMA_FORMAT_400;
213  return APV_CHROMA_FORMAT_4444;
214  default:
215  return -1;
216  }
217 }
218 
220 {
221  switch (sw_fmt) {
229  default: return -1;
230  }
231 }
232 
233 static int init_dct_shader(AVCodecContext *avctx)
234 {
235  int err;
236  VulkanEncodeAPVContext *ev = avctx->priv_data;
237  FFVulkanShader *shd = &ev->shd_dct;
238 
239  SPEC_LIST_CREATE(sl, 1, sizeof(uint32_t))
240  SPEC_LIST_ADD(sl, 16, 32, 4); /* nb_blocks: blocks_per_mb per workgroup */
241 
242  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
243  (uint32_t []) { 8, 4, 1 }, 0);
244 
246  VK_SHADER_STAGE_COMPUTE_BIT);
247 
248  const FFVulkanDescriptorSetBinding desc_set[] = {
249  {
250  .name = "coeffs_buf",
251  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
252  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
253  },
254  {
255  .name = "src",
256  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
257  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
258  .elems = av_pix_fmt_count_planes(ev->sw_format),
259  },
260  };
261  ff_vk_shader_add_descriptor_set(&ev->s, shd, desc_set, 2, 0);
262 
263  RET(ff_vk_shader_link(&ev->s, shd,
266 
267  RET(ff_vk_shader_register_exec(&ev->s, &ev->exec_pool, shd));
268 
269 fail:
270  return err;
271 }
272 
273 static int init_entropy_shader(AVCodecContext *avctx, int blocks_per_mb,
274  FFVulkanShader *shd)
275 {
276  int err;
277  VulkanEncodeAPVContext *ev = avctx->priv_data;
278 
279  /* One workgroup per tile-component, one invocation per transform block.
280  * Luma and chroma tile-components hold different block counts under
281  * chroma sub-sampling, so each gets a pipeline with its own size. */
282  uint32_t wg = ev->tile_mb_w * ev->tile_mb_h * blocks_per_mb;
283 
284  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
285  (uint32_t []) { wg, 1, 1 }, 0);
286 
288  VK_SHADER_STAGE_COMPUTE_BIT);
289 
290  const FFVulkanDescriptorSetBinding desc_set[] = {
291  {
292  .name = "coeffs_buf",
293  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
294  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
295  },
296  {
297  .name = "sizes_buf",
298  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
299  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
300  },
301  };
302  ff_vk_shader_add_descriptor_set(&ev->s, shd, desc_set, 2, 0);
303 
304  RET(ff_vk_shader_link(&ev->s, shd,
307 
308  RET(ff_vk_shader_register_exec(&ev->s, &ev->exec_pool, shd));
309 
310 fail:
311  return err;
312 }
313 
315 {
316  int err;
317  VulkanEncodeAPVContext *ev = avctx->priv_data;
318  FFVulkanShader *shd = &ev->shd_compact;
319 
320  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
321  (uint32_t []) { 256, 1, 1 }, 0);
322 
324  VK_SHADER_STAGE_COMPUTE_BIT);
325 
326  const FFVulkanDescriptorSetBinding desc_set[] = {
327  {
328  .name = "sizes_buf",
329  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
330  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
331  },
332  };
333  ff_vk_shader_add_descriptor_set(&ev->s, shd, desc_set, 1, 0);
334 
335  RET(ff_vk_shader_link(&ev->s, shd,
337  ff_seg_gather_comp_spv_len, "main"));
338 
339  RET(ff_vk_shader_register_exec(&ev->s, &ev->exec_pool, shd));
340 
341 fail:
342  return err;
343 }
344 
345 /*
346  * The DCT/quantize shader's push constants are entirely encoder-constant:
347  * frame geometry, the per-component quant scale qf, and the quantisation
348  * matrix. Build them once -- nothing here changes between frames.
349  */
351 {
352  VulkanEncodeAPVContext *ev = avctx->priv_data;
354  DCTPushData *pd = &ev->dct_push;
355  const double fact = (double)(1 << (ev->bit_depth - 1));
356 
357  pd->frame_dim[0] = avctx->width;
358  pd->frame_dim[1] = avctx->height;
359  pd->tile_count[0] = ev->tile_cols;
360  pd->tile_count[1] = ev->tile_rows;
361  pd->tile_mb_dim[0] = ev->tile_mb_w;
362  pd->tile_mb_dim[1] = ev->tile_mb_h;
363  pd->log2_chroma_sub[0] = desc->log2_chroma_w;
364  pd->log2_chroma_sub[1] = desc->log2_chroma_h;
365  pd->num_comp = ev->num_comp;
366  pd->bit_depth = ev->bit_depth;
367 
368  /*
369  * qf[c] = fact / (level_scale * 2^qp_shift). The encoder uses one QP per
370  * component, so this never varies by tile. Component 3 is alpha
371  * (4:4:4:4): full-resolution, so it takes the luma QP.
372  */
373  for (int c = 0; c < APV_MAX_NUM_COMP; c++) {
374  int qp = (c == 0 || c == 3) ? ev->qp_y : ev->qp_c;
375  int level_scale = apv_level_scale[qp % 6];
376  int qp_shift = qp / 6;
377  pd->qf[c] =
378  (float)(fact / ((double)level_scale * (double)(1 << qp_shift)));
379  }
380 
381  /*
382  * The 8-bit quantisation matrix. The shader stages it to shared memory
383  * and quantises with 1024 / qmat[i], the reciprocal partner of the
384  * decoder's per-coefficient dequant -- the same matrix that gets
385  * signalled in the frame header.
386  */
387  for (int i = 0; i < 64; i++)
388  pd->qmat[i] = apv_qmatrix_value(ev->qmatrix, i);
389 }
390 
391 static int submit_frame(AVCodecContext *avctx, FFVkExecContext *exec,
392  AVFrame *frame)
393 {
394  int err = 0;
395  VulkanEncodeAPVContext *ev = avctx->priv_data;
396  FFVulkanFunctions *vk = &ev->s.vkfn;
397  VulkanEncodeAPVFrameData *fd = exec->opaque;
398  VkImageView views[AV_NUM_DATA_POINTERS];
399 
400  VkImageMemoryBarrier2 img_bar[AV_NUM_DATA_POINTERS];
401  int nb_img_bar = 0;
402  VkBufferMemoryBarrier2 buf_bar[4];
403  int nb_buf_bar = 0;
404 
405  FFVkBuffer *coeffs_buf;
406  FFVkBuffer *bytestream_buf;
407  AVBufferRef *gathered_ref = NULL;
408  FFVkBuffer *gathered_buf;
409  FFVkBuffer *compacted_buf;
410  FFVkBuffer *sizes_buf;
411 
412  /* Allocate per-frame buffers */
414  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
415  NULL, ev->coeffs_size,
416  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
417  coeffs_buf = (FFVkBuffer *)fd->coeffs_ref->data;
418 
419  /* The entropy shader writes the bitstream here, sparsely -- one
420  * worst-case-sized slot per tile-component. Device-local, so those GPU
421  * writes stay in VRAM and never cross PCIe. */
423  &fd->bytestream_ref,
424  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
425  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
426  NULL, ev->bytestream_size,
427  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
428  bytestream_buf = (FFVkBuffer *)fd->bytestream_ref->data;
429 
430  /* The compaction shader gathers the sparse slots into here, contiguous.
431  * Device-local: shader stores over the bus are unreliably slow on some
432  * drivers, so the transfer to the host is left to the copy engine. */
434  &gathered_ref,
435  VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
436  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
437  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
438  NULL, ev->bytestream_size,
439  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
440  gathered_buf = (FFVkBuffer *)gathered_ref->data;
441 
442  /* Copy-engine destination the CPU assembles the packet from.
443  * Host-visible + host-cached so the readback is a fast cached copy. */
445  &fd->compacted_ref,
446  VK_BUFFER_USAGE_TRANSFER_DST_BIT |
447  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
448  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
449  NULL, ev->bytestream_size,
450  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
451  VK_MEMORY_PROPERTY_HOST_CACHED_BIT));
452  compacted_buf = (FFVkBuffer *)fd->compacted_ref->data;
453 
455  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
456  NULL, ev->sizes_size,
457  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
458  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
459  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT));
460  sizes_buf = (FFVkBuffer *)fd->sizes_ref->data;
461 
462  ff_vk_exec_start(&ev->s, exec);
463 
464  ff_vk_exec_add_dep_buf(&ev->s, exec, &fd->coeffs_ref, 1, 1);
465  ff_vk_exec_add_dep_buf(&ev->s, exec, &fd->bytestream_ref, 1, 1);
466  ff_vk_exec_add_dep_buf(&ev->s, exec, &gathered_ref, 1, 0);
467  gathered_ref = NULL; /* Ownership passed */
468  ff_vk_exec_add_dep_buf(&ev->s, exec, &fd->compacted_ref, 1, 1);
469  ff_vk_exec_add_dep_buf(&ev->s, exec, &fd->sizes_ref, 1, 1);
470 
471  RET(ff_vk_exec_add_dep_frame(&ev->s, exec, frame,
472  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
473  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
474 
475  RET(ff_vk_create_imageviews(&ev->s, exec, views, frame, FF_VK_REP_INT));
476 
477  ff_vk_frame_barrier(&ev->s, exec, frame,
478  img_bar, &nb_img_bar,
479  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
480  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
481  VK_ACCESS_SHADER_READ_BIT,
482  VK_IMAGE_LAYOUT_GENERAL,
483  VK_QUEUE_FAMILY_IGNORED);
484 
485  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
486  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
487  .pImageMemoryBarriers = img_bar,
488  .imageMemoryBarrierCount = nb_img_bar,
489  });
490  nb_img_bar = 0;
491 
492  /* DCT + Quantize pass */
493  {
494  ff_vk_shader_update_desc_buffer(&ev->s, exec, &ev->shd_dct,
495  0, 0, 0,
496  coeffs_buf, 0, coeffs_buf->size,
497  VK_FORMAT_UNDEFINED);
498  ff_vk_shader_update_img_array(&ev->s, exec, &ev->shd_dct,
499  frame, views,
500  0, 1,
501  VK_IMAGE_LAYOUT_GENERAL,
502  VK_NULL_HANDLE);
503 
504  ff_vk_exec_bind_shader(&ev->s, exec, &ev->shd_dct);
505  ff_vk_shader_update_push_const(&ev->s, exec, &ev->shd_dct,
506  VK_SHADER_STAGE_COMPUTE_BIT,
507  0, sizeof(ev->dct_push), &ev->dct_push);
508 
509  vk->CmdDispatch(exec->buf,
510  ev->frame_mb_x, ev->frame_mb_y, ev->num_comp);
511  }
512 
513  /* Barrier: wait for coeff writes before entropy */
514  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], coeffs_buf,
515  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE,
516  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE,
517  0, coeffs_buf->size);
518 
519  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
520  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
521  .pBufferMemoryBarriers = buf_bar,
522  .bufferMemoryBarrierCount = nb_buf_bar,
523  });
524  nb_buf_bar = 0;
525 
526  /*
527  * Entropy encoding pass. Luma (component 0) and chroma (components
528  * 1..num_comp-1) run as two dispatches: under chroma sub-sampling their
529  * tile-components hold different block counts, hence different workgroup
530  * sizes -- one pipeline each. The two write disjoint memory and need no
531  * barrier between them, so the GPU is free to overlap them.
532  */
533  for (int p = 0; !ev->skip_entropy && p < 2; p++) {
534  FFVulkanShader *shd = &ev->shd_entropy[p];
535  uint32_t z_comps = (p == 0) ? 1 : ev->num_comp - 1;
536 
537  if (z_comps == 0)
538  continue; /* 4:0:0 (monochrome) has no chroma components */
539 
540  EntropyPushData pd = {
541  .bytestream = bytestream_buf->address,
542  .tile_count = { ev->tile_cols, ev->tile_rows },
543  .num_comp = ev->num_comp,
544  .slot_size = (uint32_t)ev->slot_size,
545  .comp_base = (uint32_t)p,
546  .blocks_per_tile = (uint32_t)ev->tile_mb_w * ev->tile_mb_h *
547  ev->blocks_per_mb,
548  .frame_mb = { ev->frame_mb_x, ev->frame_mb_y },
549  .tile_mb_dim = { ev->tile_mb_w, ev->tile_mb_h },
550  .blocks_per_mb = (uint32_t)(p == 0 ? ev->blocks_per_mb
551  : ev->chroma_blocks_per_mb),
552  };
553 
554  ff_vk_shader_update_desc_buffer(&ev->s, exec, shd, 0, 0, 0,
555  coeffs_buf, 0, coeffs_buf->size,
556  VK_FORMAT_UNDEFINED);
557  ff_vk_shader_update_desc_buffer(&ev->s, exec, shd, 0, 1, 0,
558  sizes_buf, 0, sizes_buf->size,
559  VK_FORMAT_UNDEFINED);
560 
561  ff_vk_exec_bind_shader(&ev->s, exec, shd);
562  ff_vk_shader_update_push_const(&ev->s, exec, shd,
563  VK_SHADER_STAGE_COMPUTE_BIT,
564  0, sizeof(pd), &pd);
565 
566  vk->CmdDispatch(exec->buf, ev->tile_cols, ev->tile_rows, z_comps);
567  }
568 
569  /* Compaction pass: gather the sparse per-tile-component slots into one
570  * contiguous device-local buffer, then read it back with the copy
571  * engine. */
572  if (!ev->headers_only) {
573  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], bytestream_buf,
574  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE,
575  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE,
576  0, bytestream_buf->size);
577  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], sizes_buf,
578  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE,
579  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE,
580  0, sizes_buf->size);
581  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
582  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
583  .pBufferMemoryBarriers = buf_bar,
584  .bufferMemoryBarrierCount = nb_buf_bar,
585  });
586  nb_buf_bar = 0;
587 
588  CompactPushData pd = {
589  .sparse = bytestream_buf->address,
590  .compacted = gathered_buf->address,
591  .slot_size = (uint32_t)ev->slot_size,
592  };
593 
594  ff_vk_shader_update_desc_buffer(&ev->s, exec, &ev->shd_compact,
595  0, 0, 0,
596  sizes_buf, 0, sizes_buf->size,
597  VK_FORMAT_UNDEFINED);
598  ff_vk_exec_bind_shader(&ev->s, exec, &ev->shd_compact);
599  ff_vk_shader_update_push_const(&ev->s, exec, &ev->shd_compact,
600  VK_SHADER_STAGE_COMPUTE_BIT,
601  0, sizeof(pd), &pd);
602 
603  vk->CmdDispatch(exec->buf, ev->tile_count * ev->num_comp, 1, 1);
604 
605  /* The gathered size is only known once the encode is done, so the
606  * whole buffer is copied; the slots are sized to the entropy coder's
607  * worst case, which keeps this close to the payload size. */
608  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], gathered_buf,
609  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE,
610  TRANSFER_BIT, TRANSFER_READ_BIT, NONE,
611  0, gathered_buf->size);
612  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
613  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
614  .pBufferMemoryBarriers = buf_bar,
615  .bufferMemoryBarrierCount = nb_buf_bar,
616  });
617  nb_buf_bar = 0;
618 
619  vk->CmdCopyBuffer(exec->buf, gathered_buf->buf, compacted_buf->buf,
620  1, &(VkBufferCopy) { .size = ev->bytestream_size });
621  }
622 
623  err = ff_vk_exec_submit(&ev->s, exec);
624  if (err < 0)
625  return err;
626 
627  return 0;
628 
629 fail:
630  av_buffer_unref(&gathered_ref);
631  ff_vk_exec_discard_deps(&ev->s, exec);
632  return err;
633 }
634 
635 static int build_packet(AVCodecContext *avctx, FFVkExecContext *exec,
636  AVPacket *pkt)
637 {
638  int err = 0;
639  VulkanEncodeAPVContext *ev = avctx->priv_data;
640  FFVulkanFunctions *vk = &ev->s.vkfn;
641  VulkanEncodeAPVFrameData *fd = exec->opaque;
642  FFVkBuffer *compacted_buf = (FFVkBuffer *)fd->compacted_ref->data;
643  FFVkBuffer *sizes_buf = (FFVkBuffer *)fd->sizes_ref->data;
644  APVRawFrame *raw_frame = NULL;
645 
646  /* Wait for the GPU encode to finish */
647  ff_vk_exec_wait(&ev->s, exec);
648 
649  const uint32_t *sizes = NULL;
650  static uint8_t headers_only_tile; /* 1-byte token tile data */
651 
652  /* Headers-only benchmark mode never touches the GPU output. */
653  if (!ev->headers_only) {
654  /* Invalidate mapped memory if needed */
655  if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
656  VkMappedMemoryRange r = {
657  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
658  .memory = compacted_buf->mem,
659  .offset = 0,
660  .size = VK_WHOLE_SIZE,
661  };
662  vk->InvalidateMappedMemoryRanges(ev->s.hwctx->act_dev, 1, &r);
663  }
664  if (!(sizes_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
665  VkMappedMemoryRange r = {
666  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
667  .memory = sizes_buf->mem,
668  .offset = 0,
669  .size = VK_WHOLE_SIZE,
670  };
671  vk->InvalidateMappedMemoryRanges(ev->s.hwctx->act_dev, 1, &r);
672  }
673  sizes = (const uint32_t *)sizes_buf->mapped_mem;
674  }
675 
676  /* Allocate the cbs frame structure */
677  raw_frame = av_mallocz(sizeof(*raw_frame));
678  if (!raw_frame)
679  return AVERROR(ENOMEM);
680 
682  raw_frame->pbu_header.group_id = 1;
683 
684  APVRawFrameHeader *fh = &raw_frame->frame_header;
686  fh->frame_info.level_idc = ev->level_idc;
687  fh->frame_info.band_idc = ev->band_idc;
688  fh->frame_info.frame_width = avctx->width;
689  fh->frame_info.frame_height = avctx->height;
691  fh->frame_info.bit_depth_minus8 = ev->bit_depth - 8;
693 
695  /* Inferred values when the flag is 0, per the spec. */
696  fh->color_primaries = 2;
697  fh->transfer_characteristics = 2;
698  fh->matrix_coefficients = 2;
699  fh->full_range_flag = 0;
700 
701  /* compute_pf_table() builds the encoder's pf scale from the same matrix;
702  * the two must stay in sync. use_q_matrix is only signalled when the
703  * matrix is non-uniform (a flat 16 matrix is the inferred default). */
705  for (int c = 0; c < ev->num_comp; c++)
706  for (int y = 0; y < 8; y++)
707  for (int x = 0; x < 8; x++)
708  fh->quantization_matrix.q_matrix[c][y][x] =
709  apv_qmatrix_value(ev->qmatrix, y * 8 + x);
710 
714 
715  /* Populate each tile. The compacted buffer holds each tile-component's
716  * data back to back, in (tile, component) order -- the same layout the
717  * gather shader produced. */
718  uint32_t comp_off = 0;
719  for (int t = 0; t < ev->tile_count; t++) {
720  APVRawTile *tile = &raw_frame->tile[t];
721  uint32_t total_tile_data = 0;
722 
723  tile->tile_header.tile_header_size =
724  4 + ev->num_comp * (4 + 1) + 1;
725  tile->tile_header.tile_index = t;
726 
727  for (int c = 0; c < ev->num_comp; c++) {
728  uint32_t sz;
729  if (ev->headers_only) {
730  /* No readback: one token byte (CBS requires size >= 1). */
731  sz = 1;
732  tile->tile_data[c] = &headers_only_tile;
733  } else {
734  sz = sizes[t * ev->num_comp + c];
735  tile->tile_data[c] = compacted_buf->mapped_mem + comp_off;
736  comp_off += sz;
737  }
738  tile->tile_header.tile_data_size[c] = sz;
739  tile->tile_header.tile_qp[c] =
740  (c == 0 || c == 3) ? ev->qp_y : ev->qp_c;
741  total_tile_data += sz;
742  }
743  tile->tile_header.reserved_zero_8bits = 0;
744  tile->tile_dummy_byte_size = 0;
745  tile->tile_dummy_byte = NULL;
746 
747  raw_frame->tile_size[t] =
748  tile->tile_header.tile_header_size + total_tile_data;
749  }
750 
751  /* Assemble fragment using cbs_apv */
752  ff_cbs_fragment_reset(&ev->au);
753 
754  err = ff_cbs_insert_unit_content(&ev->au, -1, APV_PBU_PRIMARY_FRAME,
755  raw_frame, NULL);
756  if (err < 0) {
757  av_freep(&raw_frame);
758  return err;
759  }
760  /* raw_frame is now owned by the fragment unit */
761  raw_frame = NULL;
762 
763  /* Assemble straight into the packet: ff_cbs_write_packet() hands pkt a
764  * reference to CBS's own assembled buffer -- no copy. */
765  err = ff_cbs_write_packet(ev->cbc, pkt, &ev->au);
766  if (err < 0)
767  return err;
768 
769  pkt->pts = fd->pts;
770  pkt->dts = fd->pts;
771  pkt->duration = fd->duration;
772  pkt->flags |= AV_PKT_FLAG_KEY; /* APV is all intra */
773 
774  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
775  pkt->opaque = fd->frame_opaque;
777  fd->frame_opaque_ref = NULL;
778  }
779 
780  av_log(avctx, AV_LOG_VERBOSE, "Encoded APV frame: %i bytes (%.2f MiB)\n",
781  pkt->size, pkt->size / (1024.0 * 1024.0));
782 
787 
788  return 0;
789 }
790 
792  AVPacket *pkt)
793 {
794  int err;
795  VulkanEncodeAPVContext *ev = avctx->priv_data;
797  FFVkExecContext *exec;
798  AVFrame *frame;
799 
800  while (1) {
801  exec = ff_vk_exec_get(&ev->s, &ev->exec_pool);
802 
803  if (exec->had_submission) {
804  exec->had_submission = 0;
805  ev->in_flight--;
806  return build_packet(avctx, exec, pkt);
807  }
808 
809  frame = ev->frame;
810  err = ff_encode_get_frame(avctx, frame);
811  if (err < 0 && err != AVERROR_EOF)
812  return err;
813  else if (err == AVERROR_EOF) {
814  if (!ev->in_flight)
815  return err;
816  continue;
817  }
818 
819  fd = exec->opaque;
820  fd->pts = frame->pts;
821  fd->duration = frame->duration;
822  fd->flags = frame->flags;
823  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
824  fd->frame_opaque = frame->opaque;
825  fd->frame_opaque_ref = frame->opaque_ref;
826  frame->opaque_ref = NULL;
827  }
828 
829  err = submit_frame(avctx, exec, frame);
831  if (err < 0)
832  return err;
833 
834  ev->in_flight++;
835  if (ev->in_flight < ev->async_depth)
836  return AVERROR(EAGAIN);
837  }
838  return 0;
839 }
840 
842 {
843  VulkanEncodeAPVContext *ev = avctx->priv_data;
844 
845  ff_vk_exec_pool_free(&ev->s, &ev->exec_pool);
846 
847  ff_vk_shader_free(&ev->s, &ev->shd_dct);
848  ff_vk_shader_free(&ev->s, &ev->shd_entropy[0]);
849  ff_vk_shader_free(&ev->s, &ev->shd_entropy[1]);
850  ff_vk_shader_free(&ev->s, &ev->shd_compact);
851 
852  if (ev->exec_ctx_info) {
853  for (int i = 0; i < ev->async_depth; i++) {
860  }
861  av_freep(&ev->exec_ctx_info);
862  }
863 
869 
870  ff_cbs_fragment_free(&ev->au);
871  ff_cbs_close(&ev->cbc);
872 
873  av_frame_free(&ev->frame);
874  ff_vk_uninit(&ev->s);
875 
876  return 0;
877 }
878 
880 {
881  int err;
882  VulkanEncodeAPVContext *ev = avctx->priv_data;
883  AVHWFramesContext *hwfc;
884 
885  if (!avctx->hw_frames_ctx) {
886  av_log(avctx, AV_LOG_ERROR, "An AVHWFramesContext is required.\n");
887  return AVERROR(EINVAL);
888  }
889  hwfc = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
890  ev->sw_format = hwfc->sw_format;
891 
894  if (ev->profile_idc < 0 || ev->chroma_format_idc < 0) {
895  av_log(avctx, AV_LOG_ERROR, "Unsupported sw_format %s for APV.\n",
897  return AVERROR(EINVAL);
898  }
899 
900  /* All four APV chroma formats are supported -- 4:0:0, 4:2:2, 4:4:4 and
901  * 4:4:4:4. The profile_idc / chroma_format_idc checks above already
902  * reject any pixel format that is not one of them. */
904  ev->bit_depth = desc->comp[0].depth;
905  ev->num_comp = desc->nb_components;
906  ev->blocks_per_mb = 4; /* luma: 16x16 MB -> 4 8x8 blocks */
907  ev->chroma_blocks_per_mb = 4 >> (desc->log2_chroma_w + desc->log2_chroma_h);
908  ev->level_idc = 33; /* placeholder, real value depends on resolution and bitrate */
909  ev->band_idc = 0;
910 
911  /* Frame dimensions in macroblocks */
912  ev->frame_mb_x = (avctx->width + APV_MB_WIDTH - 1) / APV_MB_WIDTH;
913  ev->frame_mb_y = (avctx->height + APV_MB_HEIGHT - 1) / APV_MB_HEIGHT;
914 
915  /* The 20x20 tile grid cap is structural (fixed-size arrays everywhere);
916  * the spec additionally demands tiles of at least 16x8 MBs. Each
917  * tile-component maps to one entropy workgroup, one invocation per
918  * transform block. */
919  int grid_tw = (ev->frame_mb_x + APV_MAX_TILE_COLS - 1) / APV_MAX_TILE_COLS;
920  int grid_th = (ev->frame_mb_y + APV_MAX_TILE_ROWS - 1) / APV_MAX_TILE_ROWS;
921  int min_tw = FFMAX(APV_MIN_TILE_WIDTH_IN_MBS, grid_tw);
922  int min_th = FFMAX(APV_MIN_TILE_HEIGHT_IN_MBS, grid_th);
923 
924  /* tile_w/tile_h pick the tile size in MBs; 0 selects the spec minimum.
925  * An explicit request below the spec minimum is honoured down to the
926  * grid cap -- non-conformant, but more tiles mean shorter (serial)
927  * entropy streams, which is the decode speed lever. */
928  ev->tile_mb_w = ev->tile_w_mbs_opt > 0 ? ev->tile_w_mbs_opt : min_tw;
929  ev->tile_mb_h = ev->tile_h_mbs_opt > 0 ? ev->tile_h_mbs_opt : min_th;
930  ev->tile_mb_w = FFMIN(FFMAX(ev->tile_mb_w, grid_tw), ev->frame_mb_x);
931  ev->tile_mb_h = FFMIN(FFMAX(ev->tile_mb_h, grid_th), ev->frame_mb_y);
934  av_log(avctx, AV_LOG_WARNING,
935  "Tile size %dx%d MBs is below the spec minimum of %dx%d: "
936  "NON-CONFORMANT bitstream, most decoders will reject it.\n",
937  ev->tile_mb_w, ev->tile_mb_h,
939 
940  /* Left to default, grow the tile toward 1024 transform blocks (the
941  * entropy workgroup ceiling) while it still divides the frame. Bigger
942  * tiles mean fewer tile-components, which the compaction pass strongly
943  * prefers -- it is the dominant win for throughput. */
944  if (!ev->tile_w_mbs_opt && !ev->tile_h_mbs_opt) {
945  while (ev->tile_mb_w * 2 <= ev->frame_mb_x &&
946  ev->frame_mb_x % (ev->tile_mb_w * 2) == 0 &&
947  (ev->tile_mb_w * 2) * ev->tile_mb_h * ev->blocks_per_mb <= 1024)
948  ev->tile_mb_w *= 2;
949  while (ev->tile_mb_h * 2 <= ev->frame_mb_y &&
950  ev->frame_mb_y % (ev->tile_mb_h * 2) == 0 &&
951  ev->tile_mb_w * (ev->tile_mb_h * 2) * ev->blocks_per_mb <= 1024)
952  ev->tile_mb_h *= 2;
953  }
954 
955  /* Ceil division: the rightmost column / bottom row of tiles take the
956  * remainder MBs (spec-legal; the tile grid is closed at the frame edge,
957  * so those tiles may be smaller than the signalled tile size). */
958  ev->tile_cols = (ev->frame_mb_x + ev->tile_mb_w - 1) / ev->tile_mb_w;
959  ev->tile_rows = (ev->frame_mb_y + ev->tile_mb_h - 1) / ev->tile_mb_h;
960  ev->tile_count = ev->tile_cols * ev->tile_rows;
961 
962  if (ev->tile_count > APV_MAX_TILE_COUNT) {
963  av_log(avctx, AV_LOG_ERROR, "Too many tiles (%d).\n", ev->tile_count);
964  return AVERROR(EINVAL);
965  }
966 
967  /* The entropy shader runs one invocation per block in a tile-component
968  * and its shared buffers are sized for 1024. */
969  if (ev->tile_mb_w * ev->tile_mb_h * ev->blocks_per_mb > 1024) {
970  av_log(avctx, AV_LOG_ERROR,
971  "Tile-component has too many transform blocks (%d > 1024).\n",
972  ev->tile_mb_w * ev->tile_mb_h * ev->blocks_per_mb);
973  return AVERROR_PATCHWELCOME;
974  }
975 
976  /* qp_chroma left at 0 means "use the luma QP". */
977  if (ev->qp_c == 0)
978  ev->qp_c = ev->qp_y;
979 
980  /* Validate QP range */
981  int max_qp = 3 + ev->bit_depth * 6;
982  if (ev->qp_y < 0 || ev->qp_y > max_qp || ev->qp_c < 0 || ev->qp_c > max_qp) {
983  av_log(avctx, AV_LOG_ERROR,
984  "QP out of range [0, %d]: qp_y=%d, qp_c=%d.\n",
985  max_qp, ev->qp_y, ev->qp_c);
986  return AVERROR(EINVAL);
987  }
988 
989  /* Buffer sizing */
990  size_t blocks_per_tile = (size_t)ev->tile_mb_w * ev->tile_mb_h * ev->blocks_per_mb;
991  ev->coeffs_size = (size_t)ev->tile_count * ev->num_comp *
992  blocks_per_tile * APV_BLK_COEFFS * sizeof(int16_t);
993 
994  /* Worst-case per-tile-component bytestream: each coefficient at most ~32 bits.
995  * Round up generously. */
996  ev->slot_size = blocks_per_tile * APV_BLK_COEFFS * 8;
997  ev->slot_size = FFALIGN(ev->slot_size, 64);
998  ev->bytestream_size = (size_t)ev->tile_count * ev->num_comp * ev->slot_size;
999  ev->sizes_size = (size_t)ev->tile_count * ev->num_comp * sizeof(uint32_t);
1000 
1001  av_log(avctx, AV_LOG_VERBOSE,
1002  "APV Vulkan encoder: %dx%d, %d tiles (%dx%d MBs each), "
1003  "qp_y=%d qp_c=%d, coeffs=%zu KiB, bytestream=%zu KiB\n",
1004  avctx->width, avctx->height, ev->tile_count,
1005  ev->tile_mb_w, ev->tile_mb_h, ev->qp_y, ev->qp_c,
1006  ev->coeffs_size / 1024, ev->bytestream_size / 1024);
1007 
1008  ev->headers_only = !!getenv("APV_VULKAN_HEADERS_ONLY");
1009  ev->skip_entropy = !!getenv("APV_VULKAN_SKIP_ENTROPY");
1010  if (ev->skip_entropy)
1011  ev->headers_only = 1; /* the bitstream is never produced */
1012  if (ev->headers_only)
1013  av_log(avctx, AV_LOG_WARNING,
1014  "APV_VULKAN_HEADERS_ONLY set: tiles will not be downloaded "
1015  "or assembled; output packets contain headers only.\n");
1016  if (ev->skip_entropy)
1017  av_log(avctx, AV_LOG_WARNING,
1018  "APV_VULKAN_SKIP_ENTROPY set: entropy dispatch skipped "
1019  "(DCT-only benchmark mode).\n");
1020 
1021  /* Init Vulkan */
1022  err = ff_vk_init(&ev->s, avctx, NULL, avctx->hw_frames_ctx);
1023  if (err < 0)
1024  return err;
1025 
1026  ev->qf = ff_vk_qf_find(&ev->s, VK_QUEUE_COMPUTE_BIT, 0);
1027  if (!ev->qf) {
1028  av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1029  return AVERROR(ENOTSUP);
1030  }
1031 
1032  err = ff_vk_exec_pool_init(&ev->s, ev->qf, &ev->exec_pool,
1033  ev->async_depth, 0, 0, 0, NULL);
1034  if (err < 0)
1035  return err;
1036 
1037  /* Init CBS for assembling output */
1038  err = ff_cbs_init(&ev->cbc, AV_CODEC_ID_APV, avctx);
1039  if (err < 0)
1040  return err;
1041 
1042  /* Shaders */
1043  err = init_dct_shader(avctx);
1044  if (err < 0)
1045  return err;
1046  err = init_entropy_shader(avctx, ev->blocks_per_mb, &ev->shd_entropy[0]);
1047  if (err < 0)
1048  return err;
1049  err = init_entropy_shader(avctx, ev->chroma_blocks_per_mb,
1050  &ev->shd_entropy[1]);
1051  if (err < 0)
1052  return err;
1053  err = init_compact_shader(avctx);
1054  if (err < 0)
1055  return err;
1056 
1057  /* The DCT/quantize shader's push constants never change frame to frame;
1058  * build them once. */
1059  build_dct_push_const(avctx);
1060 
1061  ev->frame = av_frame_alloc();
1062  if (!ev->frame)
1063  return AVERROR(ENOMEM);
1064 
1065  /* Async data pool */
1066  ev->async_depth = ev->exec_pool.pool_size;
1067  ev->exec_ctx_info = av_calloc(ev->async_depth, sizeof(*ev->exec_ctx_info));
1068  if (!ev->exec_ctx_info)
1069  return AVERROR(ENOMEM);
1070  for (int i = 0; i < ev->async_depth; i++)
1071  ev->exec_pool.contexts[i].opaque = &ev->exec_ctx_info[i];
1072 
1073  return 0;
1074 }
1075 
1076 #define OFFSET(x) offsetof(VulkanEncodeAPVContext, x)
1077 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1079  { "qp", "Quantization parameter (luma)", OFFSET(qp_y),
1080  AV_OPT_TYPE_INT, { .i64 = 22 }, 0, 255, VE },
1081  { "qp_chroma", "Chroma quantization parameter (0 = same as luma qp)", OFFSET(qp_c),
1082  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 255, VE },
1083  { "qmatrix", "Quantization matrix", OFFSET(qmatrix),
1084  AV_OPT_TYPE_INT, { .i64 = APV_QMATRIX_HEVC }, 0, 1, VE, "qmatrix" },
1085  { "flat", "Uniform matrix, all 16 (APV spec default)", 0,
1086  AV_OPT_TYPE_CONST, { .i64 = APV_QMATRIX_FLAT }, 0, 0, VE, "qmatrix" },
1087  { "hevc", "HEVC default intra scaling list (mild perceptual shaping)", 0,
1088  AV_OPT_TYPE_CONST, { .i64 = APV_QMATRIX_HEVC }, 0, 0, VE, "qmatrix" },
1089  /* The minimum legal tile is 16x8 MBs; the maxima are this encoder's
1090  * ceiling of 1024 transform blocks per tile-component (256 MBs): with
1091  * the other dimension at its minimum, width <= 32 and height <= 16. A
1092  * value of 0 is the sentinel for the adaptive per-frame default. */
1093  { "tile_width", "Tile width in macroblocks (0 = adaptive, auto-sized per frame)", OFFSET(tile_w_mbs_opt),
1094  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 32, VE },
1095  { "tile_height", "Tile height in macroblocks (0 = adaptive, auto-sized per frame)", OFFSET(tile_h_mbs_opt),
1096  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 16, VE },
1097  { "async_depth", "Internal parallelization depth", OFFSET(async_depth),
1098  AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, VE },
1099  { NULL }
1100 };
1101 
1103  { "g", "1" },
1104  { NULL },
1105 };
1106 
1108  .class_name = "apv_vulkan",
1109  .item_name = av_default_item_name,
1110  .option = vulkan_encode_apv_options,
1111  .version = LIBAVUTIL_VERSION_INT,
1112 };
1113 
1115  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1116  NULL,
1117 };
1118 
1120  .p.name = "apv_vulkan",
1121  CODEC_LONG_NAME("Advanced Professional Video (Vulkan)"),
1122  .p.type = AVMEDIA_TYPE_VIDEO,
1123  .p.id = AV_CODEC_ID_APV,
1124  .priv_data_size = sizeof(VulkanEncodeAPVContext),
1127  .close = &vulkan_encode_apv_close,
1128  .p.priv_class = &vulkan_encode_apv_class,
1129  .p.capabilities = AV_CODEC_CAP_DELAY |
1135  .defaults = vulkan_encode_apv_defaults,
1137  .hw_configs = vulkan_encode_apv_hw_configs,
1138  .p.wrapper_name = "vulkan",
1139 };
VulkanEncodeAPVContext::frame_mb_y
int frame_mb_y
Definition: apv_encode_vulkan.c:126
APVRawFrameInfo::capture_time_distance
uint8_t capture_time_distance
Definition: cbs_apv.h:52
EntropyPushData::num_comp
int num_comp
Definition: apv_encode_vulkan.c:65
hwconfig.h
cbs.h
APV_CHROMA_FORMAT_400
@ APV_CHROMA_FORMAT_400
Definition: apv.h:47
CODEC_PIXFMTS
#define CODEC_PIXFMTS(...)
Definition: codec_internal.h:401
ff_seg_gather_comp_spv_data
const unsigned char ff_seg_gather_comp_spv_data[]
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_apv_vulkan_encoder
const FFCodec ff_apv_vulkan_encoder
Definition: apv_encode_vulkan.c:1119
VulkanEncodeAPVContext::headers_only
int headers_only
Definition: apv_encode_vulkan.c:155
VulkanEncodeAPVFrameData::compacted_ref
AVBufferRef * compacted_ref
Definition: apv_encode_vulkan.c:83
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:43
VulkanEncodeAPVContext::shd_dct
FFVulkanShader shd_dct
Definition: apv_encode_vulkan.c:100
r
const char * r
Definition: vf_curves.c:127
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
init_compact_shader
static int init_compact_shader(AVCodecContext *avctx)
Definition: apv_encode_vulkan.c:314
VulkanEncodeAPVFrameData::flags
int flags
Definition: apv_encode_vulkan.c:90
VulkanEncodeAPVContext::sw_format
enum AVPixelFormat sw_format
Definition: apv_encode_vulkan.c:134
APV_PROFILE_422_10
@ APV_PROFILE_422_10
Definition: apv.h:62
vulkan_encode_apv_options
static const AVOption vulkan_encode_apv_options[]
Definition: apv_encode_vulkan.c:1078
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2680
ff_apv_encode_dct_comp_spv_data
const unsigned char ff_apv_encode_dct_comp_spv_data[]
VulkanEncodeAPVContext::level_idc
int level_idc
Definition: apv_encode_vulkan.c:137
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:88
APV_PROFILE_4444_12
@ APV_PROFILE_4444_12
Definition: apv.h:67
FFVkExecPool::contexts
FFVkExecContext * contexts
Definition: vulkan.h:254
vulkan_encode_apv_hw_configs
static const AVCodecHWConfigInternal *const vulkan_encode_apv_hw_configs[]
Definition: apv_encode_vulkan.c:1114
VulkanEncodeAPVFrameData::frame_opaque
void * frame_opaque
Definition: apv_encode_vulkan.c:88
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3460
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_CODEC_CAP_HARDWARE
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: codec.h:127
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
VulkanEncodeAPVContext::skip_entropy
int skip_entropy
Definition: apv_encode_vulkan.c:159
APV_MAX_NUM_COMP
#define APV_MAX_NUM_COMP
Definition: apv_encode_vulkan.c:49
FF_CODEC_CAP_EOF_FLUSH
#define FF_CODEC_CAP_EOF_FLUSH
The encoder has AV_CODEC_CAP_DELAY set, but does not actually have delay - it only wants to be flushe...
Definition: codec_internal.h:90
VulkanEncodeAPVContext::blocks_per_mb
int blocks_per_mb
Definition: apv_encode_vulkan.c:130
APVRawFrameInfo::level_idc
uint8_t level_idc
Definition: cbs_apv.h:45
av_cold
#define av_cold
Definition: attributes.h:119
int64_t
long long int64_t
Definition: coverity.c:34
VulkanEncodeAPVContext::cbc
CodedBitstreamContext * cbc
Definition: apv_encode_vulkan.c:115
DCTPushData::qmat
uint8_t qmat[64]
Definition: apv_encode_vulkan.c:59
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
VulkanEncodeAPVFrameData::coeffs_ref
AVBufferRef * coeffs_ref
Definition: apv_encode_vulkan.c:81
vulkan_encode_apv_receive_packet
static int vulkan_encode_apv_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: apv_encode_vulkan.c:791
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
VulkanEncodeAPVContext::num_comp
int num_comp
Definition: apv_encode_vulkan.c:132
pixdesc.h
VulkanEncodeAPVContext::qf
AVVulkanDeviceQueueFamily * qf
Definition: apv_encode_vulkan.c:97
level_scale
const static int level_scale[2][6]
Definition: intra.c:336
APVRawFrameHeader::color_primaries
uint8_t color_primaries
Definition: cbs_apv.h:72
internal.h
APVRawFrameInfo::profile_idc
uint8_t profile_idc
Definition: cbs_apv.h:44
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:226
APVRawFrame::tile
APVRawTile tile[APV_MAX_TILE_COUNT]
Definition: cbs_apv.h:105
APVRawFrameInfo::frame_width
uint32_t frame_width
Definition: cbs_apv.h:48
AVOption
AVOption.
Definition: opt.h:428
encode.h
VulkanEncodeAPVContext::tile_cols
int tile_cols
Definition: apv_encode_vulkan.c:127
VulkanEncodeAPVContext::compacted_pool
AVBufferPool * compacted_pool
Definition: apv_encode_vulkan.c:108
profile_idc_from_pix_fmt
static int profile_idc_from_pix_fmt(enum AVPixelFormat sw_fmt)
Definition: apv_encode_vulkan.c:219
APV_CHROMA_FORMAT_4444
@ APV_CHROMA_FORMAT_4444
Definition: apv.h:50
FFCodec
Definition: codec_internal.h:127
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
FFVkBuffer::address
VkDeviceAddress address
Definition: vulkan.h:96
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:621
ff_vk_init
int ff_vk_init(FFVulkanContext *s, void *log_parent, AVBufferRef *device_ref, AVBufferRef *frames_ref)
Initializes the AVClass, in case this context is not used as the main user's context.
Definition: vulkan.c:2716
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:568
VulkanEncodeAPVContext::frame_mb_x
int frame_mb_x
Definition: apv_encode_vulkan.c:126
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2704
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
APVRawTileInfo::tile_width_in_mbs
uint32_t tile_width_in_mbs
Definition: cbs_apv.h:61
SPEC_LIST_ADD
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition: vulkan.h:52
apv_level_scale
static const uint8_t apv_level_scale[6]
Definition: apv_encode_vulkan.c:197
APVRawTileInfo::tile_size_present_in_fh_flag
uint8_t tile_size_present_in_fh_flag
Definition: cbs_apv.h:63
APV_PROFILE_422_12
@ APV_PROFILE_422_12
Definition: apv.h:63
FF_VK_REP_INT
@ FF_VK_REP_INT
Definition: vulkan.h:416
EntropyPushData::tile_count
int tile_count[2]
Definition: apv_encode_vulkan.c:64
NONE
#define NONE
Definition: vf_drawvg.c:262
init_entropy_shader
static int init_entropy_shader(AVCodecContext *avctx, int blocks_per_mb, FFVulkanShader *shd)
Definition: apv_encode_vulkan.c:273
ff_vk_exec_bind_shader
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition: vulkan.c:2657
VulkanEncodeAPVFrameData
Definition: apv_encode_vulkan.c:80
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
VulkanEncodeAPVContext::chroma_format_idc
int chroma_format_idc
Definition: apv_encode_vulkan.c:139
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
VulkanEncodeAPVContext::bytestream_size
size_t bytestream_size
Definition: apv_encode_vulkan.c:142
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:800
build_packet
static int build_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
Definition: apv_encode_vulkan.c:635
DCTPushData::bit_depth
int bit_depth
Definition: apv_encode_vulkan.c:57
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3500
AV_CODEC_FLAG_COPY_OPAQUE
#define AV_CODEC_FLAG_COPY_OPAQUE
Definition: avcodec.h:279
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
ff_apv_encode_tiles_comp_spv_data
const unsigned char ff_apv_encode_tiles_comp_spv_data[]
APV_QMATRIX_FLAT
@ APV_QMATRIX_FLAT
Definition: apv_encode_vulkan.c:181
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:639
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:2608
APV_MB_HEIGHT
@ APV_MB_HEIGHT
Definition: apv.h:41
APV_PROFILE_444_12
@ APV_PROFILE_444_12
Definition: apv.h:65
APVRawFrame::pbu_header
APVRawPBUHeader pbu_header
Definition: cbs_apv.h:102
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:2093
VulkanEncodeAPVFrameData::pts
int64_t pts
Definition: apv_encode_vulkan.c:86
APV_CHROMA_FORMAT_444
@ APV_CHROMA_FORMAT_444
Definition: apv.h:49
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
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
APVRawFrameHeader::frame_info
APVRawFrameInfo frame_info
Definition: cbs_apv.h:68
AV_CODEC_CAP_ENCODER_FLUSH
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition: codec.h:148
VulkanEncodeAPVContext
Definition: apv_encode_vulkan.c:93
EntropyPushData::blocks_per_mb
uint32_t blocks_per_mb
Definition: apv_encode_vulkan.c:71
APV_MIN_TILE_HEIGHT_IN_MBS
@ APV_MIN_TILE_HEIGHT_IN_MBS
Definition: apv.h:74
APVRawFrameHeader::transfer_characteristics
uint8_t transfer_characteristics
Definition: cbs_apv.h:73
APVRawFrameInfo::band_idc
uint8_t band_idc
Definition: cbs_apv.h:46
ff_apv_encode_tiles_comp_spv_len
const unsigned int ff_apv_encode_tiles_comp_spv_len
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:548
APVRawPBUHeader::group_id
uint16_t group_id
Definition: cbs_apv.h:35
VulkanEncodeAPVContext::in_flight
int in_flight
Definition: apv_encode_vulkan.c:122
VulkanEncodeAPVFrameData::sizes_ref
AVBufferRef * sizes_ref
Definition: apv_encode_vulkan.c:84
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
EntropyPushData::slot_size
uint32_t slot_size
Definition: apv_encode_vulkan.c:66
VulkanEncodeAPVContext::bit_depth
int bit_depth
Definition: apv_encode_vulkan.c:133
VulkanEncodeAPVContext::slot_size
size_t slot_size
Definition: apv_encode_vulkan.c:143
APVRawFrame::frame_header
APVRawFrameHeader frame_header
Definition: cbs_apv.h:103
VulkanEncodeAPVContext::sizes_size
size_t sizes_size
Definition: apv_encode_vulkan.c:144
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:129
APV_BLK_COEFFS
@ APV_BLK_COEFFS
Definition: apv.h:55
APV_MB_WIDTH
@ APV_MB_WIDTH
Definition: apv.h:40
submit_frame
static int submit_frame(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *frame)
Definition: apv_encode_vulkan.c:391
APVRawFrameHeader::full_range_flag
uint8_t full_range_flag
Definition: cbs_apv.h:75
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:573
VulkanEncodeAPVContext::tile_mb_h
int tile_mb_h
Definition: apv_encode_vulkan.c:128
APV_MAX_TILE_COUNT
@ APV_MAX_TILE_COUNT
Definition: apv.h:77
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition: codec.h:141
VulkanEncodeAPVContext::chroma_blocks_per_mb
int chroma_blocks_per_mb
Definition: apv_encode_vulkan.c:131
APVRawFrameHeader::use_q_matrix
uint8_t use_q_matrix
Definition: cbs_apv.h:77
APVRawTileInfo::tile_height_in_mbs
uint32_t tile_height_in_mbs
Definition: cbs_apv.h:62
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:600
VulkanEncodeAPVContext::frame
AVFrame * frame
Definition: apv_encode_vulkan.c:118
CompactPushData::compacted
VkDeviceAddress compacted
Definition: apv_encode_vulkan.c:76
ff_vk_exec_add_dep_buf
int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e, AVBufferRef **deps, int nb_deps, int ref)
Execution dependency management.
Definition: vulkan.c:640
VulkanEncodeAPVContext::dct_push
DCTPushData dct_push
Definition: apv_encode_vulkan.c:112
APVRawFrameHeader::matrix_coefficients
uint8_t matrix_coefficients
Definition: cbs_apv.h:74
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:299
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:628
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:349
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:525
if
if(ret)
Definition: filter_design.txt:179
VulkanEncodeAPVContext::qp_y
int qp_y
Definition: apv_encode_vulkan.c:149
fail
#define fail
Definition: test.h:478
DCTPushData::qf
float qf[APV_MAX_NUM_COMP]
Definition: apv_encode_vulkan.c:58
DCTPushData::frame_dim
int frame_dim[2]
Definition: apv_encode_vulkan.c:52
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
sizes
static const int sizes[][2]
Definition: img2dec.c:62
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
APV_MAX_TILE_COLS
@ APV_MAX_TILE_COLS
Definition: apv.h:75
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:384
ff_seg_gather_comp_spv_len
const unsigned int ff_seg_gather_comp_spv_len
apv.h
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
vulkan_encode_apv_close
static av_cold int vulkan_encode_apv_close(AVCodecContext *avctx)
Definition: apv_encode_vulkan.c:841
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
APVRawQuantizationMatrix::q_matrix
uint8_t q_matrix[APV_MAX_NUM_COMP][APV_TR_SIZE][APV_TR_SIZE]
Definition: cbs_apv.h:57
CompactPushData
Definition: apv_encode_vulkan.c:74
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
FFVkExecContext::had_submission
int had_submission
Definition: vulkan.h:114
FFVkBuffer::size
size_t size
Definition: vulkan.h:95
APV_PBU_PRIMARY_FRAME
@ APV_PBU_PRIMARY_FRAME
Definition: apv.h:27
SPEC_LIST_CREATE
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition: vulkan.h:42
double
double
Definition: af_crystalizer.c:132
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:546
DCTPushData::log2_chroma_sub
int log2_chroma_sub[2]
Definition: apv_encode_vulkan.c:55
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:100
FFVulkanContext
Definition: vulkan.h:275
APVRawFrame
Definition: cbs_apv.h:101
apv_qmat_hevc_intra
static const uint8_t apv_qmat_hevc_intra[64]
Definition: apv_encode_vulkan.c:169
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
VulkanEncodeAPVContext::qp_c
int qp_c
Definition: apv_encode_vulkan.c:150
VulkanEncodeAPVContext::shd_entropy
FFVulkanShader shd_entropy[2]
Definition: apv_encode_vulkan.c:101
APVRawFrameInfo::frame_height
uint32_t frame_height
Definition: cbs_apv.h:49
ff_vk_buf_barrier
#define ff_vk_buf_barrier(dst, vkb, s_stage, s_access, s_access2, d_stage, d_access, d_access2, offs, bsz)
Definition: vulkan.h:514
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:49
EntropyPushData::frame_mb
int frame_mb[2]
Definition: apv_encode_vulkan.c:69
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:2647
AVPacket::size
int size
Definition: packet.h:604
FFVulkanDescriptorSetBinding
Definition: vulkan.h:78
codec_internal.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
vulkan.h
APVRawFrameHeader
Definition: cbs_apv.h:67
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:550
APV_MIN_TILE_WIDTH_IN_MBS
@ APV_MIN_TILE_WIDTH_IN_MBS
Definition: apv.h:73
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:473
DCTPushData::tile_count
int tile_count[2]
Definition: apv_encode_vulkan.c:53
EntropyPushData::comp_base
uint32_t comp_base
Definition: apv_encode_vulkan.c:67
vulkan_encode_apv_class
static const AVClass vulkan_encode_apv_class
Definition: apv_encode_vulkan.c:1107
FFVulkanShader
Definition: vulkan.h:191
VulkanEncodeAPVContext::s
FFVulkanContext s
Definition: apv_encode_vulkan.c:96
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:552
CompactPushData::sparse
VkDeviceAddress sparse
Definition: apv_encode_vulkan.c:75
apv_qmatrix_value
static int apv_qmatrix_value(int qmatrix, int i)
Definition: apv_encode_vulkan.c:191
APVRawFrameInfo::chroma_format_idc
uint8_t chroma_format_idc
Definition: cbs_apv.h:50
build_dct_push_const
static void build_dct_push_const(AVCodecContext *avctx)
Definition: apv_encode_vulkan.c:350
AVCodecHWConfigInternal
Definition: hwconfig.h:25
APVRawFrameHeader::quantization_matrix
APVRawQuantizationMatrix quantization_matrix
Definition: cbs_apv.h:78
VulkanEncodeAPVContext::bytestream_pool
AVBufferPool * bytestream_pool
Definition: apv_encode_vulkan.c:106
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:94
VulkanEncodeAPVFrameData::frame_opaque_ref
AVBufferRef * frame_opaque_ref
Definition: apv_encode_vulkan.c:89
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
VulkanEncodeAPVContext::tile_w_mbs_opt
int tile_w_mbs_opt
Definition: apv_encode_vulkan.c:147
APVRawFrameHeader::tile_info
APVRawTileInfo tile_info
Definition: cbs_apv.h:80
APV_PROFILE_400_10
@ APV_PROFILE_400_10
Definition: apv.h:68
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:598
init_dct_shader
static int init_dct_shader(AVCodecContext *avctx)
Definition: apv_encode_vulkan.c:233
FFVkExecContext
Definition: vulkan.h:111
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:2621
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
FFVulkanDescriptorSetBinding::name
const char * name
Definition: vulkan.h:79
fact
static double fact(double i)
Definition: af_aiir.c:935
APV_QMATRIX_HEVC
@ APV_QMATRIX_HEVC
Definition: apv_encode_vulkan.c:182
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:100
APV_PROFILE_4444_10
@ APV_PROFILE_4444_10
Definition: apv.h:66
VulkanEncodeAPVContext::tile_count
int tile_count
Definition: apv_encode_vulkan.c:129
vulkan_encode_apv_defaults
static const FFCodecDefault vulkan_encode_apv_defaults[]
Definition: apv_encode_vulkan.c:1102
APV_DEFAULT_QMAT
#define APV_DEFAULT_QMAT
Definition: apv_encode_vulkan.c:48
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:580
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
APVRawPBUHeader::pbu_type
uint8_t pbu_type
Definition: cbs_apv.h:34
VulkanEncodeAPVContext::exec_pool
FFVkExecPool exec_pool
Definition: apv_encode_vulkan.c:98
VulkanEncodeAPVContext::sizes_pool
AVBufferPool * sizes_pool
Definition: apv_encode_vulkan.c:109
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
FFVkBuffer::mem
VkDeviceMemory mem
Definition: vulkan.h:93
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:176
EntropyPushData::blocks_per_tile
uint32_t blocks_per_tile
Definition: apv_encode_vulkan.c:68
AVCodecContext::height
int height
Definition: avcodec.h:604
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
VulkanEncodeAPVContext::coeffs_pool
AVBufferPool * coeffs_pool
Definition: apv_encode_vulkan.c:105
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
avcodec.h
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:2439
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:323
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
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:2010
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:279
tile
static int FUNC() tile(CodedBitstreamContext *ctx, RWContext *rw, APVRawTile *current, int tile_idx, uint32_t tile_size)
Definition: cbs_apv_syntax_template.c:226
FFVkExecContext::opaque
void * opaque
Definition: vulkan.h:128
FFVkExecPool
Definition: vulkan.h:253
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
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
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
APV_CHROMA_FORMAT_422
@ APV_CHROMA_FORMAT_422
Definition: apv.h:48
APVRawFrameHeader::color_description_present_flag
uint8_t color_description_present_flag
Definition: cbs_apv.h:71
AVCodecContext
main external API structure.
Definition: avcodec.h:443
VulkanEncodeAPVFrameData::bytestream_ref
AVBufferRef * bytestream_ref
Definition: apv_encode_vulkan.c:82
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
APV_PROFILE_444_10
@ APV_PROFILE_444_10
Definition: apv.h:64
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:73
VulkanEncodeAPVContext::tile_rows
int tile_rows
Definition: apv_encode_vulkan.c:127
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
APV_MAX_TILE_ROWS
@ APV_MAX_TILE_ROWS
Definition: apv.h:76
CompactPushData::slot_size
uint32_t slot_size
Definition: apv_encode_vulkan.c:77
VulkanEncodeAPVContext::profile_idc
int profile_idc
Definition: apv_encode_vulkan.c:136
VulkanEncodeAPVContext::au
CodedBitstreamFragment au
Definition: apv_encode_vulkan.c:116
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFVulkanContext::hwctx
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:312
mem.h
ff_encode_get_frame
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition: encode.c:217
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
vulkan_encode_apv_init
static av_cold int vulkan_encode_apv_init(AVCodecContext *avctx)
Definition: apv_encode_vulkan.c:879
VulkanEncodeAPVContext::tile_h_mbs_opt
int tile_h_mbs_opt
Definition: apv_encode_vulkan.c:148
VulkanEncodeAPVContext::qmatrix
int qmatrix
Definition: apv_encode_vulkan.c:151
APVRawFrame::tile_size
uint32_t tile_size[APV_MAX_TILE_COUNT]
Definition: cbs_apv.h:104
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:84
ff_vk_exec_discard_deps
void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:612
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
DCTPushData
Definition: apv_encode_vulkan.c:51
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
ff_apv_encode_dct_comp_spv_len
const unsigned int ff_apv_encode_dct_comp_spv_len
VulkanEncodeAPVContext::band_idc
int band_idc
Definition: apv_encode_vulkan.c:138
VulkanEncodeAPVContext::gathered_pool
AVBufferPool * gathered_pool
Definition: apv_encode_vulkan.c:107
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
DCTPushData::num_comp
int num_comp
Definition: apv_encode_vulkan.c:56
VulkanEncodeAPVContext::async_depth
int async_depth
Definition: apv_encode_vulkan.c:121
FFVkBuffer
Definition: vulkan.h:91
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
VE
#define VE
Definition: apv_encode_vulkan.c:1077
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:925
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVVulkanDeviceQueueFamily
Definition: hwcontext_vulkan.h:33
APVRawFrameInfo::bit_depth_minus8
uint8_t bit_depth_minus8
Definition: cbs_apv.h:51
EntropyPushData::bytestream
VkDeviceAddress bytestream
Definition: apv_encode_vulkan.c:63
DCTPushData::tile_mb_dim
int tile_mb_dim[2]
Definition: apv_encode_vulkan.c:54
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:526
VulkanEncodeAPVContext::exec_ctx_info
VulkanEncodeAPVFrameData * exec_ctx_info
Definition: apv_encode_vulkan.c:123
VulkanEncodeAPVContext::tile_mb_w
int tile_mb_w
Definition: apv_encode_vulkan.c:128
EntropyPushData::tile_mb_dim
int tile_mb_dim[2]
Definition: apv_encode_vulkan.c:70
VulkanEncodeAPVFrameData::duration
int64_t duration
Definition: apv_encode_vulkan.c:87
APVRawTile
Definition: cbs_apv.h:93
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
cbs_apv.h
OFFSET
#define OFFSET(x)
Definition: apv_encode_vulkan.c:1076
FFVulkanFunctions
Definition: vulkan_functions.h:275
FFVkExecPool::pool_size
int pool_size
Definition: vulkan.h:259
VulkanEncodeAPVContext::coeffs_size
size_t coeffs_size
Definition: apv_encode_vulkan.c:141
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
ff_vk_get_pooled_buffer
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool, AVBufferRef **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition: vulkan.c:1306
VulkanEncodeAPVContext::shd_compact
FFVulkanShader shd_compact
Definition: apv_encode_vulkan.c:102
chroma_format_from_pix_fmt
static int chroma_format_from_pix_fmt(enum AVPixelFormat sw_fmt)
Definition: apv_encode_vulkan.c:199
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3380
EntropyPushData
Definition: apv_encode_vulkan.c:62