FFmpeg
ffv1enc_vulkan.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 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 "libavutil/mem.h"
22 #include "libavutil/vulkan.h"
23 
24 #include "avcodec.h"
25 #include "internal.h"
26 #include "hwconfig.h"
27 #include "encode.h"
28 #include "libavutil/opt.h"
29 #include "codec_internal.h"
30 
31 #include "ffv1.h"
32 #include "ffv1enc.h"
33 #include "ffv1_vulkan.h"
34 
35 /* Parallel Golomb alignment */
36 #define LG_ALIGN_W 32
37 #define LG_ALIGN_H 32
38 
39 /* Unlike the decoder, we need 4 lines (but really only 3) */
40 #define RGB_LINECACHE 4
41 
42 typedef struct VulkanEncodeFFv1FrameData {
43  /* Output data */
46 
47  /* Copied from the source */
50  void *frame_opaque;
52 
53  int key_frame;
54  int idx;
56 
57 typedef struct VulkanEncodeFFv1Context {
60 
64 
66  int in_flight;
68 
76 
77  /* Constant read-only buffers */
79 
80  /* Results buffer */
82 
83  /* Slice data buffer pool */
86 
87  /* Remap data pool */
89 
90  /* Output data buffer */
92 
93  /* Gathered (contiguous) device-local buffer pool */
95 
96  /* Host-visible readback buffer pool */
98 
99  /* Intermediate frame pool */
101 
106 
107  int is_rgb;
110  int ppi;
111  int chunks;
113 
114 typedef struct SegGatherPushData {
115  VkDeviceAddress sparse;
116  VkDeviceAddress compacted;
117  uint32_t slot_size;
119 
120 extern const char *ff_source_common_comp;
121 extern const char *ff_source_rangecoder_comp;
122 extern const char *ff_source_ffv1_vlc_comp;
123 extern const char *ff_source_ffv1_common_comp;
124 extern const char *ff_source_ffv1_enc_comp;
125 
126 extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
127 extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
128 
129 extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
130 extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
131 
132 extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[];
133 extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len;
134 
135 extern const unsigned char ff_ffv1_enc_comp_spv_data[];
136 extern const unsigned int ff_ffv1_enc_comp_spv_len;
137 
138 extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[];
139 extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len;
140 
141 extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[];
142 extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len;
143 
144 extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[];
145 extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len;
146 
147 extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[];
148 extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len;
149 
150 extern const unsigned char ff_ffv1_enc_remap_comp_spv_data[];
151 extern const unsigned int ff_ffv1_enc_remap_comp_spv_len;
152 
153 extern const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[];
154 extern const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len;
155 
156 extern const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[];
157 extern const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len;
158 
159 extern const unsigned char ff_ffv1_enc_sort32_comp_spv_data[];
160 extern const unsigned int ff_ffv1_enc_sort32_comp_spv_len;
161 
162 extern const unsigned char ff_ffv1_enc_bayer_comp_spv_data[];
163 extern const unsigned int ff_ffv1_enc_bayer_comp_spv_len;
164 
165 extern const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[];
166 extern const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len;
167 
168 extern const unsigned char ff_seg_gather_comp_spv_data[];
169 extern const unsigned int ff_seg_gather_comp_spv_len;
170 
171 /* Size output slots with the v4 worst case; v3's ~(2*bits+5) bytes/sample runs
172  * to gigabytes on large frames. The bitstream version is unaffected. */
173 static size_t ffv1_vk_buffer_size(AVCodecContext *avctx)
174 {
175  VulkanEncodeFFv1Context *fv = avctx->priv_data;
176  FFV1Context *f = &fv->ctx;
177  int version = f->version;
178  size_t size;
179 
180  f->version = 4;
182  f->version = version;
183 
184  return size;
185 }
186 
188  AVFrame *enc_in, VkImageView *enc_in_views,
189  FFVkBuffer *slice_data_buf, uint32_t slice_data_size,
190  FFv1ShaderParams *pd)
191 {
192  VulkanEncodeFFv1Context *fv = avctx->priv_data;
193  FFV1Context *f = &fv->ctx;
194  FFVulkanFunctions *vk = &fv->s.vkfn;
195 
196  /* Update descriptors */
198  1, 0, 0,
199  slice_data_buf,
200  0, slice_data_size*f->slice_count,
201  VK_FORMAT_UNDEFINED);
202  ff_vk_shader_update_img_array(&fv->s, exec, &fv->rct_search,
203  enc_in, enc_in_views,
204  1, 1,
205  VK_IMAGE_LAYOUT_GENERAL,
206  VK_NULL_HANDLE);
207 
208  ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct_search);
210  VK_SHADER_STAGE_COMPUTE_BIT,
211  0, sizeof(FFv1ShaderParams), pd);
212 
213  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
214 
215  return 0;
216 }
217 
218 static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec,
219  AVFrame *enc_in, VkImageView *enc_in_views,
220  FFVkBuffer *fltmap_buf, uint32_t fltmap_size,
221  FFv1ShaderParams *pd)
222 {
223  VulkanEncodeFFv1Context *fv = avctx->priv_data;
224  FFV1Context *f = &fv->ctx;
225  FFVulkanFunctions *vk = &fv->s.vkfn;
226 
227  /* Update descriptors */
228  ff_vk_shader_update_img_array(&fv->s, exec, &fv->remap,
229  enc_in, enc_in_views,
230  1, 1,
231  VK_IMAGE_LAYOUT_GENERAL,
232  VK_NULL_HANDLE);
233  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->remap,
234  1, 2, 0,
235  fltmap_buf,
236  0, fltmap_size*f->slice_count,
237  VK_FORMAT_UNDEFINED);
238 
239  ff_vk_exec_bind_shader(&fv->s, exec, &fv->remap);
240  ff_vk_shader_update_push_const(&fv->s, exec, &fv->remap,
241  VK_SHADER_STAGE_COMPUTE_BIT,
242  0, sizeof(FFv1ShaderParams), pd);
243 
244  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
245 
246  return 0;
247 }
248 
249 static int run_sort32(AVCodecContext *avctx, FFVkExecContext *exec,
250  AVFrame *enc_in, VkImageView *enc_in_views,
251  FFVkBuffer *units_buf, uint32_t units_size,
252  FFv1ShaderParams *pd)
253 {
254  VulkanEncodeFFv1Context *fv = avctx->priv_data;
255  FFV1Context *f = &fv->ctx;
256  FFVulkanFunctions *vk = &fv->s.vkfn;
257 
258  /* Update descriptors */
259  ff_vk_shader_update_img_array(&fv->s, exec, &fv->sort32,
260  enc_in, enc_in_views,
261  1, 1,
262  VK_IMAGE_LAYOUT_GENERAL,
263  VK_NULL_HANDLE);
264  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->sort32,
265  1, 2, 0,
266  units_buf,
267  0, units_size*f->slice_count,
268  VK_FORMAT_UNDEFINED);
269 
270  ff_vk_exec_bind_shader(&fv->s, exec, &fv->sort32);
271  ff_vk_shader_update_push_const(&fv->s, exec, &fv->sort32,
272  VK_SHADER_STAGE_COMPUTE_BIT,
273  0, sizeof(FFv1ShaderParams), pd);
274 
275  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
276 
277  return 0;
278 }
279 
281  FFVkExecContext *exec,
282  const AVFrame *pict)
283 {
284  int err;
285  VulkanEncodeFFv1Context *fv = avctx->priv_data;
286  FFV1Context *f = &fv->ctx;
287  FFVulkanFunctions *vk = &fv->s.vkfn;
288 
289  VulkanEncodeFFv1FrameData *fd = exec->opaque;
290 
291  /* Slice data */
292  FFVkBuffer *slice_data_buf;
293  uint32_t plane_state_size;
294  uint32_t slice_state_size;
295  uint32_t slice_data_size;
296 
297  /* Remap data */
298  FFVkBuffer *remap_data_buf = NULL;
299  uint32_t remap_data_size = 0;
300 
301  /* Output data */
302  size_t maxsize;
303  FFVkBuffer *out_data_buf;
304  FFVkBuffer *gathered_buf = NULL;
305  FFVkBuffer *compacted_buf;
306 
307  int has_inter = avctx->gop_size > 1;
308  uint32_t context_count = f->context_count[f->context_model];
309 
310  VkImageMemoryBarrier2 img_bar[37];
311  int nb_img_bar = 0;
312  VkBufferMemoryBarrier2 buf_bar[8];
313  int nb_buf_bar = 0;
314 
315  /* Frame state */
316  f->cur_enc_frame = pict;
317  if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
319  f->key_frame = fd->key_frame = 1;
320  f->gob_count++;
321  } else {
322  f->key_frame = fd->key_frame = 0;
323  }
324 
325  f->slice_count = f->max_slice_count;
326 
327  /* Allocate slice buffer data */
328  if (f->ac == AC_GOLOMB_RICE)
329  plane_state_size = 8;
330  else
331  plane_state_size = CONTEXT_SIZE;
332 
333  plane_state_size *= context_count;
334  slice_state_size = plane_state_size*f->plane_count;
335 
336  slice_data_size = 256; /* Overestimation for the SliceContext struct */
337  slice_state_size += slice_data_size;
338  slice_state_size = FFALIGN(slice_state_size, 8);
339 
340  /* Allocate slice data buffer */
341  slice_data_buf = fv->keyframe_slice_data_ref ?
343  if (!slice_data_buf) {
345  &slice_data_buf,
346  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
347  NULL, slice_state_size*f->slice_count,
348  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
349 
350  /* Only save it if we're going to use it again */
351  if (has_inter)
352  fv->keyframe_slice_data_ref = av_refstruct_ref(slice_data_buf);
353  }
354 
355  if (f->remap_mode) {
356  if (fv->is_float32) {
357  /* Per (slice, plane): [units : max_pixels*2 uints] + [bitmap : max_pixels uints]. */
358  remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
359  } else {
361  remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
362  }
363 
365  &remap_data_buf,
366  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
367  NULL, remap_data_size*f->slice_count,
368  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
369  }
370 
371  /* Output buffer size */
372  maxsize = ffv1_vk_buffer_size(avctx);
373  maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
374 
375  /* Sparse per-slice slots: written by encode, read by gather. */
377  &fd->out_data_ref,
378  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
379  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
380  NULL, maxsize,
381  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
382  out_data_buf = fd->out_data_ref;
383 
384  /* Device-local gather destination */
386  &gathered_buf,
387  VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
388  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
389  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
390  NULL, maxsize,
391  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
392 
393  /* Contiguous output, read back by the CPU. */
395  &fd->compacted_data_ref,
396  VK_BUFFER_USAGE_TRANSFER_DST_BIT,
397  NULL, maxsize,
398  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
399  fv->s.host_cached_flag));
400  compacted_buf = fd->compacted_data_ref;
401 
402  /* Image views */
403  AVFrame *src = (AVFrame *)pict;
404  VkImageView src_views[AV_NUM_DATA_POINTERS];
405 
406  AVFrame *tmp = NULL;
407  VkImageView tmp_views[AV_NUM_DATA_POINTERS];
408  if (fv->is_rgb) {
409  /* Create a temporaty frame */
410  tmp = av_frame_alloc();
411  if (!(tmp))
412  return AVERROR(ENOMEM);
413 
415  tmp, 0));
416  }
417 
418  /* With everything allocated, setup push data */
419  FFv1ShaderParams pd = {
420  .slice_data = out_data_buf->address,
421 
422  .img_size[0] = fv->s.frames->width,
423  .img_size[1] = fv->s.frames->height,
424 
425  .plane_state_size = plane_state_size,
426  .key_frame = f->key_frame,
427  .crcref = f->crcref,
428  .micro_version = f->micro_version,
429 
430  .sar[0] = pict->sample_aspect_ratio.num,
431  .sar[1] = pict->sample_aspect_ratio.den,
432  .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
433  !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
434 
435  /* 16-byte aligned so the gather can use wide loads */
436  .slice_size_max = (out_data_buf->size / f->slice_count) & ~(size_t)15,
437  .max_pixels_per_slice = fv->max_pixels_per_slice,
438  };
439 
440  for (int i = 0; i < f->quant_table_count; i++) {
441  pd.context_count[i] = f->context_count[i];
442  pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
443  f->quant_tables[i][4][127];
444  }
445 
446  /* For some reason the C FFv1 encoder/decoder treats these differently */
447  if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
448  avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
449  avctx->sw_pix_fmt == AV_PIX_FMT_GBRP14)
450  memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
451  else
452  ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
453 
454  /* Start recording */
455  ff_vk_exec_start(&fv->s, exec);
456  fd->idx = exec->idx;
457 
458  /* For float pixel formats we want the raw bit pattern, not a value
459  * already passed through fp16/fp32 conversion (which can flush
460  * denormals). Use a UINT view in that case. */
461  RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
462  f->remap_mode ? FF_VK_REP_UINT
463  : FF_VK_REP_NATIVE));
464 
467 
468  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
469  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
470  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
471  if (fv->is_rgb)
472  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
473  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
474  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
475 
476  if (fv->optimize_rct || f->remap_mode) {
477  /* Prepare the frame for reading */
478  ff_vk_frame_barrier(&fv->s, exec, src, 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 
493  /* Run RCT search if needed */
494  if (fv->optimize_rct) {
495  RET(run_rct_search(avctx, exec, src, src_views,
496  slice_data_buf, slice_data_size, &pd));
497 
498  /* Make sure the writes are visible to the setup shader */
499  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
500  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
501  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
502  0, slice_data_size*f->slice_count);
503  }
504 
505  if (f->remap_mode) {
506  if (fv->is_float32) {
507  RET(run_sort32(avctx, exec, src, src_views,
508  remap_data_buf, remap_data_size, &pd));
509  } else {
510  RET(run_remap(avctx, exec, src, src_views,
511  remap_data_buf, remap_data_size, &pd));
512  }
513 
514  /* Make sure the writes are visible to the setup shader */
515  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
516  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
517  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
518  0, remap_data_size*f->slice_count);
519  }
520 
521  if (fv->optimize_rct || f->remap_mode) {
522  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
523  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
524  .pBufferMemoryBarriers = buf_bar,
525  .bufferMemoryBarrierCount = nb_buf_bar,
526  });
527  nb_buf_bar = 0;
528  }
529 
530  /* Setup shader */
531  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
532  1, 0, 0,
533  slice_data_buf,
534  0, slice_data_size*f->slice_count,
535  VK_FORMAT_UNDEFINED);
536  if (f->remap_mode)
538  &fv->setup, 1, 1, 0,
539  remap_data_buf,
540  0, remap_data_size*f->slice_count,
541  VK_FORMAT_UNDEFINED);
542 
543  ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
544  ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
545  VK_SHADER_STAGE_COMPUTE_BIT,
546  0, sizeof(FFv1ShaderParams), &pd);
547 
548  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
549 
550  /* Clean up temporary image if needed */
551  if (fv->is_rgb) {
552  AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
553  vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
554  vkf->access[0] = VK_ACCESS_2_NONE;
555 
556  RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
557  tmp,
559 
560  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
561  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
562  VK_PIPELINE_STAGE_2_CLEAR_BIT,
563  VK_ACCESS_2_TRANSFER_WRITE_BIT,
564  VK_IMAGE_LAYOUT_GENERAL,
565  VK_QUEUE_FAMILY_IGNORED);
566  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
567  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
568  .pImageMemoryBarriers = img_bar,
569  .imageMemoryBarrierCount = nb_img_bar,
570  });
571  nb_img_bar = 0;
572 
573  vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
574  &((VkClearColorValue) { 0 }),
575  1, &((VkImageSubresourceRange) {
576  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
577  .levelCount = 1,
578  .layerCount = 1,
579  }));
580  }
581 
582  /* Run reset shader */
583  if (f->key_frame || fv->force_pcm) {
584  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
585  1, 0, 0,
586  slice_data_buf,
587  0, slice_data_size*f->slice_count,
588  VK_FORMAT_UNDEFINED);
589  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
590  1, 1, 0,
591  slice_data_buf,
592  f->slice_count*256,
593  VK_WHOLE_SIZE,
594  VK_FORMAT_UNDEFINED);
595 
596  ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
597  ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
598  VK_SHADER_STAGE_COMPUTE_BIT,
599  0, sizeof(FFv1ShaderParams), &pd);
600 
601  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
602  f->plane_count);
603  }
604 
605  /* Sync between reset and encode shaders */
606  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
607  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
608  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
609  0, slice_data_size*f->slice_count);
610 
611  /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
612  * back into the remap buffer; the encode shader reads it. */
613  if (f->remap_mode)
614  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
615  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
616  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
617  0, remap_data_size*f->slice_count);
618  if (f->key_frame || fv->force_pcm)
619  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
620  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
621  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
622  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
623  else
624  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
625  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
626  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
627  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
628 
629  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
630  fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
631  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
632  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
633  VK_ACCESS_SHADER_READ_BIT,
634  VK_IMAGE_LAYOUT_GENERAL,
635  VK_QUEUE_FAMILY_IGNORED);
636 
637  if (fv->is_rgb)
638  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
639  VK_PIPELINE_STAGE_2_CLEAR_BIT,
640  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
641  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
642  VK_IMAGE_LAYOUT_GENERAL,
643  VK_QUEUE_FAMILY_IGNORED);
644 
645  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
646  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
647  .pImageMemoryBarriers = img_bar,
648  .imageMemoryBarrierCount = nb_img_bar,
649  .pBufferMemoryBarriers = buf_bar,
650  .bufferMemoryBarrierCount = nb_buf_bar,
651  });
652  nb_img_bar = 0;
653  nb_buf_bar = 0;
654 
655  /* Main encode shader */
656  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
657  1, 0, 0,
658  slice_data_buf,
659  0, slice_data_size*f->slice_count,
660  VK_FORMAT_UNDEFINED);
662  &fv->enc, 1, 1, 0,
663  &fv->results_buf,
664  fd->idx*f->max_slice_count*sizeof(uint32_t),
665  f->slice_count*sizeof(uint32_t),
666  VK_FORMAT_UNDEFINED);
667  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
668  1, 2, 0,
669  slice_data_buf,
670  f->slice_count*256,
671  VK_WHOLE_SIZE,
672  VK_FORMAT_UNDEFINED);
673  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
674  src, src_views,
675  1, 3,
676  VK_IMAGE_LAYOUT_GENERAL,
677  VK_NULL_HANDLE);
678  if (fv->is_rgb)
679  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
680  tmp, tmp_views,
681  1, 4,
682  VK_IMAGE_LAYOUT_GENERAL,
683  VK_NULL_HANDLE);
684  if (f->remap_mode)
686  &fv->enc, 1, 5, 0,
687  remap_data_buf,
688  0, remap_data_size*f->slice_count,
689  VK_FORMAT_UNDEFINED);
690 
691  ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
692  ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
693  VK_SHADER_STAGE_COMPUTE_BIT,
694  0, sizeof(FFv1ShaderParams), &pd);
695  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
696 
697  /* Gather the per-slice slots into one contiguous buffer, in the same
698  * submission. */
699  FFVkBuffer *results_buf = &fv->results_buf;
700  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], out_data_buf,
701  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
702  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
703  0, VK_WHOLE_SIZE);
704  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], results_buf,
705  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
706  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
707  0, VK_WHOLE_SIZE);
708  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
709  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
710  .pBufferMemoryBarriers = buf_bar,
711  .bufferMemoryBarrierCount = nb_buf_bar,
712  });
713  nb_buf_bar = 0;
714 
715  SegGatherPushData gather_pd = {
716  .sparse = out_data_buf->address,
717  .compacted = gathered_buf->address,
718  .slot_size = (uint32_t)((out_data_buf->size / f->slice_count) & ~(size_t)15),
719  };
720  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->gather, 0, 0, 0,
721  &fv->results_buf,
722  fd->idx*f->max_slice_count*sizeof(uint32_t),
723  f->slice_count*sizeof(uint32_t),
724  VK_FORMAT_UNDEFINED);
725  ff_vk_exec_bind_shader(&fv->s, exec, &fv->gather);
726  ff_vk_shader_update_push_const(&fv->s, exec, &fv->gather,
727  VK_SHADER_STAGE_COMPUTE_BIT,
728  0, sizeof(gather_pd), &gather_pd);
729  vk->CmdDispatch(exec->buf, f->slice_count, 1, 1);
730 
731  /* Read the gathered bitstream back with the copy engine. The size is
732  * only known once the encode is done, so the whole buffer is copied;
733  * with the version-4 slot sizing this is close to the payload size. */
734  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], gathered_buf,
735  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
736  TRANSFER_BIT, TRANSFER_READ_BIT, NONE_KHR,
737  0, VK_WHOLE_SIZE);
738  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
739  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
740  .pBufferMemoryBarriers = buf_bar,
741  .bufferMemoryBarrierCount = nb_buf_bar,
742  });
743  nb_buf_bar = 0;
744 
745  vk->CmdCopyBuffer(exec->buf, gathered_buf->buf, compacted_buf->buf,
746  1, &(VkBufferCopy) { .size = maxsize });
747 
748  /* Submit */
749  ff_vk_exec_move_dep_refstruct(&fv->s, exec, &slice_data_buf);
750  ff_vk_exec_move_dep_refstruct(&fv->s, exec, &gathered_buf);
751  if (remap_data_buf)
752  ff_vk_exec_move_dep_refstruct(&fv->s, exec, &remap_data_buf);
753  err = ff_vk_exec_submit(&fv->s, exec);
754  if (err < 0)
755  goto fail;
756 
757  f->picture_number++;
758 
759  av_frame_free(&tmp);
760  return 0;
761 
762 fail:
763  av_frame_free(&tmp);
764  av_refstruct_unref(&slice_data_buf);
765  av_refstruct_unref(&remap_data_buf);
766  av_refstruct_unref(&gathered_buf);
767  ff_vk_exec_discard_deps(&fv->s, exec);
768 
769  return err;
770 }
771 
772 /* Return the gathered-output buffer to its pool when the packet is freed. */
773 static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
774 {
775  av_refstruct_unref(&opaque);
776 }
777 
778 static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec,
779  AVPacket *pkt)
780 {
781  VulkanEncodeFFv1Context *fv = avctx->priv_data;
782  FFV1Context *f = &fv->ctx;
783  FFVulkanFunctions *vk = &fv->s.vkfn;
784  VulkanEncodeFFv1FrameData *fd = exec->opaque;
785 
786  FFVkBuffer *compacted_buf = fd->compacted_data_ref;
787 
788  /* Make sure the encode + gather submission is done */
789  ff_vk_exec_wait(&fv->s, exec);
790 
791  /* Invalidate the per-slice sizes if needed */
792  uint32_t rb_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
793  if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
794  VkMappedMemoryRange invalidate_data = {
795  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
796  .memory = fv->results_buf.mem,
797  .offset = rb_off,
798  .size = f->slice_count*sizeof(uint32_t),
799  };
800  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
801  1, &invalidate_data);
802  }
803 
804  /* The gather packed the slices tight and in order; sum their lengths. */
805  pkt->size = 0;
806  uint8_t *rb = fv->results_buf.mapped_mem + rb_off;
807  for (int i = 0; i < f->slice_count; i++) {
808  uint32_t sl_len = AV_RN32(rb + i*4);
809  av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %u\n", i, sl_len);
810  pkt->size += sl_len;
811  }
812  av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
813 
814  /* Invalidate the gathered bitstream if needed */
815  if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
816  VkMappedMemoryRange invalidate_data = {
817  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
818  .memory = compacted_buf->mem,
819  .offset = 0,
820  .size = VK_WHOLE_SIZE,
821  };
822  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
823  1, &invalidate_data);
824  }
825 
826  /* Hand the gathered buffer to the packet with no copy: pkt->buf references
827  * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
828  pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
830  if (!pkt->buf) {
833  return AVERROR(ENOMEM);
834  }
835  fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
836  pkt->data = compacted_buf->mapped_mem;
837 
838  pkt->pts = fd->pts;
839  pkt->dts = fd->pts;
840  pkt->duration = fd->duration;
842 
843  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
844  pkt->opaque = fd->frame_opaque;
846  fd->frame_opaque_ref = NULL;
847  }
848 
850 
851  return 0;
852 }
853 
855  AVPacket *pkt)
856 {
857  int err;
858  VulkanEncodeFFv1Context *fv = avctx->priv_data;
860  FFVkExecContext *exec;
861  AVFrame *frame;
862 
863  while (1) {
864  /* Roll an execution context */
865  exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
866 
867  /* If it had a frame, immediately output it */
868  if (exec->had_submission) {
869  exec->had_submission = 0;
870  fv->in_flight--;
871  return get_packet(avctx, exec, pkt);
872  }
873 
874  /* Get next frame to encode */
875  frame = fv->frame;
876  err = ff_encode_get_frame(avctx, frame);
877  if (err < 0 && err != AVERROR_EOF) {
878  return err;
879  } else if (err == AVERROR_EOF) {
880  if (!fv->in_flight)
881  return err;
882  continue;
883  }
884 
885  /* Encode frame */
886  fd = exec->opaque;
887  fd->pts = frame->pts;
888  fd->duration = frame->duration;
889  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
890  fd->frame_opaque = frame->opaque;
891  fd->frame_opaque_ref = frame->opaque_ref;
892  frame->opaque_ref = NULL;
893  }
894 
895  err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
897  if (err < 0)
898  return err;
899 
900  fv->in_flight++;
901  if (fv->in_flight < fv->async_depth)
902  return AVERROR(EAGAIN);
903  }
904 
905  return 0;
906 }
907 
908 static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
909 {
910  int err;
911  VulkanEncodeFFv1Context *fv = avctx->priv_data;
912  FFV1Context *f = &fv->ctx;
913  AVHWFramesContext *frames_ctx;
914  AVVulkanFramesContext *vk_frames;
915 
917  if (!fv->intermediate_frames_ref)
918  return AVERROR(ENOMEM);
919 
920  frames_ctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data;
921  frames_ctx->format = AV_PIX_FMT_VULKAN;
922  frames_ctx->sw_format = sw_format;
923  frames_ctx->width = fv->s.frames->width;
924  frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
925 
926  vk_frames = frames_ctx->hwctx;
927  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
928  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
929  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
930  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
931 
933  if (err < 0) {
934  av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
935  av_get_pix_fmt_name(sw_format), av_err2str(err));
937  return err;
938  }
939 
940  return 0;
941 }
942 
943 static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
944 {
945  int err;
946  VulkanEncodeFFv1Context *fv = avctx->priv_data;
947  FFVulkanShader *shd = &fv->rct_search;
948 
949  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
950  (uint32_t []) { 32, 32, 1 }, 0);
951 
953  VK_SHADER_STAGE_COMPUTE_BIT);
954 
955  const FFVulkanDescriptorSetBinding desc_set_const[] = {
956  { /* rangecoder_buf */
957  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
958  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
959  },
960  };
961  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
962 
963  const FFVulkanDescriptorSetBinding desc_set[] = {
964  { /* slice_data_buf */
965  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
966  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
967  },
968  { /* src */
969  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
970  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
971  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
972  },
973  };
974  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
975 
976  RET(ff_vk_shader_link(&fv->s, shd,
979 
980  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
981 
982 fail:
983  return err;
984 }
985 
986 static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
987 {
988  int err;
989  VulkanEncodeFFv1Context *fv = avctx->priv_data;
990  FFVulkanShader *shd = &fv->sort32;
991 
992  uint32_t wg_x = FFMIN(fv->max_pixels_per_slice, 256);
993  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
994  (uint32_t []) { wg_x, 1, 1 }, 0);
995 
997  VK_SHADER_STAGE_COMPUTE_BIT);
998 
999  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1000  { /* rangecoder_buf */
1001  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1002  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1003  },
1004  };
1005  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1006 
1007  const FFVulkanDescriptorSetBinding desc_set[] = {
1008  { /* slice_data_buf */
1009  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1010  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1011  },
1012  { /* src */
1013  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1014  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1015  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1016  },
1017  { /* units */
1018  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1019  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1020  },
1021  };
1022  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1023 
1024  RET(ff_vk_shader_link(&fv->s, shd,
1027 
1028  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1029 
1030 fail:
1031  return err;
1032 }
1033 
1034 static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1035 {
1036  int err;
1037  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1038  FFVulkanShader *shd = &fv->remap;
1039 
1040  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1041  (uint32_t []) { 32, 32, 1 }, 0);
1042 
1044  VK_SHADER_STAGE_COMPUTE_BIT);
1045 
1046  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1047  { /* rangecoder_buf */
1048  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1049  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1050  },
1051  };
1052  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1053 
1054  const FFVulkanDescriptorSetBinding desc_set[] = {
1055  { /* slice_data_buf */
1056  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1057  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1058  },
1059  { /* src */
1060  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1061  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1062  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1063  },
1064  { /* fltmap */
1065  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1066  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1067  },
1068  };
1069  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1070 
1071  RET(ff_vk_shader_link(&fv->s, shd,
1074 
1075  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1076 
1077 fail:
1078  return err;
1079 }
1080 
1081 static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1082 {
1083  int err;
1084  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1085  FFVulkanShader *shd = &fv->setup;
1086 
1087  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1088  (uint32_t []) { 1, 1, 1 }, 0);
1089 
1091  VK_SHADER_STAGE_COMPUTE_BIT);
1092 
1093  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1094  { /* rangecoder_buf */
1095  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1096  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1097  },
1098  };
1099  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1100 
1101  const FFVulkanDescriptorSetBinding desc_set[] = {
1102  { /* slice_data_buf */
1103  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1104  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1105  },
1106  { /* fltmap */
1107  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1108  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1109  },
1110  };
1111  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1112 
1113  RET(ff_vk_shader_link(&fv->s, shd,
1116 
1117  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1118 
1119 fail:
1120  return err;
1121 }
1122 
1123 static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1124 {
1125  int err;
1126  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1127  FFVulkanShader *shd = &fv->reset;
1128 
1129  int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1130 
1131  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1132  (uint32_t []) { wg_dim, 1, 1 }, 0);
1133 
1135  VK_SHADER_STAGE_COMPUTE_BIT);
1136 
1137  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1138  { /* rangecoder_buf */
1139  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1140  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1141  },
1142  };
1143  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1144 
1145  const FFVulkanDescriptorSetBinding desc_set[] = {
1146  { /* slice_data_buf */
1147  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1148  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1149  },
1150  { /* slice_state_buf */
1151  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1152  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1153  },
1154  };
1155  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1156 
1157  if (fv->ctx.ac == AC_GOLOMB_RICE)
1158  RET(ff_vk_shader_link(&fv->s, shd,
1161  else
1162  RET(ff_vk_shader_link(&fv->s, shd,
1165 
1166  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1167 
1168 fail:
1169  return err;
1170 }
1171 
1172 static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1173 {
1174  int err;
1175  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1176  FFV1Context *f = &fv->ctx;
1177  FFVulkanShader *shd = &fv->enc;
1178 
1179  uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1180  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1181  (uint32_t []) { wg_x, 1, 1 }, 0);
1182 
1184  VK_SHADER_STAGE_COMPUTE_BIT);
1185 
1186  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1187  { /* rangecoder_buf */
1188  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1189  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1190  },
1191  { /* quant_buf */
1192  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1193  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1194  },
1195  { /* crc_ieee_buf */
1196  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1197  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1198  },
1199  };
1200  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1);
1201 
1202  const FFVulkanDescriptorSetBinding desc_set[] = {
1203  { /* slice_data_buf */
1204  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1205  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1206  },
1207  { /* slice_results_buf */
1208  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1209  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1210  },
1211  { /* slice_state_buf */
1212  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1213  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1214  },
1215  { /* src */
1216  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1217  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1218  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1219  },
1220  { /* tmp */
1221  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1222  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1223  },
1224  { /* fltmap */
1225  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1226  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1227  },
1228  };
1229  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1230  4 + fv->is_rgb + !!f->remap_mode, 0);
1231 
1232  if (f->bayer) {
1233  if (fv->ctx.ac == AC_GOLOMB_RICE)
1234  ff_vk_shader_link(&fv->s, shd,
1237  else
1238  ff_vk_shader_link(&fv->s, shd,
1241  } else if (f->remap_mode) {
1242  if (fv->ctx.ac == AC_GOLOMB_RICE)
1243  ff_vk_shader_link(&fv->s, shd,
1246  else
1247  ff_vk_shader_link(&fv->s, shd,
1250  } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1251  if (fv->is_rgb)
1252  ff_vk_shader_link(&fv->s, shd,
1255  else
1256  ff_vk_shader_link(&fv->s, shd,
1259  } else {
1260  if (fv->is_rgb)
1261  ff_vk_shader_link(&fv->s, shd,
1264  else
1265  ff_vk_shader_link(&fv->s, shd,
1267  ff_ffv1_enc_comp_spv_len, "main");
1268  }
1269 
1270  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1271 
1272 fail:
1273  return err;
1274 }
1275 
1277 {
1278  int err;
1279  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1280  FFVulkanShader *shd = &fv->gather;
1281 
1282  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
1283  (uint32_t []) { 256, 1, 1 }, 0);
1284 
1286  VK_SHADER_STAGE_COMPUTE_BIT);
1287 
1288  const FFVulkanDescriptorSetBinding desc_set[] = {
1289  { /* sizes_buf */
1290  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1291  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1292  },
1293  };
1294  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0);
1295 
1296  RET(ff_vk_shader_link(&fv->s, shd,
1298  ff_seg_gather_comp_spv_len, "main"));
1299 
1300  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1301 
1302 fail:
1303  return err;
1304 }
1305 
1307 {
1308  int err;
1309  size_t maxsize;
1310  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1311  FFV1Context *f = &fv->ctx;
1312 
1313  if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1314  return err;
1315 
1316  if (f->ac == 1)
1317  f->ac = AC_RANGE_CUSTOM_TAB;
1318 
1319  err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1320  if (err < 0)
1321  return err;
1322 
1323  /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1324  * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1325  f->version = f->bayer ? 4 : 3;
1326 
1327  err = ff_ffv1_encode_init(avctx);
1328  if (err < 0)
1329  return err;
1330 
1331  /* Rice coding did not support high bit depths */
1332  if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1333  if (f->ac == AC_GOLOMB_RICE) {
1334  av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1335  "forcing range coder\n");
1336  f->ac = AC_RANGE_CUSTOM_TAB;
1337  }
1338  }
1339 
1340  if (f->version < 4 && avctx->gop_size > 1) {
1341  av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1342  return AVERROR_INVALIDDATA;
1343  }
1344 
1345  if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1346  av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1347  return AVERROR_INVALIDDATA;
1348  }
1349 
1350  /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1351  if (f->version == 4)
1352  f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1353 
1354  f->num_h_slices = fv->num_h_slices;
1355  f->num_v_slices = fv->num_v_slices;
1356 
1357  if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1358  if (avctx->slices) {
1359  err = ff_ffv1_encode_determine_slices(avctx);
1360  if (err < 0)
1361  return err;
1362  } else {
1363  f->num_h_slices = 32;
1364  f->num_v_slices = 32;
1365  }
1366  } else if (f->num_h_slices && f->num_v_slices <= 0) {
1367  f->num_v_slices = MAX_SLICES / f->num_h_slices;
1368  } else if (f->num_v_slices && f->num_h_slices <= 0) {
1369  f->num_h_slices = MAX_SLICES / f->num_v_slices;
1370  }
1371 
1372  f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1373  f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1374 
1375  if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1376  av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1377  "by the standard is %i\n",
1378  f->num_h_slices * f->num_v_slices, MAX_SLICES);
1379  return AVERROR_PATCHWELCOME;
1380  }
1381 
1382  f->max_slice_count = f->num_h_slices * f->num_v_slices;
1383 
1384  if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1385  return err;
1386 
1387  if (f->version < 4) {
1388  if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1389  ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1390  av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1391  "dimensions is only supported in version 4 (-level 4)\n");
1392  return AVERROR_PATCHWELCOME;
1393  }
1394  }
1395 
1396  if (fv->force_pcm) {
1397  if (f->version < 4) {
1398  av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1399  return AVERROR_INVALIDDATA;
1400  } else if (f->ac == AC_GOLOMB_RICE) {
1401  av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1402  return AVERROR_INVALIDDATA;
1403  }
1404  }
1405 
1406  /* Init Vulkan */
1407  err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1408  if (err < 0)
1409  return err;
1410 
1411  fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1412  if (!fv->qf) {
1413  av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1414  return err;
1415  }
1416 
1417  maxsize = ffv1_vk_buffer_size(avctx);
1418  if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1419  av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1420  "than maximum device allocation (%"PRIu64"), clipping\n",
1421  maxsize, fv->s.props_11.maxMemoryAllocationSize);
1422  maxsize = fv->s.props_11.maxMemoryAllocationSize;
1423  }
1424 
1425  av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1426  2*maxsize / (1024*1024),
1427  (fv->async_depth * 2*maxsize) / (1024*1024),
1428  fv->async_depth);
1429 
1430  err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1431  fv->async_depth,
1432  0, 0, 0, NULL);
1433  if (err < 0)
1434  return err;
1435 
1436  /* Detect the special RGB coding mode */
1437  fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1438  !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1439 
1440  fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1441  avctx->sw_pix_fmt == AV_PIX_FMT_GBRAPF32);
1442 
1443  if (fv->is_float32) {
1444  /* Compute the worst-case slice geometry. With version >= 4 the slice
1445  * boundaries are computed via slice_coord() which rounds up, so any
1446  * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1447  * pixels. */
1448  uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1449  uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1450  /* Round up to next pow2 for bitonic sort */
1451  uint32_t n = 1;
1452  uint32_t pn = mw*mh;
1453  while (n < pn)
1454  n <<= 1;
1455  if (n < 2)
1456  n = 2;
1457  fv->max_pixels_per_slice = n;
1458  }
1459 
1460  /* Init rct search shader */
1461  fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1462  !fv->force_pcm && fv->optimize_rct && !f->bayer;
1463 
1464  /* Init shader specialization consts */
1465  SPEC_LIST_CREATE(sl, 19, 19*sizeof(uint32_t))
1466  SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1467  SPEC_LIST_ADD(sl, 1, 32, f->ec);
1468  ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1469  SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1470  SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1471  SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1472  SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1473 
1474  if (fv->optimize_rct) {
1475  err = init_rct_search_shader(avctx, sl);
1476  if (err < 0)
1477  return err;
1478  }
1479 
1480  if (f->remap_mode) {
1481  if (fv->is_float32)
1482  err = init_sort32_shader(avctx, sl);
1483  else
1484  err = init_remap_shader(avctx, sl);
1485  if (err < 0)
1486  return err;
1487  }
1488 
1489  /* Init setup shader */
1490  err = init_setup_shader(avctx, sl);
1491  if (err < 0)
1492  return err;
1493 
1494  /* Init reset shader */
1495  err = init_reset_shader(avctx, sl);
1496  if (err < 0)
1497  return err;
1498 
1499  if (fv->is_rgb)
1500  RET(init_indirect(avctx, fv->ctx.use32bit ?
1502 
1503  /* Encode shader */
1504  err = init_encode_shader(avctx, sl);
1505  if (err < 0)
1506  return err;
1507 
1508  /* Gather shader */
1509  err = init_gather_shader(avctx);
1510  if (err < 0)
1511  return err;
1512 
1513  /* Constant data */
1514  err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1515  if (err < 0)
1516  return err;
1517 
1518  /* Update setup global descriptors */
1520  &fv->setup, 0, 0, 0,
1521  &fv->consts_buf,
1522  256*sizeof(uint32_t), 512*sizeof(uint8_t),
1523  VK_FORMAT_UNDEFINED));
1524 
1525  /* Update encode global descriptors */
1527  &fv->enc, 0, 0, 0,
1528  &fv->consts_buf,
1529  256*sizeof(uint32_t), 512*sizeof(uint8_t),
1530  VK_FORMAT_UNDEFINED));
1532  &fv->enc, 0, 1, 0,
1533  &fv->consts_buf,
1534  256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1535  VK_WHOLE_SIZE,
1536  VK_FORMAT_UNDEFINED));
1538  &fv->enc, 0, 2, 0,
1539  &fv->consts_buf,
1540  0, 256*sizeof(uint32_t),
1541  VK_FORMAT_UNDEFINED));
1542 
1543  /* Temporary frame */
1544  fv->frame = av_frame_alloc();
1545  if (!fv->frame)
1546  return AVERROR(ENOMEM);
1547 
1548  /* Async data pool */
1549  fv->async_depth = fv->exec_pool.pool_size;
1550  fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1551  if (!fv->exec_ctx_info)
1552  return AVERROR(ENOMEM);
1553  for (int i = 0; i < fv->async_depth; i++)
1554  fv->exec_pool.contexts[i].opaque = &fv->exec_ctx_info[i];
1555 
1556  /* Buffers */
1557  RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1558  fv->async_depth*f->max_slice_count*sizeof(uint32_t),
1559  NULL, NULL,
1560  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1561  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1562  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1563  RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1564 
1565 fail:
1566  return err;
1567 }
1568 
1570 {
1571  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1572 
1573  ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1574 
1575  ff_vk_shader_free(&fv->s, &fv->enc);
1576  ff_vk_shader_free(&fv->s, &fv->gather);
1577  ff_vk_shader_free(&fv->s, &fv->reset);
1578  ff_vk_shader_free(&fv->s, &fv->setup);
1579  ff_vk_shader_free(&fv->s, &fv->remap);
1580  ff_vk_shader_free(&fv->s, &fv->sort32);
1581  ff_vk_shader_free(&fv->s, &fv->rct_search);
1582 
1583  if (fv->exec_ctx_info) {
1584  for (int i = 0; i < fv->async_depth; i++) {
1589  }
1590  }
1591  av_free(fv->exec_ctx_info);
1592 
1594 
1598 
1602 
1603  ff_vk_free_buf(&fv->s, &fv->results_buf);
1604 
1605  ff_vk_free_buf(&fv->s, &fv->consts_buf);
1606 
1607  av_frame_free(&fv->frame);
1608  ff_vk_uninit(&fv->s);
1609 
1610  return 0;
1611 }
1612 
1613 #define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1614 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1616  { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1617  { .i64 = -1 }, -1, 2, VE },
1618  { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1619  { .i64 = 0 }, 0, 1, VE },
1620  { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1621  { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1622  { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1623  { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1624  { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1625  { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1626  { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1627  { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1628  { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1629  { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1630  { "default", NULL, 0, AV_OPT_TYPE_CONST,
1631  { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1632  { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1633  { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1634  { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1635  { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1636 
1637  { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1638  { .i64 = -1 }, -1, MAX_SLICES, VE },
1639  { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1640  { .i64 = -1 }, -1, MAX_SLICES, VE },
1641 
1642  { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1643  { .i64 = 0 }, 0, 1, VE },
1644 
1645  { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1646  { .i64 = 1 }, 0, 1, VE },
1647 
1648  { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1649  { .i64 = 1 }, 1, INT_MAX, VE },
1650 
1651  { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1652  { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1653  { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1654  { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1655  { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1656  { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1657  { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1658  { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1659  { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1660  { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1661 
1662  { NULL }
1663 };
1664 
1666  { "g", "1" },
1667  { NULL },
1668 };
1669 
1671  .class_name = "ffv1_vulkan",
1672  .item_name = av_default_item_name,
1673  .option = vulkan_encode_ffv1_options,
1674  .version = LIBAVUTIL_VERSION_INT,
1675 };
1676 
1678  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1679  NULL,
1680 };
1681 
1683  .p.name = "ffv1_vulkan",
1684  CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1685  .p.type = AVMEDIA_TYPE_VIDEO,
1686  .p.id = AV_CODEC_ID_FFV1,
1687  .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1690  .close = &vulkan_encode_ffv1_close,
1691  .p.priv_class = &vulkan_encode_ffv1_class,
1692  .p.capabilities = AV_CODEC_CAP_DELAY |
1698  .defaults = vulkan_encode_ffv1_defaults,
1700  .hw_configs = vulkan_encode_ffv1_hw_configs,
1701  .p.wrapper_name = "vulkan",
1702 };
ffv1_vk_packet_free
static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
Definition: ffv1enc_vulkan.c:773
hwconfig.h
ff_ffv1_enc_sort32_comp_spv_data
const unsigned char ff_ffv1_enc_sort32_comp_spv_data[]
CODEC_PIXFMTS
#define CODEC_PIXFMTS(...)
Definition: codec_internal.h:409
ff_vk_create_buf
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, void *pNext, void *alloc_pNext, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Definition: vulkan.c:1016
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
ff_ffv1_enc_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_golomb_comp_spv_len
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
VulkanEncodeFFv1Context::out_data_pool
AVRefStructPool * out_data_pool
Definition: ffv1enc_vulkan.c:91
QTABLE_8BIT
@ QTABLE_8BIT
Definition: ffv1enc.h:30
ff_ffv1_encode_determine_slices
int ff_ffv1_encode_determine_slices(AVCodecContext *avctx)
Definition: ffv1enc.c:570
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
ff_ffv1_enc_comp_spv_len
const unsigned int ff_ffv1_enc_comp_spv_len
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
AV_PIX_FMT_YA8
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition: pixfmt.h:140
ff_ffv1_enc_rgb_float_golomb_comp_spv_data
const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[]
FFVulkanContext::props_11
VkPhysicalDeviceVulkan11Properties props_11
Definition: vulkan.h:297
VulkanEncodeFFv1Context::gather
FFVulkanShader gather
Definition: ffv1enc_vulkan.c:75
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2614
FFVulkanContext::device_ref
AVBufferRef * device_ref
Definition: vulkan.h:327
FFVkExecPool::contexts
FFVkExecContext * contexts
Definition: vulkan.h:269
ff_vk_exec_add_dep_refstruct
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition: vulkan.c:687
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:133
RET
#define RET(x)
Definition: vulkan.h:37
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
FFv1ShaderParams::fmt_lut
int fmt_lut[4]
Definition: ffv1_vulkan.h:39
VulkanEncodeFFv1Context::is_rgb
int is_rgb
Definition: ffv1enc_vulkan.c:107
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
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
av_cold
#define av_cold
Definition: attributes.h:119
int64_t
long long int64_t
Definition: coverity.c:34
VulkanEncodeFFv1Context::in_flight
int in_flight
Definition: ffv1enc_vulkan.c:66
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
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
ff_vk_map_buffer
static int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem, int invalidate)
Definition: vulkan.h:614
VulkanEncodeFFv1Context::chunks
int chunks
Definition: ffv1enc_vulkan.c:111
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
internal.h
AC_RANGE_DEFAULT_TAB_FORCE
#define AC_RANGE_DEFAULT_TAB_FORCE
Definition: ffv1.h:55
AVPacket::data
uint8_t * data
Definition: packet.h:603
run_remap
static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *fltmap_buf, uint32_t fltmap_size, FFv1ShaderParams *pd)
Definition: ffv1enc_vulkan.c:218
AVOption
AVOption.
Definition: opt.h:428
encode.h
mh
#define mh
Definition: vf_colormatrix.c:105
VulkanEncodeFFv1Context::rct_search
FFVulkanShader rct_search
Definition: ffv1enc_vulkan.c:69
ff_source_ffv1_vlc_comp
const char * ff_source_ffv1_vlc_comp
data
const char data[16]
Definition: mxf.c:149
AV_PIX_FMT_RGBA128
#define AV_PIX_FMT_RGBA128
Definition: pixfmt.h:636
ff_ffv1_write_extradata
av_cold int ff_ffv1_write_extradata(AVCodecContext *avctx)
Definition: ffv1enc.c:447
FFCodec
Definition: codec_internal.h:129
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
FFV1Context::num_h_slices
int num_h_slices
Definition: ffv1.h:177
FFVkBuffer::address
VkDeviceAddress address
Definition: vulkan.h:99
VulkanEncodeFFv1Context::remap_data_pool
AVRefStructPool * remap_data_pool
Definition: ffv1enc_vulkan.c:88
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:2651
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
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2638
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: defs.h:62
ff_ffv1_enc_rgb_float_comp_spv_len
const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:716
ffv1_vk_buffer_size
static size_t ffv1_vk_buffer_size(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:173
SPEC_LIST_ADD
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition: vulkan.h:55
init_remap_shader
static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1034
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
AC_RANGE_CUSTOM_TAB
#define AC_RANGE_CUSTOM_TAB
Definition: ffv1.h:54
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
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
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
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:95
ff_ffv1_enc_remap_comp_spv_len
const unsigned int ff_ffv1_enc_remap_comp_spv_len
VulkanEncodeFFv1Context::results_buf
FFVkBuffer results_buf
Definition: ffv1enc_vulkan.c:81
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:700
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
vulkan_encode_ffv1_class
static const AVClass vulkan_encode_ffv1_class
Definition: ffv1enc_vulkan.c:1670
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:133
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:566
AVVkFrame::img
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Definition: hwcontext_vulkan.h:266
VulkanEncodeFFv1FrameData::key_frame
int key_frame
Definition: ffv1enc_vulkan.c:53
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:639
VulkanEncodeFFv1Context::num_v_slices
int num_v_slices
Definition: ffv1enc_vulkan.c:103
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:564
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
init_gather_shader
static int init_gather_shader(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1276
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:171
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
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::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
VulkanEncodeFFv1Context::ppi
int ppi
Definition: ffv1enc_vulkan.c:110
MAX_SLICES
#define MAX_SLICES
Definition: d3d12va_hevc.c:33
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:45
AV_CODEC_CAP_ENCODER_FLUSH
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition: codec.h:154
SegGatherPushData::compacted
VkDeviceAddress compacted
Definition: ffv1enc_vulkan.c:116
ff_ffv1_enc_setup_comp_spv_len
const unsigned int ff_ffv1_enc_setup_comp_spv_len
VulkanEncodeFFv1FrameData::frame_opaque_ref
AVBufferRef * frame_opaque_ref
Definition: ffv1enc_vulkan.c:51
AVRational::num
int num
Numerator.
Definition: rational.h:59
ff_ffv1_vulkan_encoder
const FFCodec ff_ffv1_vulkan_encoder
Definition: ffv1enc_vulkan.c:1682
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
FFVulkanDescriptorSetBinding::type
VkDescriptorType type
Definition: vulkan.h:83
VulkanEncodeFFv1Context::s
FFVulkanContext s
Definition: ffv1enc_vulkan.c:61
VulkanEncodeFFv1FrameData
Definition: ffv1enc_vulkan.c:42
vulkan_encode_ffv1_hw_configs
const AVCodecHWConfigInternal *const vulkan_encode_ffv1_hw_configs[]
Definition: ffv1enc_vulkan.c:1677
get_packet
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:778
ff_ffv1_enc_rgb_float_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
VulkanEncodeFFv1Context::exec_ctx_info
VulkanEncodeFFv1FrameData * exec_ctx_info
Definition: ffv1enc_vulkan.c:65
VulkanEncodeFFv1Context::setup
FFVulkanShader setup
Definition: ffv1enc_vulkan.c:72
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
FFV1Context::use32bit
int use32bit
Definition: ffv1.h:160
ff_ffv1_enc_reset_comp_spv_data
const unsigned char ff_ffv1_enc_reset_comp_spv_data[]
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:590
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:147
ff_seg_gather_comp_spv_data
const unsigned char ff_seg_gather_comp_spv_data[]
ff_vk_set_perm
void ff_vk_set_perm(enum AVPixelFormat pix_fmt, int lut[4], int inv)
Since storage images may not be swizzled, we have to do this in the shader itself.
Definition: vulkan.c:1526
QTABLE_GT8BIT
@ QTABLE_GT8BIT
Definition: ffv1enc.h:31
FFVulkanContext::host_cached_flag
VkMemoryPropertyFlagBits host_cached_flag
Definition: vulkan.h:325
AVVulkanFramesContext::img_flags
VkImageCreateFlags img_flags
Flags to set during image creation.
Definition: hwcontext_vulkan.h:224
vulkan_encode_ffv1_receive_packet
static int vulkan_encode_ffv1_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:854
ff_source_ffv1_common_comp
const char * ff_source_ffv1_common_comp
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
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
FFV1Context::ac
int ac
1=range coder <-> 0=golomb rice
Definition: ffv1.h:147
ff_ffv1_encode_setup_plane_info
av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, enum AVPixelFormat pix_fmt)
Definition: ffv1enc.c:807
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:310
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:628
ff_ffv1_enc_bayer_comp_spv_data
const unsigned char ff_ffv1_enc_bayer_comp_spv_data[]
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:357
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
ff_vk_exec_move_dep_refstruct
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition: vulkan.c:694
ff_ffv1_enc_rct_search_comp_spv_len
const unsigned int ff_ffv1_enc_rct_search_comp_spv_len
FFv1ShaderParams::extend_lookup
uint32_t extend_lookup[8]
Definition: ffv1_vulkan.h:36
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
VulkanEncodeFFv1Context::frame
AVFrame * frame
Definition: ffv1enc_vulkan.c:59
fail
#define fail
Definition: test.h:479
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:586
ff_ffv1_vk_init_consts
int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
Definition: ffv1_vulkan.c:85
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:535
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
ff_ffv1_enc_rgb_comp_spv_len
const unsigned int ff_ffv1_enc_rgb_comp_spv_len
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
run_rct_search
static int run_rct_search(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *slice_data_buf, uint32_t slice_data_size, FFv1ShaderParams *pd)
Definition: ffv1enc_vulkan.c:187
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
AC_GOLOMB_RICE
#define AC_GOLOMB_RICE
Definition: ffv1.h:52
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
init_encode_shader
static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1172
FFV1Context::num_v_slices
int num_v_slices
Definition: ffv1.h:176
VulkanEncodeFFv1Context::force_pcm
int force_pcm
Definition: ffv1enc_vulkan.c:104
VulkanEncodeFFv1Context::consts_buf
FFVkBuffer consts_buf
Definition: ffv1enc_vulkan.c:78
VulkanEncodeFFv1FrameData::idx
int idx
Definition: ffv1enc_vulkan.c:54
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:392
ff_ffv1_enc_bayer_golomb_comp_spv_data
const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[]
ff_ffv1_enc_rgb_comp_spv_data
const unsigned char ff_ffv1_enc_rgb_comp_spv_data[]
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:360
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
FFVkExecContext::had_submission
int had_submission
Definition: vulkan.h:131
FFVkBuffer::size
size_t size
Definition: vulkan.h:98
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:191
SPEC_LIST_CREATE
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition: vulkan.h:45
ff_ffv1_enc_rgb_golomb_comp_spv_data
const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[]
ffv1_vulkan.h
AVVkFrame::access
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
Definition: hwcontext_vulkan.h:290
VulkanEncodeFFv1Context::num_h_slices
int num_h_slices
Definition: ffv1enc_vulkan.c:102
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:103
FFVulkanContext
Definition: vulkan.h:290
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
VulkanEncodeFFv1FrameData::duration
int64_t duration
Definition: ffv1enc_vulkan.c:49
VulkanEncodeFFv1Context
Definition: ffv1enc_vulkan.c:57
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:83
f
f
Definition: af_crystalizer.c:122
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:562
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
VulkanEncodeFFv1Context::ctx
FFV1Context ctx
Definition: ffv1enc_vulkan.c:58
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
AVPacket::size
int size
Definition: packet.h:604
FFVulkanDescriptorSetBinding
Definition: vulkan.h:81
VulkanEncodeFFv1FrameData::pts
int64_t pts
Definition: ffv1enc_vulkan.c:48
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1021
codec_internal.h
AVVkFrame
Definition: hwcontext_vulkan.h:261
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
vulkan.h
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:584
size
int size
Definition: twinvq_data.h:10344
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:473
init_indirect
static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
Definition: ffv1enc_vulkan.c:908
FFVulkanShader
Definition: vulkan.h:206
VulkanEncodeFFv1Context::optimize_rct
int optimize_rct
Definition: ffv1enc_vulkan.c:105
VulkanEncodeFFv1Context::gathered_data_pool
AVRefStructPool * gathered_data_pool
Definition: ffv1enc_vulkan.c:94
AVCodecHWConfigInternal
Definition: hwconfig.h:25
QTABLE_DEFAULT
@ QTABLE_DEFAULT
Definition: ffv1enc.h:29
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:97
ff_ffv1_enc_remap_comp_spv_data
const unsigned char ff_ffv1_enc_remap_comp_spv_data[]
ff_ffv1_enc_reset_comp_spv_len
const unsigned int ff_ffv1_enc_reset_comp_spv_len
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
ff_source_common_comp
const char * ff_source_common_comp
av_refstruct_ref
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
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
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
VulkanEncodeFFv1Context::sort32
FFVulkanShader sort32
Definition: ffv1enc_vulkan.c:71
ff_ffv1_enc_rct_search_comp_spv_data
const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[]
version
version
Definition: libkvazaar.c:313
VulkanEncodeFFv1Context::enc
FFVulkanShader enc
Definition: ffv1enc_vulkan.c:74
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
ff_ffv1_enc_golomb_comp_spv_data
const unsigned char ff_ffv1_enc_golomb_comp_spv_data[]
ff_ffv1_vk_set_common_sl
void ff_ffv1_vk_set_common_sl(AVCodecContext *avctx, FFV1Context *f, VkSpecializationInfo *sl, enum AVPixelFormat sw_format)
Definition: ffv1_vulkan.c:24
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
VE
#define VE
Definition: ffv1enc_vulkan.c:1614
ff_ffv1_enc_sort32_comp_spv_len
const unsigned int ff_ffv1_enc_sort32_comp_spv_len
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:100
ff_source_ffv1_enc_comp
const char * ff_source_ffv1_enc_comp
VulkanEncodeFFv1Context::compacted_data_pool
AVRefStructPool * compacted_data_pool
Definition: ffv1enc_vulkan.c:97
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:599
SegGatherPushData::sparse
VkDeviceAddress sparse
Definition: ffv1enc_vulkan.c:115
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
ff_ffv1_enc_bayer_comp_spv_len
const unsigned int ff_ffv1_enc_bayer_comp_spv_len
FF_VK_REP_UINT
@ FF_VK_REP_UINT
Definition: vulkan.h:435
ff_ffv1_enc_reset_golomb_comp_spv_data
const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[]
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:565
VulkanEncodeFFv1Context::slice_data_pool
AVRefStructPool * slice_data_pool
Definition: ffv1enc_vulkan.c:84
ff_ffv1_common_init
av_cold int ff_ffv1_common_init(AVCodecContext *avctx, FFV1Context *s)
Definition: ffv1.c:36
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ffv1.h
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:96
SegGatherPushData
Definition: ffv1enc_vulkan.c:114
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:182
vulkan_encode_ffv1_close
static av_cold int vulkan_encode_ffv1_close(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1569
FFVulkanContext::props
VkPhysicalDeviceProperties2 props
Definition: vulkan.h:296
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition: vulkan.c:1230
AVCodecContext::height
int height
Definition: avcodec.h:604
init_setup_shader
static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1081
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:695
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
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_ffv1_enc_bayer_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len
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
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
ff_ffv1_encode_buffer_size
size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx)
Definition: ffv1enc.c:1863
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_seg_gather_comp_spv_len
const unsigned int ff_seg_gather_comp_spv_len
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
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:294
SegGatherPushData::slot_size
uint32_t slot_size
Definition: ffv1enc_vulkan.c:117
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
AVCodecContext::strict_std_compliance
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition: avcodec.h:1375
VulkanEncodeFFv1Context::exec_pool
FFVkExecPool exec_pool
Definition: ffv1enc_vulkan.c:63
FFVkExecContext::opaque
void * opaque
Definition: vulkan.h:150
FFVkExecPool
Definition: vulkan.h:268
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
VulkanEncodeFFv1Context::intermediate_frames_ref
AVBufferRef * intermediate_frames_ref
Definition: ffv1enc_vulkan.c:100
VulkanEncodeFFv1FrameData::frame_opaque
void * frame_opaque
Definition: ffv1enc_vulkan.c:50
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:569
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:297
vulkan_encode_ffv1_options
static const AVOption vulkan_encode_ffv1_options[]
Definition: ffv1enc_vulkan.c:1615
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:139
AVCodecContext
main external API structure.
Definition: avcodec.h:443
ff_ffv1_enc_comp_spv_data
const unsigned char ff_ffv1_enc_comp_spv_data[]
init_reset_shader
static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1123
VulkanEncodeFFv1FrameData::compacted_data_ref
FFVkBuffer * compacted_data_ref
Definition: ffv1enc_vulkan.c:45
RGB_LINECACHE
#define RGB_LINECACHE
Definition: ffv1enc_vulkan.c:40
VulkanEncodeFFv1Context::reset
FFVulkanShader reset
Definition: ffv1enc_vulkan.c:73
AVRational::den
int den
Denominator.
Definition: rational.h:60
run_sort32
static int run_sort32(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *units_buf, uint32_t units_size, FFv1ShaderParams *pd)
Definition: ffv1enc_vulkan.c:249
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:585
VulkanEncodeFFv1Context::async_depth
int async_depth
Definition: ffv1enc_vulkan.c:67
VulkanEncodeFFv1FrameData::out_data_ref
FFVkBuffer * out_data_ref
Definition: ffv1enc_vulkan.c:44
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:79
ffv1enc.h
vulkan_encode_ffv1_submit_frame
static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, FFVkExecContext *exec, const AVFrame *pict)
Definition: ffv1enc_vulkan.c:280
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:180
VulkanEncodeFFv1Context::qf
AVVulkanDeviceQueueFamily * qf
Definition: ffv1enc_vulkan.c:62
vulkan_encode_ffv1_defaults
static const FFCodecDefault vulkan_encode_ffv1_defaults[]
Definition: ffv1enc_vulkan.c:1665
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:329
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:218
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:291
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
ff_ffv1_encode_init
av_cold int ff_ffv1_encode_init(AVCodecContext *avctx)
Definition: ffv1enc.c:605
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
VulkanEncodeFFv1Context::is_float32
int is_float32
Definition: ffv1enc_vulkan.c:108
FFV1Context
Definition: ffv1.h:122
av_refstruct_pool_uninit
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFv1ShaderParams
Definition: ffv1_vulkan.h:33
ff_vk_exec_discard_deps
void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:636
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1037
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
VulkanEncodeFFv1Context::keyframe_slice_data_ref
FFVkBuffer * keyframe_slice_data_ref
Definition: ffv1enc_vulkan.c:85
VulkanEncodeFFv1Context::max_pixels_per_slice
uint32_t max_pixels_per_slice
Definition: ffv1enc_vulkan.c:109
FFVkBuffer
Definition: vulkan.h:94
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
vulkan_encode_ffv1_init
static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1306
FFv1ShaderParams::context_count
uint16_t context_count[8]
Definition: ffv1_vulkan.h:37
ff_ffv1_enc_reset_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:881
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVVulkanDeviceQueueFamily
Definition: hwcontext_vulkan.h:33
ff_ffv1_enc_setup_comp_spv_data
const unsigned char ff_ffv1_enc_setup_comp_spv_data[]
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
FFVulkanContext::frames
AVHWFramesContext * frames
Definition: vulkan.h:333
ff_ffv1_enc_rgb_float_comp_spv_data
const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[]
OFFSET
#define OFFSET(x)
Definition: ffv1enc_vulkan.c:1613
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
VulkanEncodeFFv1Context::remap
FFVulkanShader remap
Definition: ffv1enc_vulkan.c:70
FFv1ShaderParams::slice_data
VkDeviceAddress slice_data
Definition: ffv1_vulkan.h:34
ff_ffv1_enc_rgb_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len
av_hwframe_get_buffer
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:506
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
init_sort32_shader
static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:986
FFVulkanFunctions
Definition: vulkan_functions.h:276
FFVkExecPool::pool_size
int pool_size
Definition: vulkan.h:274
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
FFVkExecContext::idx
uint32_t idx
Definition: vulkan.h:129
src
#define src
Definition: vp8dsp.c:248
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
init_rct_search_shader
static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:943
ff_source_rangecoder_comp
const char * ff_source_rangecoder_comp