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  AVBufferRef *slice_data_ref;
293  FFVkBuffer *slice_data_buf;
294  uint32_t plane_state_size;
295  uint32_t slice_state_size;
296  uint32_t slice_data_size;
297 
298  /* Remap data */
299  AVBufferRef *remap_data_ref = NULL;
300  FFVkBuffer *remap_data_buf = NULL;
301  uint32_t remap_data_size = 0;
302 
303  /* Output data */
304  size_t maxsize;
305  FFVkBuffer *out_data_buf;
306  AVBufferRef *gathered_ref = NULL;
307  FFVkBuffer *gathered_buf;
308  FFVkBuffer *compacted_buf;
309 
310  int has_inter = avctx->gop_size > 1;
311  uint32_t context_count = f->context_count[f->context_model];
312 
313  VkImageMemoryBarrier2 img_bar[37];
314  int nb_img_bar = 0;
315  VkBufferMemoryBarrier2 buf_bar[8];
316  int nb_buf_bar = 0;
317 
318  /* Frame state */
319  f->cur_enc_frame = pict;
320  if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
322  f->key_frame = fd->key_frame = 1;
323  f->gob_count++;
324  } else {
325  f->key_frame = fd->key_frame = 0;
326  }
327 
328  f->slice_count = f->max_slice_count;
329 
330  /* Allocate slice buffer data */
331  if (f->ac == AC_GOLOMB_RICE)
332  plane_state_size = 8;
333  else
334  plane_state_size = CONTEXT_SIZE;
335 
336  plane_state_size *= context_count;
337  slice_state_size = plane_state_size*f->plane_count;
338 
339  slice_data_size = 256; /* Overestimation for the SliceContext struct */
340  slice_state_size += slice_data_size;
341  slice_state_size = FFALIGN(slice_state_size, 8);
342 
343  /* Allocate slice data buffer */
344  slice_data_ref = fv->keyframe_slice_data_ref;
345  if (!slice_data_ref) {
347  &slice_data_ref,
348  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
349  NULL, slice_state_size*f->slice_count,
350  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
351 
352  /* Only save it if we're going to use it again */
353  if (has_inter)
354  fv->keyframe_slice_data_ref = slice_data_ref;
355  }
356  slice_data_buf = (FFVkBuffer *)slice_data_ref->data;
357 
358  if (f->remap_mode) {
359  if (fv->is_float32) {
360  /* Per (slice, plane): [units : max_pixels*2 uints] + [bitmap : max_pixels uints]. */
361  remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
362  } else {
364  remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
365  }
366 
368  &remap_data_ref,
369  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
370  NULL, remap_data_size*f->slice_count,
371  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
372  remap_data_buf = (FFVkBuffer *)remap_data_ref->data;
373  }
374 
375  /* Output buffer size */
376  maxsize = ffv1_vk_buffer_size(avctx);
377  maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
378 
379  /* Sparse per-slice slots: written by encode, read by gather. */
381  &fd->out_data_ref,
382  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
383  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
384  NULL, maxsize,
385  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
386  out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
387 
388  /* Device-local gather destination */
390  &gathered_ref,
391  VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
392  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
393  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
394  NULL, maxsize,
395  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
396  gathered_buf = (FFVkBuffer *)gathered_ref->data;
397 
398  /* Contiguous output, read back by the CPU. */
400  &fd->compacted_data_ref,
401  VK_BUFFER_USAGE_TRANSFER_DST_BIT,
402  NULL, maxsize,
403  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
404  fv->s.host_cached_flag));
405  compacted_buf = (FFVkBuffer *)fd->compacted_data_ref->data;
406 
407  /* Image views */
408  AVFrame *src = (AVFrame *)pict;
409  VkImageView src_views[AV_NUM_DATA_POINTERS];
410 
411  AVFrame *tmp = NULL;
412  VkImageView tmp_views[AV_NUM_DATA_POINTERS];
413  if (fv->is_rgb) {
414  /* Create a temporaty frame */
415  tmp = av_frame_alloc();
416  if (!(tmp))
417  return AVERROR(ENOMEM);
418 
420  tmp, 0));
421  }
422 
423  /* With everything allocated, setup push data */
424  FFv1ShaderParams pd = {
425  .slice_data = out_data_buf->address,
426 
427  .img_size[0] = fv->s.frames->width,
428  .img_size[1] = fv->s.frames->height,
429 
430  .plane_state_size = plane_state_size,
431  .key_frame = f->key_frame,
432  .crcref = f->crcref,
433  .micro_version = f->micro_version,
434 
435  .sar[0] = pict->sample_aspect_ratio.num,
436  .sar[1] = pict->sample_aspect_ratio.den,
437  .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
438  !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
439 
440  /* 16-byte aligned so the gather can use wide loads */
441  .slice_size_max = (out_data_buf->size / f->slice_count) & ~(size_t)15,
442  .max_pixels_per_slice = fv->max_pixels_per_slice,
443  };
444 
445  for (int i = 0; i < f->quant_table_count; i++) {
446  pd.context_count[i] = f->context_count[i];
447  pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
448  f->quant_tables[i][4][127];
449  }
450 
451  /* For some reason the C FFv1 encoder/decoder treats these differently */
452  if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
453  avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
454  avctx->sw_pix_fmt == AV_PIX_FMT_GBRP14)
455  memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
456  else
457  ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
458 
459  /* Start recording */
460  ff_vk_exec_start(&fv->s, exec);
461  fd->idx = exec->idx;
462 
463  /* For float pixel formats we want the raw bit pattern, not a value
464  * already passed through fp16/fp32 conversion (which can flush
465  * denormals). Use a UINT view in that case. */
466  RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
467  f->remap_mode ? FF_VK_REP_UINT
468  : FF_VK_REP_NATIVE));
469 
470  ff_vk_exec_add_dep_buf(&fv->s, exec, &slice_data_ref, 1, has_inter);
471  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->out_data_ref, 1, 1);
472  ff_vk_exec_add_dep_buf(&fv->s, exec, &gathered_ref, 1, 0);
473  gathered_ref = NULL; /* Ownership passed */
474  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->compacted_data_ref, 1, 1);
475  if (f->remap_mode) {
476  ff_vk_exec_add_dep_buf(&fv->s, exec, &remap_data_ref, 1, 0);
477  remap_data_ref = NULL;
478  }
479 
480  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
481  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
482  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
483  if (fv->is_rgb)
484  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
485  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
486  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
487 
488  if (fv->optimize_rct || f->remap_mode) {
489  /* Prepare the frame for reading */
490  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
491  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
492  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
493  VK_ACCESS_SHADER_READ_BIT,
494  VK_IMAGE_LAYOUT_GENERAL,
495  VK_QUEUE_FAMILY_IGNORED);
496 
497  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
498  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
499  .pImageMemoryBarriers = img_bar,
500  .imageMemoryBarrierCount = nb_img_bar,
501  });
502  nb_img_bar = 0;
503  }
504 
505  /* Run RCT search if needed */
506  if (fv->optimize_rct) {
507  RET(run_rct_search(avctx, exec, src, src_views,
508  slice_data_buf, slice_data_size, &pd));
509 
510  /* Make sure the writes are visible to the setup shader */
511  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
512  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
513  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
514  0, slice_data_size*f->slice_count);
515  }
516 
517  if (f->remap_mode) {
518  if (fv->is_float32) {
519  RET(run_sort32(avctx, exec, src, src_views,
520  remap_data_buf, remap_data_size, &pd));
521  } else {
522  RET(run_remap(avctx, exec, src, src_views,
523  remap_data_buf, remap_data_size, &pd));
524  }
525 
526  /* Make sure the writes are visible to the setup shader */
527  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
528  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
529  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
530  0, remap_data_size*f->slice_count);
531  }
532 
533  if (fv->optimize_rct || f->remap_mode) {
534  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
535  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
536  .pBufferMemoryBarriers = buf_bar,
537  .bufferMemoryBarrierCount = nb_buf_bar,
538  });
539  nb_buf_bar = 0;
540  }
541 
542  /* Setup shader */
543  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
544  1, 0, 0,
545  slice_data_buf,
546  0, slice_data_size*f->slice_count,
547  VK_FORMAT_UNDEFINED);
548  if (f->remap_mode)
550  &fv->setup, 1, 1, 0,
551  remap_data_buf,
552  0, remap_data_size*f->slice_count,
553  VK_FORMAT_UNDEFINED);
554 
555  ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
556  ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
557  VK_SHADER_STAGE_COMPUTE_BIT,
558  0, sizeof(FFv1ShaderParams), &pd);
559 
560  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
561 
562  /* Clean up temporary image if needed */
563  if (fv->is_rgb) {
564  AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
565  vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
566  vkf->access[0] = VK_ACCESS_2_NONE;
567 
568  RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
569  tmp,
571 
572  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
573  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
574  VK_PIPELINE_STAGE_2_CLEAR_BIT,
575  VK_ACCESS_2_TRANSFER_WRITE_BIT,
576  VK_IMAGE_LAYOUT_GENERAL,
577  VK_QUEUE_FAMILY_IGNORED);
578  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
579  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
580  .pImageMemoryBarriers = img_bar,
581  .imageMemoryBarrierCount = nb_img_bar,
582  });
583  nb_img_bar = 0;
584 
585  vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
586  &((VkClearColorValue) { 0 }),
587  1, &((VkImageSubresourceRange) {
588  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
589  .levelCount = 1,
590  .layerCount = 1,
591  }));
592  }
593 
594  /* Run reset shader */
595  if (f->key_frame || fv->force_pcm) {
596  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
597  1, 0, 0,
598  slice_data_buf,
599  0, slice_data_size*f->slice_count,
600  VK_FORMAT_UNDEFINED);
601  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
602  1, 1, 0,
603  slice_data_buf,
604  f->slice_count*256,
605  VK_WHOLE_SIZE,
606  VK_FORMAT_UNDEFINED);
607 
608  ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
609  ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
610  VK_SHADER_STAGE_COMPUTE_BIT,
611  0, sizeof(FFv1ShaderParams), &pd);
612 
613  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
614  f->plane_count);
615  }
616 
617  /* Sync between reset and encode shaders */
618  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
619  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
620  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
621  0, slice_data_size*f->slice_count);
622 
623  /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
624  * back into the remap buffer; the encode shader reads it. */
625  if (f->remap_mode)
626  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
627  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
628  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
629  0, remap_data_size*f->slice_count);
630  if (f->key_frame || fv->force_pcm)
631  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
632  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
633  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
634  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
635  else
636  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
637  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
638  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
639  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
640 
641  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
642  fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
643  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
644  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
645  VK_ACCESS_SHADER_READ_BIT,
646  VK_IMAGE_LAYOUT_GENERAL,
647  VK_QUEUE_FAMILY_IGNORED);
648 
649  if (fv->is_rgb)
650  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
651  VK_PIPELINE_STAGE_2_CLEAR_BIT,
652  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
653  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
654  VK_IMAGE_LAYOUT_GENERAL,
655  VK_QUEUE_FAMILY_IGNORED);
656 
657  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
658  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
659  .pImageMemoryBarriers = img_bar,
660  .imageMemoryBarrierCount = nb_img_bar,
661  .pBufferMemoryBarriers = buf_bar,
662  .bufferMemoryBarrierCount = nb_buf_bar,
663  });
664  nb_img_bar = 0;
665  nb_buf_bar = 0;
666 
667  /* Main encode shader */
668  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
669  1, 0, 0,
670  slice_data_buf,
671  0, slice_data_size*f->slice_count,
672  VK_FORMAT_UNDEFINED);
674  &fv->enc, 1, 1, 0,
675  &fv->results_buf,
676  fd->idx*f->max_slice_count*sizeof(uint32_t),
677  f->slice_count*sizeof(uint32_t),
678  VK_FORMAT_UNDEFINED);
679  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
680  1, 2, 0,
681  slice_data_buf,
682  f->slice_count*256,
683  VK_WHOLE_SIZE,
684  VK_FORMAT_UNDEFINED);
685  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
686  src, src_views,
687  1, 3,
688  VK_IMAGE_LAYOUT_GENERAL,
689  VK_NULL_HANDLE);
690  if (fv->is_rgb)
691  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
692  tmp, tmp_views,
693  1, 4,
694  VK_IMAGE_LAYOUT_GENERAL,
695  VK_NULL_HANDLE);
696  if (f->remap_mode)
698  &fv->enc, 1, 5, 0,
699  remap_data_buf,
700  0, remap_data_size*f->slice_count,
701  VK_FORMAT_UNDEFINED);
702 
703  ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
704  ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
705  VK_SHADER_STAGE_COMPUTE_BIT,
706  0, sizeof(FFv1ShaderParams), &pd);
707  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
708 
709  /* Gather the per-slice slots into one contiguous buffer, in the same
710  * submission. */
711  FFVkBuffer *results_buf = &fv->results_buf;
712  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], out_data_buf,
713  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
714  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
715  0, VK_WHOLE_SIZE);
716  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], results_buf,
717  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
718  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
719  0, VK_WHOLE_SIZE);
720  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
721  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
722  .pBufferMemoryBarriers = buf_bar,
723  .bufferMemoryBarrierCount = nb_buf_bar,
724  });
725  nb_buf_bar = 0;
726 
727  SegGatherPushData gather_pd = {
728  .sparse = out_data_buf->address,
729  .compacted = gathered_buf->address,
730  .slot_size = (uint32_t)((out_data_buf->size / f->slice_count) & ~(size_t)15),
731  };
732  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->gather, 0, 0, 0,
733  &fv->results_buf,
734  fd->idx*f->max_slice_count*sizeof(uint32_t),
735  f->slice_count*sizeof(uint32_t),
736  VK_FORMAT_UNDEFINED);
737  ff_vk_exec_bind_shader(&fv->s, exec, &fv->gather);
738  ff_vk_shader_update_push_const(&fv->s, exec, &fv->gather,
739  VK_SHADER_STAGE_COMPUTE_BIT,
740  0, sizeof(gather_pd), &gather_pd);
741  vk->CmdDispatch(exec->buf, f->slice_count, 1, 1);
742 
743  /* Read the gathered bitstream back with the copy engine. The size is
744  * only known once the encode is done, so the whole buffer is copied;
745  * with the version-4 slot sizing this is close to the payload size. */
746  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], gathered_buf,
747  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
748  TRANSFER_BIT, TRANSFER_READ_BIT, NONE_KHR,
749  0, VK_WHOLE_SIZE);
750  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
751  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
752  .pBufferMemoryBarriers = buf_bar,
753  .bufferMemoryBarrierCount = nb_buf_bar,
754  });
755  nb_buf_bar = 0;
756 
757  vk->CmdCopyBuffer(exec->buf, gathered_buf->buf, compacted_buf->buf,
758  1, &(VkBufferCopy) { .size = maxsize });
759 
760  /* Submit */
761  err = ff_vk_exec_submit(&fv->s, exec);
762  if (err < 0)
763  return err;
764 
765  f->picture_number++;
766 
767  /* This, if needed, was referenced by the execution context
768  * as it was declared as a dependency. */
769  av_frame_free(&tmp);
770  return 0;
771 
772 fail:
773  av_frame_free(&tmp);
774  av_buffer_unref(&gathered_ref);
775  ff_vk_exec_discard_deps(&fv->s, exec);
776 
777  return err;
778 }
779 
780 /* Return the gathered-output buffer to its pool when the packet is freed. */
781 static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
782 {
783  AVBufferRef *buf_ref = opaque;
784  av_buffer_unref(&buf_ref);
785 }
786 
787 static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec,
788  AVPacket *pkt)
789 {
790  VulkanEncodeFFv1Context *fv = avctx->priv_data;
791  FFV1Context *f = &fv->ctx;
792  FFVulkanFunctions *vk = &fv->s.vkfn;
793  VulkanEncodeFFv1FrameData *fd = exec->opaque;
794 
795  FFVkBuffer *compacted_buf = (FFVkBuffer *)fd->compacted_data_ref->data;
796 
797  /* Make sure the encode + gather submission is done */
798  ff_vk_exec_wait(&fv->s, exec);
799 
800  /* Invalidate the per-slice sizes if needed */
801  uint32_t rb_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
802  if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
803  VkMappedMemoryRange invalidate_data = {
804  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
805  .memory = fv->results_buf.mem,
806  .offset = rb_off,
807  .size = f->slice_count*sizeof(uint32_t),
808  };
809  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
810  1, &invalidate_data);
811  }
812 
813  /* The gather packed the slices tight and in order; sum their lengths. */
814  pkt->size = 0;
815  uint8_t *rb = fv->results_buf.mapped_mem + rb_off;
816  for (int i = 0; i < f->slice_count; i++) {
817  uint32_t sl_len = AV_RN32(rb + i*4);
818  av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %u\n", i, sl_len);
819  pkt->size += sl_len;
820  }
821  av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
822 
823  /* Invalidate the gathered bitstream if needed */
824  if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
825  VkMappedMemoryRange invalidate_data = {
826  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
827  .memory = compacted_buf->mem,
828  .offset = 0,
829  .size = VK_WHOLE_SIZE,
830  };
831  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
832  1, &invalidate_data);
833  }
834 
835  /* Hand the gathered buffer to the packet with no copy: pkt->buf references
836  * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
837  pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
839  if (!pkt->buf) {
842  return AVERROR(ENOMEM);
843  }
844  fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
845  pkt->data = compacted_buf->mapped_mem;
846 
847  pkt->pts = fd->pts;
848  pkt->dts = fd->pts;
849  pkt->duration = fd->duration;
851 
852  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
853  pkt->opaque = fd->frame_opaque;
855  fd->frame_opaque_ref = NULL;
856  }
857 
859 
860  return 0;
861 }
862 
864  AVPacket *pkt)
865 {
866  int err;
867  VulkanEncodeFFv1Context *fv = avctx->priv_data;
869  FFVkExecContext *exec;
870  AVFrame *frame;
871 
872  while (1) {
873  /* Roll an execution context */
874  exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
875 
876  /* If it had a frame, immediately output it */
877  if (exec->had_submission) {
878  exec->had_submission = 0;
879  fv->in_flight--;
880  return get_packet(avctx, exec, pkt);
881  }
882 
883  /* Get next frame to encode */
884  frame = fv->frame;
885  err = ff_encode_get_frame(avctx, frame);
886  if (err < 0 && err != AVERROR_EOF) {
887  return err;
888  } else if (err == AVERROR_EOF) {
889  if (!fv->in_flight)
890  return err;
891  continue;
892  }
893 
894  /* Encode frame */
895  fd = exec->opaque;
896  fd->pts = frame->pts;
897  fd->duration = frame->duration;
898  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
899  fd->frame_opaque = frame->opaque;
900  fd->frame_opaque_ref = frame->opaque_ref;
901  frame->opaque_ref = NULL;
902  }
903 
904  err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
906  if (err < 0)
907  return err;
908 
909  fv->in_flight++;
910  if (fv->in_flight < fv->async_depth)
911  return AVERROR(EAGAIN);
912  }
913 
914  return 0;
915 }
916 
917 static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
918 {
919  int err;
920  VulkanEncodeFFv1Context *fv = avctx->priv_data;
921  FFV1Context *f = &fv->ctx;
922  AVHWFramesContext *frames_ctx;
923  AVVulkanFramesContext *vk_frames;
924 
926  if (!fv->intermediate_frames_ref)
927  return AVERROR(ENOMEM);
928 
929  frames_ctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data;
930  frames_ctx->format = AV_PIX_FMT_VULKAN;
931  frames_ctx->sw_format = sw_format;
932  frames_ctx->width = fv->s.frames->width;
933  frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
934 
935  vk_frames = frames_ctx->hwctx;
936  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
937  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
938  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
939  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
940 
942  if (err < 0) {
943  av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
944  av_get_pix_fmt_name(sw_format), av_err2str(err));
946  return err;
947  }
948 
949  return 0;
950 }
951 
952 static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
953 {
954  int err;
955  VulkanEncodeFFv1Context *fv = avctx->priv_data;
956  FFVulkanShader *shd = &fv->rct_search;
957 
958  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
959  (uint32_t []) { 32, 32, 1 }, 0);
960 
962  VK_SHADER_STAGE_COMPUTE_BIT);
963 
964  const FFVulkanDescriptorSetBinding desc_set_const[] = {
965  { /* rangecoder_buf */
966  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
967  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
968  },
969  };
970  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
971 
972  const FFVulkanDescriptorSetBinding desc_set[] = {
973  { /* slice_data_buf */
974  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
975  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
976  },
977  { /* src */
978  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
979  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
980  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
981  },
982  };
983  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
984 
985  RET(ff_vk_shader_link(&fv->s, shd,
988 
989  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
990 
991 fail:
992  return err;
993 }
994 
995 static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
996 {
997  int err;
998  VulkanEncodeFFv1Context *fv = avctx->priv_data;
999  FFVulkanShader *shd = &fv->sort32;
1000 
1001  uint32_t wg_x = FFMIN(fv->max_pixels_per_slice, 256);
1002  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1003  (uint32_t []) { wg_x, 1, 1 }, 0);
1004 
1006  VK_SHADER_STAGE_COMPUTE_BIT);
1007 
1008  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1009  { /* rangecoder_buf */
1010  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1011  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1012  },
1013  };
1014  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1015 
1016  const FFVulkanDescriptorSetBinding desc_set[] = {
1017  { /* slice_data_buf */
1018  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1019  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1020  },
1021  { /* src */
1022  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1023  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1024  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1025  },
1026  { /* units */
1027  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1028  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1029  },
1030  };
1031  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1032 
1033  RET(ff_vk_shader_link(&fv->s, shd,
1036 
1037  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1038 
1039 fail:
1040  return err;
1041 }
1042 
1043 static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1044 {
1045  int err;
1046  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1047  FFVulkanShader *shd = &fv->remap;
1048 
1049  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1050  (uint32_t []) { 32, 32, 1 }, 0);
1051 
1053  VK_SHADER_STAGE_COMPUTE_BIT);
1054 
1055  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1056  { /* rangecoder_buf */
1057  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1058  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1059  },
1060  };
1061  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1062 
1063  const FFVulkanDescriptorSetBinding desc_set[] = {
1064  { /* slice_data_buf */
1065  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1066  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1067  },
1068  { /* src */
1069  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1070  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1071  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1072  },
1073  { /* fltmap */
1074  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1075  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1076  },
1077  };
1078  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1079 
1080  RET(ff_vk_shader_link(&fv->s, shd,
1083 
1084  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1085 
1086 fail:
1087  return err;
1088 }
1089 
1090 static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1091 {
1092  int err;
1093  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1094  FFVulkanShader *shd = &fv->setup;
1095 
1096  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1097  (uint32_t []) { 1, 1, 1 }, 0);
1098 
1100  VK_SHADER_STAGE_COMPUTE_BIT);
1101 
1102  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1103  { /* rangecoder_buf */
1104  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1105  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1106  },
1107  };
1108  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1109 
1110  const FFVulkanDescriptorSetBinding desc_set[] = {
1111  { /* slice_data_buf */
1112  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1113  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1114  },
1115  { /* fltmap */
1116  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1117  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1118  },
1119  };
1120  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1121 
1122  RET(ff_vk_shader_link(&fv->s, shd,
1125 
1126  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1127 
1128 fail:
1129  return err;
1130 }
1131 
1132 static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1133 {
1134  int err;
1135  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1136  FFVulkanShader *shd = &fv->reset;
1137 
1138  int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1139 
1140  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1141  (uint32_t []) { wg_dim, 1, 1 }, 0);
1142 
1144  VK_SHADER_STAGE_COMPUTE_BIT);
1145 
1146  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1147  { /* rangecoder_buf */
1148  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1149  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1150  },
1151  };
1152  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1153 
1154  const FFVulkanDescriptorSetBinding desc_set[] = {
1155  { /* slice_data_buf */
1156  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1157  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1158  },
1159  { /* slice_state_buf */
1160  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1161  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1162  },
1163  };
1164  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1165 
1166  if (fv->ctx.ac == AC_GOLOMB_RICE)
1167  RET(ff_vk_shader_link(&fv->s, shd,
1170  else
1171  RET(ff_vk_shader_link(&fv->s, shd,
1174 
1175  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1176 
1177 fail:
1178  return err;
1179 }
1180 
1181 static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1182 {
1183  int err;
1184  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1185  FFV1Context *f = &fv->ctx;
1186  FFVulkanShader *shd = &fv->enc;
1187 
1188  uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1189  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1190  (uint32_t []) { wg_x, 1, 1 }, 0);
1191 
1193  VK_SHADER_STAGE_COMPUTE_BIT);
1194 
1195  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1196  { /* rangecoder_buf */
1197  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1198  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1199  },
1200  { /* quant_buf */
1201  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1202  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1203  },
1204  { /* crc_ieee_buf */
1205  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1206  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1207  },
1208  };
1209  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1);
1210 
1211  const FFVulkanDescriptorSetBinding desc_set[] = {
1212  { /* slice_data_buf */
1213  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1214  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1215  },
1216  { /* slice_results_buf */
1217  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1218  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1219  },
1220  { /* slice_state_buf */
1221  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1222  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1223  },
1224  { /* src */
1225  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1226  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1227  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1228  },
1229  { /* tmp */
1230  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1231  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1232  },
1233  { /* fltmap */
1234  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1235  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1236  },
1237  };
1238  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1239  4 + fv->is_rgb + !!f->remap_mode, 0);
1240 
1241  if (f->bayer) {
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 (f->remap_mode) {
1251  if (fv->ctx.ac == AC_GOLOMB_RICE)
1252  ff_vk_shader_link(&fv->s, shd,
1255  else
1256  ff_vk_shader_link(&fv->s, shd,
1259  } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1260  if (fv->is_rgb)
1261  ff_vk_shader_link(&fv->s, shd,
1264  else
1265  ff_vk_shader_link(&fv->s, shd,
1268  } else {
1269  if (fv->is_rgb)
1270  ff_vk_shader_link(&fv->s, shd,
1273  else
1274  ff_vk_shader_link(&fv->s, shd,
1276  ff_ffv1_enc_comp_spv_len, "main");
1277  }
1278 
1279  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1280 
1281 fail:
1282  return err;
1283 }
1284 
1286 {
1287  int err;
1288  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1289  FFVulkanShader *shd = &fv->gather;
1290 
1291  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
1292  (uint32_t []) { 256, 1, 1 }, 0);
1293 
1295  VK_SHADER_STAGE_COMPUTE_BIT);
1296 
1297  const FFVulkanDescriptorSetBinding desc_set[] = {
1298  { /* sizes_buf */
1299  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1300  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1301  },
1302  };
1303  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0);
1304 
1305  RET(ff_vk_shader_link(&fv->s, shd,
1307  ff_seg_gather_comp_spv_len, "main"));
1308 
1309  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1310 
1311 fail:
1312  return err;
1313 }
1314 
1316 {
1317  int err;
1318  size_t maxsize;
1319  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1320  FFV1Context *f = &fv->ctx;
1321 
1322  if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1323  return err;
1324 
1325  if (f->ac == 1)
1326  f->ac = AC_RANGE_CUSTOM_TAB;
1327 
1328  err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1329  if (err < 0)
1330  return err;
1331 
1332  /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1333  * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1334  f->version = f->bayer ? 4 : 3;
1335 
1336  err = ff_ffv1_encode_init(avctx);
1337  if (err < 0)
1338  return err;
1339 
1340  /* Rice coding did not support high bit depths */
1341  if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1342  if (f->ac == AC_GOLOMB_RICE) {
1343  av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1344  "forcing range coder\n");
1345  f->ac = AC_RANGE_CUSTOM_TAB;
1346  }
1347  }
1348 
1349  if (f->version < 4 && avctx->gop_size > 1) {
1350  av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1351  return AVERROR_INVALIDDATA;
1352  }
1353 
1354  if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1355  av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1356  return AVERROR_INVALIDDATA;
1357  }
1358 
1359  /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1360  if (f->version == 4)
1361  f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1362 
1363  f->num_h_slices = fv->num_h_slices;
1364  f->num_v_slices = fv->num_v_slices;
1365 
1366  if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1367  if (avctx->slices) {
1368  err = ff_ffv1_encode_determine_slices(avctx);
1369  if (err < 0)
1370  return err;
1371  } else {
1372  f->num_h_slices = 32;
1373  f->num_v_slices = 32;
1374  }
1375  } else if (f->num_h_slices && f->num_v_slices <= 0) {
1376  f->num_v_slices = MAX_SLICES / f->num_h_slices;
1377  } else if (f->num_v_slices && f->num_h_slices <= 0) {
1378  f->num_h_slices = MAX_SLICES / f->num_v_slices;
1379  }
1380 
1381  f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1382  f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1383 
1384  if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1385  av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1386  "by the standard is %i\n",
1387  f->num_h_slices * f->num_v_slices, MAX_SLICES);
1388  return AVERROR_PATCHWELCOME;
1389  }
1390 
1391  f->max_slice_count = f->num_h_slices * f->num_v_slices;
1392 
1393  if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1394  return err;
1395 
1396  if (f->version < 4) {
1397  if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1398  ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1399  av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1400  "dimensions is only supported in version 4 (-level 4)\n");
1401  return AVERROR_PATCHWELCOME;
1402  }
1403  }
1404 
1405  if (fv->force_pcm) {
1406  if (f->version < 4) {
1407  av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1408  return AVERROR_INVALIDDATA;
1409  } else if (f->ac == AC_GOLOMB_RICE) {
1410  av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1411  return AVERROR_INVALIDDATA;
1412  }
1413  }
1414 
1415  /* Init Vulkan */
1416  err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1417  if (err < 0)
1418  return err;
1419 
1420  fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1421  if (!fv->qf) {
1422  av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1423  return err;
1424  }
1425 
1426  maxsize = ffv1_vk_buffer_size(avctx);
1427  if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1428  av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1429  "than maximum device allocation (%"PRIu64"), clipping\n",
1430  maxsize, fv->s.props_11.maxMemoryAllocationSize);
1431  maxsize = fv->s.props_11.maxMemoryAllocationSize;
1432  }
1433 
1434  av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1435  2*maxsize / (1024*1024),
1436  (fv->async_depth * 2*maxsize) / (1024*1024),
1437  fv->async_depth);
1438 
1439  err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1440  fv->async_depth,
1441  0, 0, 0, NULL);
1442  if (err < 0)
1443  return err;
1444 
1445  /* Detect the special RGB coding mode */
1446  fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1447  !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1448 
1449  fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1450  avctx->sw_pix_fmt == AV_PIX_FMT_GBRAPF32);
1451 
1452  if (fv->is_float32) {
1453  /* Compute the worst-case slice geometry. With version >= 4 the slice
1454  * boundaries are computed via slice_coord() which rounds up, so any
1455  * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1456  * pixels. */
1457  uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1458  uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1459  /* Round up to next pow2 for bitonic sort */
1460  uint32_t n = 1;
1461  uint32_t pn = mw*mh;
1462  while (n < pn)
1463  n <<= 1;
1464  if (n < 2)
1465  n = 2;
1466  fv->max_pixels_per_slice = n;
1467  }
1468 
1469  /* Init rct search shader */
1470  fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1471  !fv->force_pcm && fv->optimize_rct && !f->bayer;
1472 
1473  /* Init shader specialization consts */
1474  SPEC_LIST_CREATE(sl, 19, 19*sizeof(uint32_t))
1475  SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1476  SPEC_LIST_ADD(sl, 1, 32, f->ec);
1477  ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1478  SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1479  SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1480  SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1481  SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1482 
1483  if (fv->optimize_rct) {
1484  err = init_rct_search_shader(avctx, sl);
1485  if (err < 0)
1486  return err;
1487  }
1488 
1489  if (f->remap_mode) {
1490  if (fv->is_float32)
1491  err = init_sort32_shader(avctx, sl);
1492  else
1493  err = init_remap_shader(avctx, sl);
1494  if (err < 0)
1495  return err;
1496  }
1497 
1498  /* Init setup shader */
1499  err = init_setup_shader(avctx, sl);
1500  if (err < 0)
1501  return err;
1502 
1503  /* Init reset shader */
1504  err = init_reset_shader(avctx, sl);
1505  if (err < 0)
1506  return err;
1507 
1508  if (fv->is_rgb)
1509  RET(init_indirect(avctx, fv->ctx.use32bit ?
1511 
1512  /* Encode shader */
1513  err = init_encode_shader(avctx, sl);
1514  if (err < 0)
1515  return err;
1516 
1517  /* Gather shader */
1518  err = init_gather_shader(avctx);
1519  if (err < 0)
1520  return err;
1521 
1522  /* Constant data */
1523  err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1524  if (err < 0)
1525  return err;
1526 
1527  /* Update setup global descriptors */
1529  &fv->setup, 0, 0, 0,
1530  &fv->consts_buf,
1531  256*sizeof(uint32_t), 512*sizeof(uint8_t),
1532  VK_FORMAT_UNDEFINED));
1533 
1534  /* Update encode global descriptors */
1536  &fv->enc, 0, 0, 0,
1537  &fv->consts_buf,
1538  256*sizeof(uint32_t), 512*sizeof(uint8_t),
1539  VK_FORMAT_UNDEFINED));
1541  &fv->enc, 0, 1, 0,
1542  &fv->consts_buf,
1543  256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1544  VK_WHOLE_SIZE,
1545  VK_FORMAT_UNDEFINED));
1547  &fv->enc, 0, 2, 0,
1548  &fv->consts_buf,
1549  0, 256*sizeof(uint32_t),
1550  VK_FORMAT_UNDEFINED));
1551 
1552  /* Temporary frame */
1553  fv->frame = av_frame_alloc();
1554  if (!fv->frame)
1555  return AVERROR(ENOMEM);
1556 
1557  /* Async data pool */
1558  fv->async_depth = fv->exec_pool.pool_size;
1559  fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1560  if (!fv->exec_ctx_info)
1561  return AVERROR(ENOMEM);
1562  for (int i = 0; i < fv->async_depth; i++)
1563  fv->exec_pool.contexts[i].opaque = &fv->exec_ctx_info[i];
1564 
1565  /* Buffers */
1566  RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1567  fv->async_depth*f->max_slice_count*sizeof(uint32_t),
1568  NULL, NULL,
1569  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1570  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1571  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1572  RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1573 
1574 fail:
1575  return err;
1576 }
1577 
1579 {
1580  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1581 
1582  ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1583 
1584  ff_vk_shader_free(&fv->s, &fv->enc);
1585  ff_vk_shader_free(&fv->s, &fv->gather);
1586  ff_vk_shader_free(&fv->s, &fv->reset);
1587  ff_vk_shader_free(&fv->s, &fv->setup);
1588  ff_vk_shader_free(&fv->s, &fv->remap);
1589  ff_vk_shader_free(&fv->s, &fv->sort32);
1590  ff_vk_shader_free(&fv->s, &fv->rct_search);
1591 
1592  if (fv->exec_ctx_info) {
1593  for (int i = 0; i < fv->async_depth; i++) {
1598  }
1599  }
1600  av_free(fv->exec_ctx_info);
1601 
1603 
1607 
1611 
1612  ff_vk_free_buf(&fv->s, &fv->results_buf);
1613 
1614  ff_vk_free_buf(&fv->s, &fv->consts_buf);
1615 
1616  av_frame_free(&fv->frame);
1617  ff_vk_uninit(&fv->s);
1618 
1619  return 0;
1620 }
1621 
1622 #define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1623 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1625  { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1626  { .i64 = -1 }, -1, 2, VE },
1627  { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1628  { .i64 = 0 }, 0, 1, VE },
1629  { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1630  { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1631  { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1632  { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1633  { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1634  { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1635  { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1636  { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1637  { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1638  { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1639  { "default", NULL, 0, AV_OPT_TYPE_CONST,
1640  { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1641  { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1642  { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1643  { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1644  { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1645 
1646  { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1647  { .i64 = -1 }, -1, MAX_SLICES, VE },
1648  { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1649  { .i64 = -1 }, -1, MAX_SLICES, VE },
1650 
1651  { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1652  { .i64 = 0 }, 0, 1, VE },
1653 
1654  { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1655  { .i64 = 1 }, 0, 1, VE },
1656 
1657  { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1658  { .i64 = 1 }, 1, INT_MAX, VE },
1659 
1660  { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1661  { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1662  { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1663  { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1664  { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1665  { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1666  { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1667  { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1668  { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1669  { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1670 
1671  { NULL }
1672 };
1673 
1675  { "g", "1" },
1676  { NULL },
1677 };
1678 
1680  .class_name = "ffv1_vulkan",
1681  .item_name = av_default_item_name,
1682  .option = vulkan_encode_ffv1_options,
1683  .version = LIBAVUTIL_VERSION_INT,
1684 };
1685 
1687  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1688  NULL,
1689 };
1690 
1692  .p.name = "ffv1_vulkan",
1693  CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1694  .p.type = AVMEDIA_TYPE_VIDEO,
1695  .p.id = AV_CODEC_ID_FFV1,
1696  .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1699  .close = &vulkan_encode_ffv1_close,
1700  .p.priv_class = &vulkan_encode_ffv1_class,
1701  .p.capabilities = AV_CODEC_CAP_DELAY |
1707  .defaults = vulkan_encode_ffv1_defaults,
1709  .hw_configs = vulkan_encode_ffv1_hw_configs,
1710  .p.wrapper_name = "vulkan",
1711 };
ffv1_vk_packet_free
static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
Definition: ffv1enc_vulkan.c:781
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:401
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:1050
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
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:282
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:2680
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:88
FFVulkanContext::device_ref
AVBufferRef * device_ref
Definition: vulkan.h:310
FFVkExecPool::contexts
FFVkExecContext * contexts
Definition: vulkan.h:254
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
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
VulkanEncodeFFv1FrameData::compacted_data_ref
AVBufferRef * compacted_data_ref
Definition: ffv1enc_vulkan.c:45
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:566
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:630
ff_ffv1_write_extradata
av_cold int ff_ffv1_write_extradata(AVCodecContext *avctx)
Definition: ffv1enc.c:447
FFCodec
Definition: codec_internal.h:127
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: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
FF_VK_REP_NATIVE
@ FF_VK_REP_NATIVE
Definition: vulkan.h:412
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2704
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:52
init_remap_shader
static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1043
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:2657
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:800
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:92
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:3496
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:1679
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:560
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:558
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
init_gather_shader
static int init_gather_shader(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1285
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:2093
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
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:148
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
VulkanEncodeFFv1Context::keyframe_slice_data_ref
AVBufferRef * keyframe_slice_data_ref
Definition: ffv1enc_vulkan.c:85
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:1691
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:80
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:1686
get_packet
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:787
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:573
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
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:1592
QTABLE_GT8BIT
@ QTABLE_GT8BIT
Definition: ffv1enc.h:31
FFVulkanContext::host_cached_flag
VkMemoryPropertyFlagBits host_cached_flag
Definition: vulkan.h:308
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:863
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
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
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
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:299
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:349
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
if
if(ret)
Definition: filter_design.txt:179
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
VulkanEncodeFFv1Context::frame
AVFrame * frame
Definition: ffv1enc_vulkan.c:59
fail
#define fail
Definition: test.h:478
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:529
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:1181
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:384
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:242
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:360
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
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
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:42
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:100
FFVulkanContext
Definition: vulkan.h:275
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
VulkanEncodeFFv1Context::slice_data_pool
AVBufferPool * slice_data_pool
Definition: ffv1enc_vulkan.c:84
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
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:2647
AVPacket::size
int size
Definition: packet.h:604
FFVulkanDescriptorSetBinding
Definition: vulkan.h:78
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:578
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:917
FFVulkanShader
Definition: vulkan.h:191
VulkanEncodeFFv1Context::optimize_rct
int optimize_rct
Definition: ffv1enc_vulkan.c:105
AVCodecHWConfigInternal
Definition: hwconfig.h:25
QTABLE_DEFAULT
@ QTABLE_DEFAULT
Definition: ffv1enc.h:29
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:94
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
VulkanEncodeFFv1FrameData::out_data_ref
AVBufferRef * out_data_ref
Definition: ffv1enc_vulkan.c:44
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
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
VE
#define VE
Definition: ffv1enc_vulkan.c:1623
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:98
ff_source_ffv1_enc_comp
const char * ff_source_ffv1_enc_comp
VulkanEncodeFFv1Context::remap_data_pool
AVBufferPool * remap_data_pool
Definition: ffv1enc_vulkan.c:88
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:580
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:418
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:559
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:93
SegGatherPushData
Definition: ffv1enc_vulkan.c:114
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:176
vulkan_encode_ffv1_close
static av_cold int vulkan_encode_ffv1_close(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1578
FFVulkanContext::props
VkPhysicalDeviceProperties2 props
Definition: vulkan.h:281
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition: vulkan.c:1264
AVCodecContext::height
int height
Definition: avcodec.h:604
init_setup_shader
static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1090
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
VulkanEncodeFFv1Context::gathered_data_pool
AVBufferPool * gathered_data_pool
Definition: ffv1enc_vulkan.c:94
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:2439
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:2010
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:279
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: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
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:286
vulkan_encode_ffv1_options
static const AVOption vulkan_encode_ffv1_options[]
Definition: ffv1enc_vulkan.c:1624
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
VulkanEncodeFFv1Context::compacted_data_pool
AVBufferPool * compacted_data_pool
Definition: ffv1enc_vulkan.c:97
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:1132
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:579
VulkanEncodeFFv1Context::async_depth
int async_depth
Definition: ffv1enc_vulkan.c:67
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
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:1674
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
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_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:612
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::max_pixels_per_slice
uint32_t max_pixels_per_slice
Definition: ffv1enc_vulkan.c:109
FFVkBuffer
Definition: vulkan.h:91
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:1315
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:925
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:316
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:1622
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:995
FFVulkanFunctions
Definition: vulkan_functions.h:275
FFVkExecPool::pool_size
int pool_size
Definition: vulkan.h:259
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
FFVkExecContext::idx
uint32_t idx
Definition: vulkan.h:112
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:3376
init_rct_search_shader
static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:952
VulkanEncodeFFv1Context::out_data_pool
AVBufferPool * out_data_pool
Definition: ffv1enc_vulkan.c:91
ff_source_rangecoder_comp
const char * ff_source_rangecoder_comp