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  size_t max_heap_size;
69 
77 
78  /* Constant read-only buffers */
80 
81  /* Results buffer */
83 
84  /* Slice data buffer pool */
87 
88  /* Remap data pool */
90 
91  /* Output data buffer */
93 
94  /* Gathered (contiguous) output buffer pool */
96 
97  /* Intermediate frame pool */
99 
104 
105  int is_rgb;
108  int ppi;
109  int chunks;
111 
112 typedef struct SegGatherPushData {
113  VkDeviceAddress sparse;
114  VkDeviceAddress compacted;
115  uint32_t slot_size;
117 
118 extern const char *ff_source_common_comp;
119 extern const char *ff_source_rangecoder_comp;
120 extern const char *ff_source_ffv1_vlc_comp;
121 extern const char *ff_source_ffv1_common_comp;
122 extern const char *ff_source_ffv1_enc_comp;
123 
124 extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
125 extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
126 
127 extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
128 extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
129 
130 extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[];
131 extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len;
132 
133 extern const unsigned char ff_ffv1_enc_comp_spv_data[];
134 extern const unsigned int ff_ffv1_enc_comp_spv_len;
135 
136 extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[];
137 extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len;
138 
139 extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[];
140 extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len;
141 
142 extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[];
143 extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len;
144 
145 extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[];
146 extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len;
147 
148 extern const unsigned char ff_ffv1_enc_remap_comp_spv_data[];
149 extern const unsigned int ff_ffv1_enc_remap_comp_spv_len;
150 
151 extern const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[];
152 extern const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len;
153 
154 extern const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[];
155 extern const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len;
156 
157 extern const unsigned char ff_ffv1_enc_sort32_comp_spv_data[];
158 extern const unsigned int ff_ffv1_enc_sort32_comp_spv_len;
159 
160 extern const unsigned char ff_ffv1_enc_bayer_comp_spv_data[];
161 extern const unsigned int ff_ffv1_enc_bayer_comp_spv_len;
162 
163 extern const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[];
164 extern const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len;
165 
166 extern const unsigned char ff_seg_gather_comp_spv_data[];
167 extern const unsigned int ff_seg_gather_comp_spv_len;
168 
169 /* Size output slots with the v4 worst case; v3's ~(2*bits+5) bytes/sample runs
170  * to gigabytes on large frames. The bitstream version is unaffected. */
171 static size_t ffv1_vk_buffer_size(AVCodecContext *avctx)
172 {
173  VulkanEncodeFFv1Context *fv = avctx->priv_data;
174  FFV1Context *f = &fv->ctx;
175  int version = f->version;
176  size_t size;
177 
178  f->version = 4;
180  f->version = version;
181 
182  return size;
183 }
184 
186  AVFrame *enc_in, VkImageView *enc_in_views,
187  FFVkBuffer *slice_data_buf, uint32_t slice_data_size,
188  FFv1ShaderParams *pd)
189 {
190  VulkanEncodeFFv1Context *fv = avctx->priv_data;
191  FFV1Context *f = &fv->ctx;
192  FFVulkanFunctions *vk = &fv->s.vkfn;
193 
194  /* Update descriptors */
196  1, 0, 0,
197  slice_data_buf,
198  0, slice_data_size*f->slice_count,
199  VK_FORMAT_UNDEFINED);
200  ff_vk_shader_update_img_array(&fv->s, exec, &fv->rct_search,
201  enc_in, enc_in_views,
202  1, 1,
203  VK_IMAGE_LAYOUT_GENERAL,
204  VK_NULL_HANDLE);
205 
206  ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct_search);
208  VK_SHADER_STAGE_COMPUTE_BIT,
209  0, sizeof(FFv1ShaderParams), pd);
210 
211  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
212 
213  return 0;
214 }
215 
216 static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec,
217  AVFrame *enc_in, VkImageView *enc_in_views,
218  FFVkBuffer *fltmap_buf, uint32_t fltmap_size,
219  FFv1ShaderParams *pd)
220 {
221  VulkanEncodeFFv1Context *fv = avctx->priv_data;
222  FFV1Context *f = &fv->ctx;
223  FFVulkanFunctions *vk = &fv->s.vkfn;
224 
225  /* Update descriptors */
226  ff_vk_shader_update_img_array(&fv->s, exec, &fv->remap,
227  enc_in, enc_in_views,
228  1, 1,
229  VK_IMAGE_LAYOUT_GENERAL,
230  VK_NULL_HANDLE);
231  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->remap,
232  1, 2, 0,
233  fltmap_buf,
234  0, fltmap_size*f->slice_count,
235  VK_FORMAT_UNDEFINED);
236 
237  ff_vk_exec_bind_shader(&fv->s, exec, &fv->remap);
238  ff_vk_shader_update_push_const(&fv->s, exec, &fv->remap,
239  VK_SHADER_STAGE_COMPUTE_BIT,
240  0, sizeof(FFv1ShaderParams), pd);
241 
242  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
243 
244  return 0;
245 }
246 
247 static int run_sort32(AVCodecContext *avctx, FFVkExecContext *exec,
248  AVFrame *enc_in, VkImageView *enc_in_views,
249  FFVkBuffer *units_buf, uint32_t units_size,
250  FFv1ShaderParams *pd)
251 {
252  VulkanEncodeFFv1Context *fv = avctx->priv_data;
253  FFV1Context *f = &fv->ctx;
254  FFVulkanFunctions *vk = &fv->s.vkfn;
255 
256  /* Update descriptors */
257  ff_vk_shader_update_img_array(&fv->s, exec, &fv->sort32,
258  enc_in, enc_in_views,
259  1, 1,
260  VK_IMAGE_LAYOUT_GENERAL,
261  VK_NULL_HANDLE);
262  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->sort32,
263  1, 2, 0,
264  units_buf,
265  0, units_size*f->slice_count,
266  VK_FORMAT_UNDEFINED);
267 
268  ff_vk_exec_bind_shader(&fv->s, exec, &fv->sort32);
269  ff_vk_shader_update_push_const(&fv->s, exec, &fv->sort32,
270  VK_SHADER_STAGE_COMPUTE_BIT,
271  0, sizeof(FFv1ShaderParams), pd);
272 
273  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
274 
275  return 0;
276 }
277 
279  FFVkExecContext *exec,
280  const AVFrame *pict)
281 {
282  int err;
283  VulkanEncodeFFv1Context *fv = avctx->priv_data;
284  FFV1Context *f = &fv->ctx;
285  FFVulkanFunctions *vk = &fv->s.vkfn;
286 
287  VulkanEncodeFFv1FrameData *fd = exec->opaque;
288 
289  /* Slice data */
290  AVBufferRef *slice_data_ref;
291  FFVkBuffer *slice_data_buf;
292  uint32_t plane_state_size;
293  uint32_t slice_state_size;
294  uint32_t slice_data_size;
295 
296  /* Remap data */
297  AVBufferRef *remap_data_ref = NULL;
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 *compacted_buf;
305 
306  int has_inter = avctx->gop_size > 1;
307  uint32_t context_count = f->context_count[f->context_model];
308 
309  VkImageMemoryBarrier2 img_bar[37];
310  int nb_img_bar = 0;
311  VkBufferMemoryBarrier2 buf_bar[8];
312  int nb_buf_bar = 0;
313 
314  /* Frame state */
315  f->cur_enc_frame = pict;
316  if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
318  f->key_frame = fd->key_frame = 1;
319  f->gob_count++;
320  } else {
321  f->key_frame = fd->key_frame = 0;
322  }
323 
324  f->slice_count = f->max_slice_count;
325 
326  /* Allocate slice buffer data */
327  if (f->ac == AC_GOLOMB_RICE)
328  plane_state_size = 8;
329  else
330  plane_state_size = CONTEXT_SIZE;
331 
332  plane_state_size *= context_count;
333  slice_state_size = plane_state_size*f->plane_count;
334 
335  slice_data_size = 256; /* Overestimation for the SliceContext struct */
336  slice_state_size += slice_data_size;
337  slice_state_size = FFALIGN(slice_state_size, 8);
338 
339  /* Allocate slice data buffer */
340  slice_data_ref = fv->keyframe_slice_data_ref;
341  if (!slice_data_ref) {
343  &slice_data_ref,
344  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
345  NULL, slice_state_size*f->slice_count,
346  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
347 
348  /* Only save it if we're going to use it again */
349  if (has_inter)
350  fv->keyframe_slice_data_ref = slice_data_ref;
351  }
352  slice_data_buf = (FFVkBuffer *)slice_data_ref->data;
353 
354  if (f->remap_mode) {
355  if (fv->is_float32) {
356  /* Per (slice, plane): [units : max_pixels*2 uints] + [bitmap : max_pixels uints]. */
357  remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
358  } else {
360  remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
361  }
362 
364  &remap_data_ref,
365  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
366  NULL, remap_data_size*f->slice_count,
367  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
368  remap_data_buf = (FFVkBuffer *)remap_data_ref->data;
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 output: written by encode, read by gather, never by the
376  * CPU, so device-local unless it won't fit in VRAM. */
377  VkMemoryPropertyFlagBits out_buf_flags;
378  if (maxsize < fv->max_heap_size)
379  out_buf_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
380  else
381  out_buf_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
382  fv->s.host_cached_flag;
383 
385  &fd->out_data_ref,
386  VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
387  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
388  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
389  NULL, maxsize, out_buf_flags));
390  out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
391 
392  /* Contiguous gathered output, read back by the CPU. */
394  &fd->compacted_data_ref,
395  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
396  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
397  NULL, maxsize,
398  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
399  fv->s.host_cached_flag));
400  compacted_buf = (FFVkBuffer *)fd->compacted_data_ref->data;
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 
465  ff_vk_exec_add_dep_buf(&fv->s, exec, &slice_data_ref, 1, has_inter);
466  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->out_data_ref, 1, 1);
467  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->compacted_data_ref, 1, 1);
468  if (f->remap_mode) {
469  ff_vk_exec_add_dep_buf(&fv->s, exec, &remap_data_ref, 1, 0);
470  remap_data_ref = NULL;
471  }
472 
473  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
474  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
475  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
476  if (fv->is_rgb)
477  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
478  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
479  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
480 
481  if (fv->optimize_rct || f->remap_mode) {
482  /* Prepare the frame for reading */
483  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
484  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
485  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
486  VK_ACCESS_SHADER_READ_BIT,
487  VK_IMAGE_LAYOUT_GENERAL,
488  VK_QUEUE_FAMILY_IGNORED);
489 
490  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
491  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
492  .pImageMemoryBarriers = img_bar,
493  .imageMemoryBarrierCount = nb_img_bar,
494  });
495  nb_img_bar = 0;
496  }
497 
498  /* Run RCT search if needed */
499  if (fv->optimize_rct) {
500  RET(run_rct_search(avctx, exec, src, src_views,
501  slice_data_buf, slice_data_size, &pd));
502 
503  /* Make sure the writes are visible to the setup shader */
504  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
505  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
506  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
507  0, slice_data_size*f->slice_count);
508  }
509 
510  if (f->remap_mode) {
511  if (fv->is_float32) {
512  RET(run_sort32(avctx, exec, src, src_views,
513  remap_data_buf, remap_data_size, &pd));
514  } else {
515  RET(run_remap(avctx, exec, src, src_views,
516  remap_data_buf, remap_data_size, &pd));
517  }
518 
519  /* Make sure the writes are visible to the setup shader */
520  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
521  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
522  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
523  0, remap_data_size*f->slice_count);
524  }
525 
526  if (fv->optimize_rct || f->remap_mode) {
527  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
528  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
529  .pBufferMemoryBarriers = buf_bar,
530  .bufferMemoryBarrierCount = nb_buf_bar,
531  });
532  nb_buf_bar = 0;
533  }
534 
535  /* Setup shader */
536  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
537  1, 0, 0,
538  slice_data_buf,
539  0, slice_data_size*f->slice_count,
540  VK_FORMAT_UNDEFINED);
541  if (f->remap_mode)
543  &fv->setup, 1, 1, 0,
544  remap_data_buf,
545  0, remap_data_size*f->slice_count,
546  VK_FORMAT_UNDEFINED);
547 
548  ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
549  ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
550  VK_SHADER_STAGE_COMPUTE_BIT,
551  0, sizeof(FFv1ShaderParams), &pd);
552 
553  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
554 
555  /* Clean up temporary image if needed */
556  if (fv->is_rgb) {
557  AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
558  vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
559  vkf->access[0] = VK_ACCESS_2_NONE;
560 
561  RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
562  tmp,
564 
565  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
566  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
567  VK_PIPELINE_STAGE_2_CLEAR_BIT,
568  VK_ACCESS_2_TRANSFER_WRITE_BIT,
569  VK_IMAGE_LAYOUT_GENERAL,
570  VK_QUEUE_FAMILY_IGNORED);
571  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
572  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
573  .pImageMemoryBarriers = img_bar,
574  .imageMemoryBarrierCount = nb_img_bar,
575  });
576  nb_img_bar = 0;
577 
578  vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
579  &((VkClearColorValue) { 0 }),
580  1, &((VkImageSubresourceRange) {
581  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
582  .levelCount = 1,
583  .layerCount = 1,
584  }));
585  }
586 
587  /* Run reset shader */
588  if (f->key_frame || fv->force_pcm) {
589  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
590  1, 0, 0,
591  slice_data_buf,
592  0, slice_data_size*f->slice_count,
593  VK_FORMAT_UNDEFINED);
594  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
595  1, 1, 0,
596  slice_data_buf,
597  f->slice_count*256,
598  VK_WHOLE_SIZE,
599  VK_FORMAT_UNDEFINED);
600 
601  ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
602  ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
603  VK_SHADER_STAGE_COMPUTE_BIT,
604  0, sizeof(FFv1ShaderParams), &pd);
605 
606  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
607  f->plane_count);
608  }
609 
610  /* Sync between reset and encode shaders */
611  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
612  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
613  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
614  0, slice_data_size*f->slice_count);
615 
616  /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
617  * back into the remap buffer; the encode shader reads it. */
618  if (f->remap_mode)
619  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
620  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
621  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
622  0, remap_data_size*f->slice_count);
623  if (f->key_frame || fv->force_pcm)
624  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
625  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
626  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
627  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
628  else
629  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
630  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
631  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
632  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
633 
634  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
635  fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
636  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
637  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
638  VK_ACCESS_SHADER_READ_BIT,
639  VK_IMAGE_LAYOUT_GENERAL,
640  VK_QUEUE_FAMILY_IGNORED);
641 
642  if (fv->is_rgb)
643  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
644  VK_PIPELINE_STAGE_2_CLEAR_BIT,
645  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
646  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
647  VK_IMAGE_LAYOUT_GENERAL,
648  VK_QUEUE_FAMILY_IGNORED);
649 
650  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
651  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
652  .pImageMemoryBarriers = img_bar,
653  .imageMemoryBarrierCount = nb_img_bar,
654  .pBufferMemoryBarriers = buf_bar,
655  .bufferMemoryBarrierCount = nb_buf_bar,
656  });
657  nb_img_bar = 0;
658  nb_buf_bar = 0;
659 
660  /* Main encode shader */
661  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
662  1, 0, 0,
663  slice_data_buf,
664  0, slice_data_size*f->slice_count,
665  VK_FORMAT_UNDEFINED);
667  &fv->enc, 1, 1, 0,
668  &fv->results_buf,
669  fd->idx*f->max_slice_count*sizeof(uint32_t),
670  f->slice_count*sizeof(uint32_t),
671  VK_FORMAT_UNDEFINED);
672  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
673  1, 2, 0,
674  slice_data_buf,
675  f->slice_count*256,
676  VK_WHOLE_SIZE,
677  VK_FORMAT_UNDEFINED);
678  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
679  src, src_views,
680  1, 3,
681  VK_IMAGE_LAYOUT_GENERAL,
682  VK_NULL_HANDLE);
683  if (fv->is_rgb)
684  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
685  tmp, tmp_views,
686  1, 4,
687  VK_IMAGE_LAYOUT_GENERAL,
688  VK_NULL_HANDLE);
689  if (f->remap_mode)
691  &fv->enc, 1, 5, 0,
692  remap_data_buf,
693  0, remap_data_size*f->slice_count,
694  VK_FORMAT_UNDEFINED);
695 
696  ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
697  ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
698  VK_SHADER_STAGE_COMPUTE_BIT,
699  0, sizeof(FFv1ShaderParams), &pd);
700  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
701 
702  /* Gather the per-slice slots into one contiguous host-visible buffer,
703  * in the same submission (no separate transfer pass). */
704  FFVkBuffer *results_buf = &fv->results_buf;
705  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], out_data_buf,
706  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
707  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
708  0, VK_WHOLE_SIZE);
709  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], results_buf,
710  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
711  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
712  0, VK_WHOLE_SIZE);
713  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
714  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
715  .pBufferMemoryBarriers = buf_bar,
716  .bufferMemoryBarrierCount = nb_buf_bar,
717  });
718  nb_buf_bar = 0;
719 
720  SegGatherPushData gather_pd = {
721  .sparse = out_data_buf->address,
722  .compacted = compacted_buf->address,
723  .slot_size = (uint32_t)((out_data_buf->size / f->slice_count) & ~(size_t)15),
724  };
725  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->gather, 0, 0, 0,
726  &fv->results_buf,
727  fd->idx*f->max_slice_count*sizeof(uint32_t),
728  f->slice_count*sizeof(uint32_t),
729  VK_FORMAT_UNDEFINED);
730  ff_vk_exec_bind_shader(&fv->s, exec, &fv->gather);
731  ff_vk_shader_update_push_const(&fv->s, exec, &fv->gather,
732  VK_SHADER_STAGE_COMPUTE_BIT,
733  0, sizeof(gather_pd), &gather_pd);
734  vk->CmdDispatch(exec->buf, f->slice_count, 1, 1);
735 
736  /* Submit */
737  err = ff_vk_exec_submit(&fv->s, exec);
738  if (err < 0)
739  return err;
740 
741  f->picture_number++;
742 
743  /* This, if needed, was referenced by the execution context
744  * as it was declared as a dependency. */
745  av_frame_free(&tmp);
746  return 0;
747 
748 fail:
749  av_frame_free(&tmp);
750  ff_vk_exec_discard_deps(&fv->s, exec);
751 
752  return err;
753 }
754 
755 /* Return the gathered-output buffer to its pool when the packet is freed. */
756 static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
757 {
758  AVBufferRef *buf_ref = opaque;
759  av_buffer_unref(&buf_ref);
760 }
761 
762 static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec,
763  AVPacket *pkt)
764 {
765  VulkanEncodeFFv1Context *fv = avctx->priv_data;
766  FFV1Context *f = &fv->ctx;
767  FFVulkanFunctions *vk = &fv->s.vkfn;
768  VulkanEncodeFFv1FrameData *fd = exec->opaque;
769 
770  FFVkBuffer *compacted_buf = (FFVkBuffer *)fd->compacted_data_ref->data;
771 
772  /* Make sure the encode + gather submission is done */
773  ff_vk_exec_wait(&fv->s, exec);
774 
775  /* Invalidate the per-slice sizes if needed */
776  uint32_t rb_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
777  if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
778  VkMappedMemoryRange invalidate_data = {
779  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
780  .memory = fv->results_buf.mem,
781  .offset = rb_off,
782  .size = f->slice_count*sizeof(uint32_t),
783  };
784  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
785  1, &invalidate_data);
786  }
787 
788  /* The gather packed the slices tight and in order; sum their lengths. */
789  pkt->size = 0;
790  uint8_t *rb = fv->results_buf.mapped_mem + rb_off;
791  for (int i = 0; i < f->slice_count; i++) {
792  uint32_t sl_len = AV_RN32(rb + i*4);
793  av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %u\n", i, sl_len);
794  pkt->size += sl_len;
795  }
796  av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
797 
798  /* Invalidate the gathered bitstream if needed */
799  if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
800  VkMappedMemoryRange invalidate_data = {
801  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
802  .memory = compacted_buf->mem,
803  .offset = 0,
804  .size = VK_WHOLE_SIZE,
805  };
806  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
807  1, &invalidate_data);
808  }
809 
810  /* Hand the gathered buffer to the packet with no copy: pkt->buf references
811  * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
812  pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
814  if (!pkt->buf) {
817  return AVERROR(ENOMEM);
818  }
819  fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
820  pkt->data = compacted_buf->mapped_mem;
821 
822  pkt->pts = fd->pts;
823  pkt->dts = fd->pts;
824  pkt->duration = fd->duration;
826 
827  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
828  pkt->opaque = fd->frame_opaque;
830  fd->frame_opaque_ref = NULL;
831  }
832 
834 
835  return 0;
836 }
837 
839  AVPacket *pkt)
840 {
841  int err;
842  VulkanEncodeFFv1Context *fv = avctx->priv_data;
844  FFVkExecContext *exec;
845  AVFrame *frame;
846 
847  while (1) {
848  /* Roll an execution context */
849  exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
850 
851  /* If it had a frame, immediately output it */
852  if (exec->had_submission) {
853  exec->had_submission = 0;
854  fv->in_flight--;
855  return get_packet(avctx, exec, pkt);
856  }
857 
858  /* Get next frame to encode */
859  frame = fv->frame;
860  err = ff_encode_get_frame(avctx, frame);
861  if (err < 0 && err != AVERROR_EOF) {
862  return err;
863  } else if (err == AVERROR_EOF) {
864  if (!fv->in_flight)
865  return err;
866  continue;
867  }
868 
869  /* Encode frame */
870  fd = exec->opaque;
871  fd->pts = frame->pts;
872  fd->duration = frame->duration;
873  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
874  fd->frame_opaque = frame->opaque;
875  fd->frame_opaque_ref = frame->opaque_ref;
876  frame->opaque_ref = NULL;
877  }
878 
879  err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
881  if (err < 0)
882  return err;
883 
884  fv->in_flight++;
885  if (fv->in_flight < fv->async_depth)
886  return AVERROR(EAGAIN);
887  }
888 
889  return 0;
890 }
891 
892 static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
893 {
894  int err;
895  VulkanEncodeFFv1Context *fv = avctx->priv_data;
896  FFV1Context *f = &fv->ctx;
897  AVHWFramesContext *frames_ctx;
898  AVVulkanFramesContext *vk_frames;
899 
901  if (!fv->intermediate_frames_ref)
902  return AVERROR(ENOMEM);
903 
904  frames_ctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data;
905  frames_ctx->format = AV_PIX_FMT_VULKAN;
906  frames_ctx->sw_format = sw_format;
907  frames_ctx->width = fv->s.frames->width;
908  frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
909 
910  vk_frames = frames_ctx->hwctx;
911  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
912  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
913  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
914  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
915 
917  if (err < 0) {
918  av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
919  av_get_pix_fmt_name(sw_format), av_err2str(err));
921  return err;
922  }
923 
924  return 0;
925 }
926 
927 static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
928 {
929  int err;
930  VulkanEncodeFFv1Context *fv = avctx->priv_data;
931  FFVulkanShader *shd = &fv->rct_search;
932 
933  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
934  (uint32_t []) { 32, 32, 1 }, 0);
935 
937  VK_SHADER_STAGE_COMPUTE_BIT);
938 
939  const FFVulkanDescriptorSetBinding desc_set_const[] = {
940  { /* rangecoder_buf */
941  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
942  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
943  },
944  };
945  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
946 
947  const FFVulkanDescriptorSetBinding desc_set[] = {
948  { /* slice_data_buf */
949  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
950  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
951  },
952  { /* src */
953  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
954  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
955  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
956  },
957  };
958  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0);
959 
960  RET(ff_vk_shader_link(&fv->s, shd,
963 
964  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
965 
966 fail:
967  return err;
968 }
969 
970 static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
971 {
972  int err;
973  VulkanEncodeFFv1Context *fv = avctx->priv_data;
974  FFVulkanShader *shd = &fv->sort32;
975 
976  uint32_t wg_x = FFMIN(fv->max_pixels_per_slice, 256);
977  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
978  (uint32_t []) { wg_x, 1, 1 }, 0);
979 
981  VK_SHADER_STAGE_COMPUTE_BIT);
982 
983  const FFVulkanDescriptorSetBinding desc_set_const[] = {
984  { /* rangecoder_buf */
985  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
986  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
987  },
988  };
989  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
990 
991  const FFVulkanDescriptorSetBinding desc_set[] = {
992  { /* slice_data_buf */
993  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
994  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
995  },
996  { /* src */
997  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
998  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
999  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1000  },
1001  { /* units */
1002  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1003  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1004  },
1005  };
1006  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0, 0);
1007 
1008  RET(ff_vk_shader_link(&fv->s, shd,
1011 
1012  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1013 
1014 fail:
1015  return err;
1016 }
1017 
1018 static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1019 {
1020  int err;
1021  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1022  FFVulkanShader *shd = &fv->remap;
1023 
1024  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1025  (uint32_t []) { 32, 32, 1 }, 0);
1026 
1028  VK_SHADER_STAGE_COMPUTE_BIT);
1029 
1030  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1031  { /* rangecoder_buf */
1032  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1033  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1034  },
1035  };
1036  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
1037 
1038  const FFVulkanDescriptorSetBinding desc_set[] = {
1039  { /* slice_data_buf */
1040  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1041  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1042  },
1043  { /* src */
1044  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1045  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1046  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1047  },
1048  { /* fltmap */
1049  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1050  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1051  },
1052  };
1053  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0, 0);
1054 
1055  RET(ff_vk_shader_link(&fv->s, shd,
1058 
1059  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1060 
1061 fail:
1062  return err;
1063 }
1064 
1065 static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1066 {
1067  int err;
1068  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1069  FFVulkanShader *shd = &fv->setup;
1070 
1071  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1072  (uint32_t []) { 1, 1, 1 }, 0);
1073 
1075  VK_SHADER_STAGE_COMPUTE_BIT);
1076 
1077  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1078  { /* rangecoder_buf */
1079  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1080  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1081  },
1082  };
1083  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
1084 
1085  const FFVulkanDescriptorSetBinding desc_set[] = {
1086  { /* slice_data_buf */
1087  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1088  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1089  },
1090  { /* fltmap */
1091  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1092  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1093  },
1094  };
1095  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0);
1096 
1097  RET(ff_vk_shader_link(&fv->s, shd,
1100 
1101  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1102 
1103 fail:
1104  return err;
1105 }
1106 
1107 static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1108 {
1109  int err;
1110  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1111  FFVulkanShader *shd = &fv->reset;
1112 
1113  int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1114 
1115  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1116  (uint32_t []) { wg_dim, 1, 1 }, 0);
1117 
1119  VK_SHADER_STAGE_COMPUTE_BIT);
1120 
1121  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1122  { /* rangecoder_buf */
1123  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1124  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1125  },
1126  };
1127  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
1128 
1129  const FFVulkanDescriptorSetBinding desc_set[] = {
1130  { /* slice_data_buf */
1131  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1132  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1133  },
1134  { /* slice_state_buf */
1135  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1136  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1137  },
1138  };
1139  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0);
1140 
1141  if (fv->ctx.ac == AC_GOLOMB_RICE)
1142  RET(ff_vk_shader_link(&fv->s, shd,
1145  else
1146  RET(ff_vk_shader_link(&fv->s, shd,
1149 
1150  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1151 
1152 fail:
1153  return err;
1154 }
1155 
1156 static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1157 {
1158  int err;
1159  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1160  FFV1Context *f = &fv->ctx;
1161  FFVulkanShader *shd = &fv->enc;
1162 
1163  uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1164  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1165  (uint32_t []) { wg_x, 1, 1 }, 0);
1166 
1168  VK_SHADER_STAGE_COMPUTE_BIT);
1169 
1170  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1171  { /* rangecoder_buf */
1172  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1173  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1174  },
1175  { /* quant_buf */
1176  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1177  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1178  },
1179  { /* crc_ieee_buf */
1180  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1181  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1182  },
1183  };
1184  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1, 0);
1185 
1186  const FFVulkanDescriptorSetBinding desc_set[] = {
1187  { /* slice_data_buf */
1188  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1189  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1190  },
1191  { /* slice_results_buf */
1192  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1193  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1194  },
1195  { /* slice_state_buf */
1196  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1197  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1198  },
1199  { /* src */
1200  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1201  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1202  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1203  },
1204  { /* tmp */
1205  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1206  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1207  },
1208  { /* fltmap */
1209  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1210  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1211  },
1212  };
1213  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1214  4 + fv->is_rgb + !!f->remap_mode, 0, 0);
1215 
1216  if (f->bayer) {
1217  if (fv->ctx.ac == AC_GOLOMB_RICE)
1218  ff_vk_shader_link(&fv->s, shd,
1221  else
1222  ff_vk_shader_link(&fv->s, shd,
1225  } else if (f->remap_mode) {
1226  if (fv->ctx.ac == AC_GOLOMB_RICE)
1227  ff_vk_shader_link(&fv->s, shd,
1230  else
1231  ff_vk_shader_link(&fv->s, shd,
1234  } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1235  if (fv->is_rgb)
1236  ff_vk_shader_link(&fv->s, shd,
1239  else
1240  ff_vk_shader_link(&fv->s, shd,
1243  } else {
1244  if (fv->is_rgb)
1245  ff_vk_shader_link(&fv->s, shd,
1248  else
1249  ff_vk_shader_link(&fv->s, shd,
1251  ff_ffv1_enc_comp_spv_len, "main");
1252  }
1253 
1254  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1255 
1256 fail:
1257  return err;
1258 }
1259 
1261 {
1262  int err;
1263  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1264  FFVulkanShader *shd = &fv->gather;
1265 
1266  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
1267  (uint32_t []) { 256, 1, 1 }, 0);
1268 
1270  VK_SHADER_STAGE_COMPUTE_BIT);
1271 
1272  const FFVulkanDescriptorSetBinding desc_set[] = {
1273  { /* sizes_buf */
1274  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1275  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1276  },
1277  };
1278  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0, 0);
1279 
1280  RET(ff_vk_shader_link(&fv->s, shd,
1282  ff_seg_gather_comp_spv_len, "main"));
1283 
1284  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1285 
1286 fail:
1287  return err;
1288 }
1289 
1291 {
1292  int err;
1293  size_t maxsize, max_heap_size, max_host_size;
1294  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1295  FFV1Context *f = &fv->ctx;
1296 
1297  if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1298  return err;
1299 
1300  if (f->ac == 1)
1301  f->ac = AC_RANGE_CUSTOM_TAB;
1302 
1303  err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1304  if (err < 0)
1305  return err;
1306 
1307  /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1308  * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1309  f->version = f->bayer ? 4 : 3;
1310 
1311  err = ff_ffv1_encode_init(avctx);
1312  if (err < 0)
1313  return err;
1314 
1315  /* Rice coding did not support high bit depths */
1316  if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1317  if (f->ac == AC_GOLOMB_RICE) {
1318  av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1319  "forcing range coder\n");
1320  f->ac = AC_RANGE_CUSTOM_TAB;
1321  }
1322  }
1323 
1324  if (f->version < 4 && avctx->gop_size > 1) {
1325  av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1326  return AVERROR_INVALIDDATA;
1327  }
1328 
1329  if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1330  av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1331  return AVERROR_INVALIDDATA;
1332  }
1333 
1334  /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1335  if (f->version == 4)
1336  f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1337 
1338  f->num_h_slices = fv->num_h_slices;
1339  f->num_v_slices = fv->num_v_slices;
1340 
1341  if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1342  if (avctx->slices) {
1343  err = ff_ffv1_encode_determine_slices(avctx);
1344  if (err < 0)
1345  return err;
1346  } else {
1347  f->num_h_slices = 32;
1348  f->num_v_slices = 32;
1349  }
1350  } else if (f->num_h_slices && f->num_v_slices <= 0) {
1351  f->num_v_slices = MAX_SLICES / f->num_h_slices;
1352  } else if (f->num_v_slices && f->num_h_slices <= 0) {
1353  f->num_h_slices = MAX_SLICES / f->num_v_slices;
1354  }
1355 
1356  f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1357  f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1358 
1359  if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1360  av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1361  "by the standard is %i\n",
1362  f->num_h_slices * f->num_v_slices, MAX_SLICES);
1363  return AVERROR_PATCHWELCOME;
1364  }
1365 
1366  f->max_slice_count = f->num_h_slices * f->num_v_slices;
1367 
1368  if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1369  return err;
1370 
1371  if (f->version < 4) {
1372  if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1373  ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1374  av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1375  "dimensions is only supported in version 4 (-level 4)\n");
1376  return AVERROR_PATCHWELCOME;
1377  }
1378  }
1379 
1380  if (fv->force_pcm) {
1381  if (f->version < 4) {
1382  av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1383  return AVERROR_INVALIDDATA;
1384  } else if (f->ac == AC_GOLOMB_RICE) {
1385  av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1386  return AVERROR_INVALIDDATA;
1387  }
1388  }
1389 
1390  /* Init Vulkan */
1391  err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1392  if (err < 0)
1393  return err;
1394 
1395  fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1396  if (!fv->qf) {
1397  av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1398  return err;
1399  }
1400 
1401  /* Try to measure VRAM size */
1402  max_heap_size = 0;
1403  max_host_size = 0;
1404  for (int i = 0; i < fv->s.mprops.memoryHeapCount; i++) {
1405  if (fv->s.mprops.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
1406  max_heap_size = FFMAX(fv->max_heap_size,
1407  fv->s.mprops.memoryHeaps[i].size);
1408  if (!(fv->s.mprops.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT))
1409  max_host_size = FFMAX(max_host_size,
1410  fv->s.mprops.memoryHeaps[i].size);
1411  }
1412  fv->max_heap_size = max_heap_size;
1413 
1414  maxsize = ffv1_vk_buffer_size(avctx);
1415  if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1416  av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1417  "than maximum device allocation (%"PRIu64"), clipping\n",
1418  maxsize, fv->s.props_11.maxMemoryAllocationSize);
1419  maxsize = fv->s.props_11.maxMemoryAllocationSize;
1420  }
1421 
1422  if (max_heap_size < maxsize) {
1423  av_log(avctx, AV_LOG_WARNING, "Encoding buffer (%zu) larger than VRAM (%zu), "
1424  "using host memory (slower)\n",
1425  maxsize, fv->max_heap_size);
1426 
1427  /* Keep 1/2th of RAM as headroom */
1428  max_heap_size = max_host_size - (max_host_size >> 1);
1429  } else {
1430  /* Keep 1/8th of VRAM as headroom */
1431  max_heap_size = max_heap_size - (max_heap_size >> 3);
1432  }
1433 
1434  av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1435  maxsize / (1024*1024),
1436  (fv->async_depth * 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 
1606 
1610 
1611  ff_vk_free_buf(&fv->s, &fv->results_buf);
1612 
1613  ff_vk_free_buf(&fv->s, &fv->consts_buf);
1614 
1615  av_frame_free(&fv->frame);
1616  ff_vk_uninit(&fv->s);
1617 
1618  return 0;
1619 }
1620 
1621 #define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1622 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1624  { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1625  { .i64 = -1 }, -1, 2, VE },
1626  { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1627  { .i64 = 0 }, 0, 1, VE },
1628  { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1629  { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1630  { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1631  { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1632  { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1633  { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1634  { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1635  { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1636  { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1637  { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1638  { "default", NULL, 0, AV_OPT_TYPE_CONST,
1639  { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1640  { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1641  { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1642  { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1643  { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1644 
1645  { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1646  { .i64 = -1 }, -1, MAX_SLICES, VE },
1647  { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1648  { .i64 = -1 }, -1, MAX_SLICES, VE },
1649 
1650  { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1651  { .i64 = 0 }, 0, 1, VE },
1652 
1653  { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1654  { .i64 = 1 }, 0, 1, VE },
1655 
1656  { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1657  { .i64 = 1 }, 1, INT_MAX, VE },
1658 
1659  { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1660  { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1661  { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1662  { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1663  { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1664  { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1665  { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1666  { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1667  { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1668  { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1669 
1670  { NULL }
1671 };
1672 
1674  { "g", "1" },
1675  { NULL },
1676 };
1677 
1679  .class_name = "ffv1_vulkan",
1680  .item_name = av_default_item_name,
1681  .option = vulkan_encode_ffv1_options,
1682  .version = LIBAVUTIL_VERSION_INT,
1683 };
1684 
1686  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1687  NULL,
1688 };
1689 
1691  .p.name = "ffv1_vulkan",
1692  CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1693  .p.type = AVMEDIA_TYPE_VIDEO,
1694  .p.id = AV_CODEC_ID_FFV1,
1695  .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1698  .close = &vulkan_encode_ffv1_close,
1699  .p.priv_class = &vulkan_encode_ffv1_class,
1700  .p.capabilities = AV_CODEC_CAP_DELAY |
1706  .defaults = vulkan_encode_ffv1_defaults,
1708  .hw_configs = vulkan_encode_ffv1_hw_configs,
1709  .p.wrapper_name = "vulkan",
1710 };
ffv1_vk_packet_free
static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
Definition: ffv1enc_vulkan.c:756
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
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:319
VulkanEncodeFFv1Context::gather
FFVulkanShader gather
Definition: ffv1enc_vulkan.c:76
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2853
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:88
FFVulkanContext::device_ref
AVBufferRef * device_ref
Definition: vulkan.h:347
FFVkExecPool::contexts
FFVkExecContext * contexts
Definition: vulkan.h:291
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:68
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:105
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:466
ff_vk_map_buffer
static int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem, int invalidate)
Definition: vulkan.h:603
VulkanEncodeFFv1Context::chunks
int chunks
Definition: ffv1enc_vulkan.c:109
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:216
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:70
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:130
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:2891
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:449
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2879
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:710
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ffv1_vk_buffer_size
static size_t ffv1_vk_buffer_size(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:171
SPEC_LIST_ADD
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition: vulkan.h:86
init_remap_shader
static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1018
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:2830
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
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:82
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:694
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:1678
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:101
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:2781
init_gather_shader
static int init_gather_shader(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1260
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:2646
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
VulkanEncodeFFv1Context::ppi
int ppi
Definition: ffv1enc_vulkan.c:108
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:114
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:86
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:1690
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:114
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:1685
get_packet
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:762
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:73
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
FFV1Context::use32bit
int use32bit
Definition: ffv1.h:160
QTABLE_8BIT
@ QTABLE_8BIT
Definition: ffv1enc.h:30
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
VulkanEncodeFFv1Context::max_heap_size
size_t max_heap_size
Definition: ffv1enc_vulkan.c:68
FFVulkanContext::host_cached_flag
VkMemoryPropertyFlagBits host_cached_flag
Definition: vulkan.h:345
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:838
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
QTABLE_GT8BIT
@ QTABLE_GT8BIT
Definition: ffv1enc.h:31
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:185
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:1156
FFV1Context::num_v_slices
int num_v_slices
Definition: ffv1.h:176
QTABLE_DEFAULT
@ QTABLE_DEFAULT
Definition: ffv1enc.h:29
VulkanEncodeFFv1Context::force_pcm
int force_pcm
Definition: ffv1enc_vulkan.c:102
VulkanEncodeFFv1Context::consts_buf
FFVkBuffer consts_buf
Definition: ffv1enc_vulkan.c:79
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:2419
FFVkExecContext::had_submission
int had_submission
Definition: vulkan.h:148
FFVkBuffer::size
size_t size
Definition: vulkan.h:129
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:76
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:100
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:134
FFVulkanContext
Definition: vulkan.h:312
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:85
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:551
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:579
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:2820
AVPacket::size
int size
Definition: packet.h:604
FFVulkanDescriptorSetBinding
Definition: vulkan.h:112
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:467
init_indirect
static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
Definition: ffv1enc_vulkan.c:892
FFVulkanShader
Definition: vulkan.h:225
VulkanEncodeFFv1Context::optimize_rct
int optimize_rct
Definition: ffv1enc_vulkan.c:103
AVCodecHWConfigInternal
Definition: hwconfig.h:25
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:128
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:145
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:2794
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
VulkanEncodeFFv1Context::sort32
FFVulkanShader sort32
Definition: ffv1enc_vulkan.c:72
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:75
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:1622
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:89
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:113
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:455
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:127
SegGatherPushData
Definition: ffv1enc_vulkan.c:112
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:318
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:1065
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:689
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
FFVulkanContext::mprops
VkPhysicalDeviceMemoryProperties mprops
Definition: vulkan.h:321
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
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:316
SegGatherPushData::slot_size
uint32_t slot_size
Definition: ffv1enc_vulkan.c:115
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:162
FFVkExecPool
Definition: vulkan.h:290
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:98
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:563
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:1623
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:156
VulkanEncodeFFv1Context::compacted_data_pool
AVBufferPool * compacted_data_pool
Definition: ffv1enc_vulkan.c:95
AVCodecContext
main external API structure.
Definition: avcodec.h:443
ff_ffv1_enc_comp_spv_data
const unsigned char ff_ffv1_enc_comp_spv_data[]
ff_vk_shader_add_descriptor_set
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular, int print_to_shader_only)
Add descriptor to a shader.
Definition: vulkan.c:2546
init_reset_shader
static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1107
RGB_LINECACHE
#define RGB_LINECACHE
Definition: ffv1enc_vulkan.c:40
VulkanEncodeFFv1Context::reset
FFVulkanShader reset
Definition: ffv1enc_vulkan.c:74
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:247
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:278
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:1673
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:349
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:106
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:107
FFVkBuffer
Definition: vulkan.h:125
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:1290
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:353
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:1621
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:71
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:970
FFVulkanFunctions
Definition: vulkan_functions.h:275
FFVkExecPool::pool_size
int pool_size
Definition: vulkan.h:296
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:146
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:927
VulkanEncodeFFv1Context::out_data_pool
AVBufferPool * out_data_pool
Definition: ffv1enc_vulkan.c:92
ff_source_rangecoder_comp
const char * ff_source_rangecoder_comp