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 */
45 
46  /* Copied from the source */
49  void *frame_opaque;
51 
52  int key_frame;
53  int idx;
55 
56 typedef struct VulkanEncodeFFv1Context {
59 
63 
66 
67  VkBufferCopy *buf_regions;
69  int in_flight;
71  size_t max_heap_size;
72 
79 
80  /* Constant read-only buffers */
82 
83  /* Results buffer */
85 
86  /* Slice data buffer pool */
89 
90  /* Remap data pool */
92 
93  /* Output data buffer */
95 
96  /* Intermediate frame pool */
98 
103 
104  int is_rgb;
107  int ppi;
108  int chunks;
110 
111 extern const char *ff_source_common_comp;
112 extern const char *ff_source_rangecoder_comp;
113 extern const char *ff_source_ffv1_vlc_comp;
114 extern const char *ff_source_ffv1_common_comp;
115 extern const char *ff_source_ffv1_enc_comp;
116 
117 extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
118 extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
119 
120 extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
121 extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
122 
123 extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[];
124 extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len;
125 
126 extern const unsigned char ff_ffv1_enc_comp_spv_data[];
127 extern const unsigned int ff_ffv1_enc_comp_spv_len;
128 
129 extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[];
130 extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len;
131 
132 extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[];
133 extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len;
134 
135 extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[];
136 extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len;
137 
138 extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[];
139 extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len;
140 
141 extern const unsigned char ff_ffv1_enc_remap_comp_spv_data[];
142 extern const unsigned int ff_ffv1_enc_remap_comp_spv_len;
143 
144 extern const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[];
145 extern const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len;
146 
147 extern const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[];
148 extern const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len;
149 
150 extern const unsigned char ff_ffv1_enc_sort32_comp_spv_data[];
151 extern const unsigned int ff_ffv1_enc_sort32_comp_spv_len;
152 
154  AVFrame *enc_in, VkImageView *enc_in_views,
155  FFVkBuffer *slice_data_buf, uint32_t slice_data_size,
156  FFv1ShaderParams *pd)
157 {
158  VulkanEncodeFFv1Context *fv = avctx->priv_data;
159  FFV1Context *f = &fv->ctx;
160  FFVulkanFunctions *vk = &fv->s.vkfn;
161 
162  /* Update descriptors */
164  1, 0, 0,
165  slice_data_buf,
166  0, slice_data_size*f->slice_count,
167  VK_FORMAT_UNDEFINED);
168  ff_vk_shader_update_img_array(&fv->s, exec, &fv->rct_search,
169  enc_in, enc_in_views,
170  1, 1,
171  VK_IMAGE_LAYOUT_GENERAL,
172  VK_NULL_HANDLE);
173 
174  ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct_search);
176  VK_SHADER_STAGE_COMPUTE_BIT,
177  0, sizeof(FFv1ShaderParams), pd);
178 
179  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
180 
181  return 0;
182 }
183 
184 static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec,
185  AVFrame *enc_in, VkImageView *enc_in_views,
186  FFVkBuffer *fltmap_buf, uint32_t fltmap_size,
187  FFv1ShaderParams *pd)
188 {
189  VulkanEncodeFFv1Context *fv = avctx->priv_data;
190  FFV1Context *f = &fv->ctx;
191  FFVulkanFunctions *vk = &fv->s.vkfn;
192 
193  /* Update descriptors */
194  ff_vk_shader_update_img_array(&fv->s, exec, &fv->remap,
195  enc_in, enc_in_views,
196  1, 1,
197  VK_IMAGE_LAYOUT_GENERAL,
198  VK_NULL_HANDLE);
199  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->remap,
200  1, 2, 0,
201  fltmap_buf,
202  0, fltmap_size*f->slice_count,
203  VK_FORMAT_UNDEFINED);
204 
205  ff_vk_exec_bind_shader(&fv->s, exec, &fv->remap);
206  ff_vk_shader_update_push_const(&fv->s, exec, &fv->remap,
207  VK_SHADER_STAGE_COMPUTE_BIT,
208  0, sizeof(FFv1ShaderParams), pd);
209 
210  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
211 
212  return 0;
213 }
214 
215 static int run_sort32(AVCodecContext *avctx, FFVkExecContext *exec,
216  AVFrame *enc_in, VkImageView *enc_in_views,
217  FFVkBuffer *units_buf, uint32_t units_size,
218  FFv1ShaderParams *pd)
219 {
220  VulkanEncodeFFv1Context *fv = avctx->priv_data;
221  FFV1Context *f = &fv->ctx;
222  FFVulkanFunctions *vk = &fv->s.vkfn;
223 
224  /* Update descriptors */
225  ff_vk_shader_update_img_array(&fv->s, exec, &fv->sort32,
226  enc_in, enc_in_views,
227  1, 1,
228  VK_IMAGE_LAYOUT_GENERAL,
229  VK_NULL_HANDLE);
230  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->sort32,
231  1, 2, 0,
232  units_buf,
233  0, units_size*f->slice_count,
234  VK_FORMAT_UNDEFINED);
235 
236  ff_vk_exec_bind_shader(&fv->s, exec, &fv->sort32);
237  ff_vk_shader_update_push_const(&fv->s, exec, &fv->sort32,
238  VK_SHADER_STAGE_COMPUTE_BIT,
239  0, sizeof(FFv1ShaderParams), pd);
240 
241  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
242 
243  return 0;
244 }
245 
247  FFVkExecContext *exec,
248  const AVFrame *pict)
249 {
250  int err;
251  VulkanEncodeFFv1Context *fv = avctx->priv_data;
252  FFV1Context *f = &fv->ctx;
253  FFVulkanFunctions *vk = &fv->s.vkfn;
254 
255  VulkanEncodeFFv1FrameData *fd = exec->opaque;
256 
257  /* Slice data */
258  AVBufferRef *slice_data_ref;
259  FFVkBuffer *slice_data_buf;
260  uint32_t plane_state_size;
261  uint32_t slice_state_size;
262  uint32_t slice_data_size;
263 
264  /* Remap data */
265  AVBufferRef *remap_data_ref = NULL;
266  FFVkBuffer *remap_data_buf = NULL;
267  uint32_t remap_data_size = 0;
268 
269  /* Output data */
270  size_t maxsize;
271  FFVkBuffer *out_data_buf;
272 
273  int has_inter = avctx->gop_size > 1;
274  uint32_t context_count = f->context_count[f->context_model];
275 
276  VkImageMemoryBarrier2 img_bar[37];
277  int nb_img_bar = 0;
278  VkBufferMemoryBarrier2 buf_bar[8];
279  int nb_buf_bar = 0;
280 
281  /* Frame state */
282  f->cur_enc_frame = pict;
283  if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
285  f->key_frame = fd->key_frame = 1;
286  f->gob_count++;
287  } else {
288  f->key_frame = fd->key_frame = 0;
289  }
290 
291  f->slice_count = f->max_slice_count;
292 
293  /* Allocate slice buffer data */
294  if (f->ac == AC_GOLOMB_RICE)
295  plane_state_size = 8;
296  else
297  plane_state_size = CONTEXT_SIZE;
298 
299  plane_state_size *= context_count;
300  slice_state_size = plane_state_size*f->plane_count;
301 
302  slice_data_size = 256; /* Overestimation for the SliceContext struct */
303  slice_state_size += slice_data_size;
304  slice_state_size = FFALIGN(slice_state_size, 8);
305 
306  /* Allocate slice data buffer */
307  slice_data_ref = fv->keyframe_slice_data_ref;
308  if (!slice_data_ref) {
310  &slice_data_ref,
311  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
312  NULL, slice_state_size*f->slice_count,
313  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
314 
315  /* Only save it if we're going to use it again */
316  if (has_inter)
317  fv->keyframe_slice_data_ref = slice_data_ref;
318  }
319  slice_data_buf = (FFVkBuffer *)slice_data_ref->data;
320 
321  if (f->remap_mode) {
322  if (fv->is_float32) {
323  /* Per (slice, plane): [units : max_pixels*2 uints] + [bitmap : max_pixels uints]. */
324  remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
325  } else {
327  remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
328  }
329 
331  &remap_data_ref,
332  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
333  NULL, remap_data_size*f->slice_count,
334  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
335  remap_data_buf = (FFVkBuffer *)remap_data_ref->data;
336  }
337 
338  /* Output buffer size */
339  maxsize = ff_ffv1_encode_buffer_size(avctx);
340  maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
341 
342  /* Allocate output buffer */
343  VkMemoryPropertyFlagBits out_buf_flags;
344  if (maxsize < fv->max_heap_size) {
345  out_buf_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
346  /* If we can't map host memory, we can't let the GPU copy its buffer. */
348  out_buf_flags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
349  } else {
350  out_buf_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
351  fv->s.host_cached_flag;
352  }
353 
355  &fd->out_data_ref,
356  VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
357  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
358  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
359  NULL, maxsize, out_buf_flags));
360  out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
361 
362  /* Image views */
363  AVFrame *src = (AVFrame *)pict;
364  VkImageView src_views[AV_NUM_DATA_POINTERS];
365 
366  AVFrame *tmp = NULL;
367  VkImageView tmp_views[AV_NUM_DATA_POINTERS];
368  if (fv->is_rgb) {
369  /* Create a temporaty frame */
370  tmp = av_frame_alloc();
371  if (!(tmp))
372  return AVERROR(ENOMEM);
373 
375  tmp, 0));
376  }
377 
378  /* With everything allocated, setup push data */
379  FFv1ShaderParams pd = {
380  .slice_data = out_data_buf->address,
381 
382  .img_size[0] = fv->s.frames->width,
383  .img_size[1] = fv->s.frames->height,
384 
385  .plane_state_size = plane_state_size,
386  .key_frame = f->key_frame,
387  .crcref = f->crcref,
388  .micro_version = f->micro_version,
389 
390  .sar[0] = pict->sample_aspect_ratio.num,
391  .sar[1] = pict->sample_aspect_ratio.den,
392  .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
393  !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
394  .slice_size_max = out_data_buf->size / f->slice_count,
395  .max_pixels_per_slice = fv->max_pixels_per_slice,
396  };
397 
398  for (int i = 0; i < f->quant_table_count; i++) {
399  pd.context_count[i] = f->context_count[i];
400  pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
401  f->quant_tables[i][4][127];
402  }
403 
404  /* For some reason the C FFv1 encoder/decoder treats these differently */
405  if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
406  avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
407  avctx->sw_pix_fmt == AV_PIX_FMT_GBRP14)
408  memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
409  else
410  ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
411 
412  /* Start recording */
413  ff_vk_exec_start(&fv->s, exec);
414  fd->idx = exec->idx;
415 
416  /* For float pixel formats we want the raw bit pattern, not a value
417  * already passed through fp16/fp32 conversion (which can flush
418  * denormals). Use a UINT view in that case. */
419  RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
420  f->remap_mode ? FF_VK_REP_UINT
421  : FF_VK_REP_NATIVE));
422 
423  ff_vk_exec_add_dep_buf(&fv->s, exec, &slice_data_ref, 1, has_inter);
424  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->out_data_ref, 1, 1);
425  if (f->remap_mode) {
426  ff_vk_exec_add_dep_buf(&fv->s, exec, &remap_data_ref, 1, 0);
427  remap_data_ref = NULL;
428  }
429 
430  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
431  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
432  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
433  if (fv->is_rgb)
434  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
435  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
436  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
437 
438  if (fv->optimize_rct || f->remap_mode) {
439  /* Prepare the frame for reading */
440  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
441  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
442  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
443  VK_ACCESS_SHADER_READ_BIT,
444  VK_IMAGE_LAYOUT_GENERAL,
445  VK_QUEUE_FAMILY_IGNORED);
446 
447  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
448  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
449  .pImageMemoryBarriers = img_bar,
450  .imageMemoryBarrierCount = nb_img_bar,
451  });
452  nb_img_bar = 0;
453  }
454 
455  /* Run RCT search if needed */
456  if (fv->optimize_rct) {
457  RET(run_rct_search(avctx, exec, src, src_views,
458  slice_data_buf, slice_data_size, &pd));
459 
460  /* Make sure the writes are visible to the setup shader */
461  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
462  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
463  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
464  0, slice_data_size*f->slice_count);
465  }
466 
467  if (f->remap_mode) {
468  if (fv->is_float32) {
469  RET(run_sort32(avctx, exec, src, src_views,
470  remap_data_buf, remap_data_size, &pd));
471  } else {
472  RET(run_remap(avctx, exec, src, src_views,
473  remap_data_buf, remap_data_size, &pd));
474  }
475 
476  /* Make sure the writes are visible to the setup shader */
477  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
478  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
479  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
480  0, remap_data_size*f->slice_count);
481  }
482 
483  if (fv->optimize_rct || f->remap_mode) {
484  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
485  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
486  .pBufferMemoryBarriers = buf_bar,
487  .bufferMemoryBarrierCount = nb_buf_bar,
488  });
489  nb_buf_bar = 0;
490  }
491 
492  /* Setup shader */
493  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
494  1, 0, 0,
495  slice_data_buf,
496  0, slice_data_size*f->slice_count,
497  VK_FORMAT_UNDEFINED);
498  if (f->remap_mode)
500  &fv->setup, 1, 1, 0,
501  remap_data_buf,
502  0, remap_data_size*f->slice_count,
503  VK_FORMAT_UNDEFINED);
504 
505  ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
506  ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
507  VK_SHADER_STAGE_COMPUTE_BIT,
508  0, sizeof(FFv1ShaderParams), &pd);
509 
510  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
511 
512  /* Clean up temporary image if needed */
513  if (fv->is_rgb) {
514  AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
515  vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
516  vkf->access[0] = VK_ACCESS_2_NONE;
517 
518  RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
519  tmp,
521 
522  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
523  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
524  VK_PIPELINE_STAGE_2_CLEAR_BIT,
525  VK_ACCESS_2_TRANSFER_WRITE_BIT,
526  VK_IMAGE_LAYOUT_GENERAL,
527  VK_QUEUE_FAMILY_IGNORED);
528  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
529  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
530  .pImageMemoryBarriers = img_bar,
531  .imageMemoryBarrierCount = nb_img_bar,
532  });
533  nb_img_bar = 0;
534 
535  vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
536  &((VkClearColorValue) { 0 }),
537  1, &((VkImageSubresourceRange) {
538  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
539  .levelCount = 1,
540  .layerCount = 1,
541  }));
542  }
543 
544  /* Run reset shader */
545  if (f->key_frame || fv->force_pcm) {
546  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
547  1, 0, 0,
548  slice_data_buf,
549  0, slice_data_size*f->slice_count,
550  VK_FORMAT_UNDEFINED);
551  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
552  1, 1, 0,
553  slice_data_buf,
554  f->slice_count*256,
555  VK_WHOLE_SIZE,
556  VK_FORMAT_UNDEFINED);
557 
558  ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
559  ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
560  VK_SHADER_STAGE_COMPUTE_BIT,
561  0, sizeof(FFv1ShaderParams), &pd);
562 
563  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
564  f->plane_count);
565  }
566 
567  /* Sync between reset and encode shaders */
568  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
569  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
570  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
571  0, slice_data_size*f->slice_count);
572 
573  /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
574  * back into the remap buffer; the encode shader reads it. */
575  if (f->remap_mode)
576  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
577  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
578  COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
579  0, remap_data_size*f->slice_count);
580  if (f->key_frame || fv->force_pcm)
581  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
582  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
583  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
584  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
585  else
586  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
587  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
588  COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
589  slice_data_size*f->slice_count, VK_WHOLE_SIZE);
590 
591  ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
592  fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
593  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
594  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
595  VK_ACCESS_SHADER_READ_BIT,
596  VK_IMAGE_LAYOUT_GENERAL,
597  VK_QUEUE_FAMILY_IGNORED);
598 
599  if (fv->is_rgb)
600  ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
601  VK_PIPELINE_STAGE_2_CLEAR_BIT,
602  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
603  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
604  VK_IMAGE_LAYOUT_GENERAL,
605  VK_QUEUE_FAMILY_IGNORED);
606 
607  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
608  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
609  .pImageMemoryBarriers = img_bar,
610  .imageMemoryBarrierCount = nb_img_bar,
611  .pBufferMemoryBarriers = buf_bar,
612  .bufferMemoryBarrierCount = nb_buf_bar,
613  });
614  nb_img_bar = 0;
615  nb_buf_bar = 0;
616 
617  /* Main encode shader */
618  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
619  1, 0, 0,
620  slice_data_buf,
621  0, slice_data_size*f->slice_count,
622  VK_FORMAT_UNDEFINED);
624  &fv->enc, 1, 1, 0,
625  &fv->results_buf,
626  fd->idx*f->max_slice_count*sizeof(uint32_t),
627  f->slice_count*sizeof(uint32_t),
628  VK_FORMAT_UNDEFINED);
629  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
630  1, 2, 0,
631  slice_data_buf,
632  f->slice_count*256,
633  VK_WHOLE_SIZE,
634  VK_FORMAT_UNDEFINED);
635  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
636  src, src_views,
637  1, 3,
638  VK_IMAGE_LAYOUT_GENERAL,
639  VK_NULL_HANDLE);
640  if (fv->is_rgb)
641  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
642  tmp, tmp_views,
643  1, 4,
644  VK_IMAGE_LAYOUT_GENERAL,
645  VK_NULL_HANDLE);
646  if (f->remap_mode)
648  &fv->enc, 1, 5, 0,
649  remap_data_buf,
650  0, remap_data_size*f->slice_count,
651  VK_FORMAT_UNDEFINED);
652 
653  ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
654  ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
655  VK_SHADER_STAGE_COMPUTE_BIT,
656  0, sizeof(FFv1ShaderParams), &pd);
657  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
658 
659  /* Submit */
660  err = ff_vk_exec_submit(&fv->s, exec);
661  if (err < 0)
662  return err;
663 
664  f->picture_number++;
665 
666  /* This, if needed, was referenced by the execution context
667  * as it was declared as a dependency. */
668  av_frame_free(&tmp);
669  return 0;
670 
671 fail:
672  av_frame_free(&tmp);
673  ff_vk_exec_discard_deps(&fv->s, exec);
674 
675  return err;
676 }
677 
678 static int transfer_slices(AVCodecContext *avctx,
679  VkBufferCopy *buf_regions, int nb_regions,
681  uint8_t *dst, AVBufferRef *dst_ref)
682 {
683  int err;
684  VulkanEncodeFFv1Context *fv = avctx->priv_data;
685  FFVulkanFunctions *vk = &fv->s.vkfn;
686  FFVkExecContext *exec;
687 
688  FFVkBuffer *out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
689 
690  AVBufferRef *mapped_ref;
691  FFVkBuffer *mapped_buf;
692 
693  VkBufferMemoryBarrier2 buf_bar[8];
694  int nb_buf_bar = 0;
695 
696  err = ff_vk_host_map_buffer(&fv->s, &mapped_ref, dst, dst_ref,
697  VK_BUFFER_USAGE_TRANSFER_DST_BIT);
698  if (err < 0)
699  return err;
700 
701  mapped_buf = (FFVkBuffer *)mapped_ref->data;
702 
703  /* Transfer the slices */
704  exec = ff_vk_exec_get(&fv->s, &fv->transfer_exec_pool);
705  ff_vk_exec_start(&fv->s, exec);
706 
707  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->out_data_ref, 1, 0);
708  fd->out_data_ref = NULL; /* Ownership passed */
709 
710  ff_vk_exec_add_dep_buf(&fv->s, exec, &mapped_ref, 1, 0);
711  mapped_ref = NULL; /* Ownership passed */
712 
713  /* Ensure the output buffer is finished */
714  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], out_data_buf,
715  COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
716  TRANSFER_BIT, TRANSFER_READ_BIT, NONE_KHR,
717  0, VK_WHOLE_SIZE);
718  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
719  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
720  .pBufferMemoryBarriers = buf_bar,
721  .bufferMemoryBarrierCount = nb_buf_bar,
722  });
723  nb_buf_bar = 0;
724 
725  for (int i = 0; i < nb_regions; i++)
726  buf_regions[i].dstOffset += mapped_buf->virtual_offset;
727 
728  vk->CmdCopyBuffer(exec->buf,
729  out_data_buf->buf, mapped_buf->buf,
730  nb_regions, buf_regions);
731 
732  /* Submit */
733  err = ff_vk_exec_submit(&fv->s, exec);
734  if (err < 0)
735  return err;
736 
737  /* We need the encoded data immediately */
738  ff_vk_exec_wait(&fv->s, exec);
739 
740  return 0;
741 }
742 
743 static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec,
744  AVPacket *pkt)
745 {
746  int err;
747  VulkanEncodeFFv1Context *fv = avctx->priv_data;
748  FFV1Context *f = &fv->ctx;
749  FFVulkanFunctions *vk = &fv->s.vkfn;
750  VulkanEncodeFFv1FrameData *fd = exec->opaque;
751 
752  FFVkBuffer *out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
753  uint32_t slice_size_max = out_data_buf->size / f->slice_count;
754 
755  /* Make sure encoding's done */
756  ff_vk_exec_wait(&fv->s, exec);
757 
758  /* Invalidate slice/output data if needed */
759  uint32_t rb_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
760  if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
761  VkMappedMemoryRange invalidate_data = {
762  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
763  .memory = fv->results_buf.mem,
764  .offset = rb_off,
765  .size = f->slice_count*sizeof(uint32_t),
766  };
767  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
768  1, &invalidate_data);
769  }
770 
771  /* Calculate final size */
772  pkt->size = 0;
773  uint8_t *rb = fv->results_buf.mapped_mem + rb_off;
774  for (int i = 0; i < f->slice_count; i++) {
775  uint32_t sl_len = AV_RN32(rb + i*4);
776  av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %u\n", i, sl_len);
777 
778  fv->buf_regions[i] = (VkBufferCopy) {
779  .srcOffset = i*slice_size_max,
780  .dstOffset = pkt->size,
781  .size = sl_len,
782  };
783  pkt->size += sl_len;
784  }
785  av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
786 
787  /* Allocate packet */
788  if ((err = ff_get_encode_buffer(avctx, pkt, pkt->size, 0)) < 0)
789  return err;
790 
791  pkt->pts = fd->pts;
792  pkt->dts = fd->pts;
793  pkt->duration = fd->duration;
795 
796  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
797  pkt->opaque = fd->frame_opaque;
799  fd->frame_opaque_ref = NULL;
800  }
801 
802  /* Try using host mapped memory transfers first */
804  err = transfer_slices(avctx, fv->buf_regions, f->slice_count, fd,
805  pkt->data, pkt->buf);
806  if (err >= 0)
807  return err;
808  }
809 
810  /* Invalidate slice/output data if needed */
811  if (!(out_data_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
812  VkMappedMemoryRange invalidate_data = {
813  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
814  .memory = out_data_buf->mem,
815  .offset = 0,
816  .size = VK_WHOLE_SIZE,
817  };
818  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
819  1, &invalidate_data);
820  }
821 
822  /* Copy each slice */
823  for (int i = 0; i < f->slice_count; i++) {
824  VkBufferCopy *region = &fv->buf_regions[i];
825  memcpy(pkt->data + region->dstOffset,
826  out_data_buf->mapped_mem + region->srcOffset,
827  region->size);
828  }
829 
831 
832  return 0;
833 }
834 
836  AVPacket *pkt)
837 {
838  int err;
839  VulkanEncodeFFv1Context *fv = avctx->priv_data;
841  FFVkExecContext *exec;
842  AVFrame *frame;
843 
844  while (1) {
845  /* Roll an execution context */
846  exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
847 
848  /* If it had a frame, immediately output it */
849  if (exec->had_submission) {
850  exec->had_submission = 0;
851  fv->in_flight--;
852  return get_packet(avctx, exec, pkt);
853  }
854 
855  /* Get next frame to encode */
856  frame = fv->frame;
857  err = ff_encode_get_frame(avctx, frame);
858  if (err < 0 && err != AVERROR_EOF) {
859  return err;
860  } else if (err == AVERROR_EOF) {
861  if (!fv->in_flight)
862  return err;
863  continue;
864  }
865 
866  /* Encode frame */
867  fd = exec->opaque;
868  fd->pts = frame->pts;
869  fd->duration = frame->duration;
870  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
871  fd->frame_opaque = frame->opaque;
872  fd->frame_opaque_ref = frame->opaque_ref;
873  frame->opaque_ref = NULL;
874  }
875 
876  err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
878  if (err < 0)
879  return err;
880 
881  fv->in_flight++;
882  if (fv->in_flight < fv->async_depth)
883  return AVERROR(EAGAIN);
884  }
885 
886  return 0;
887 }
888 
889 static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
890 {
891  int err;
892  VulkanEncodeFFv1Context *fv = avctx->priv_data;
893  FFV1Context *f = &fv->ctx;
894  AVHWFramesContext *frames_ctx;
895  AVVulkanFramesContext *vk_frames;
896 
898  if (!fv->intermediate_frames_ref)
899  return AVERROR(ENOMEM);
900 
901  frames_ctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data;
902  frames_ctx->format = AV_PIX_FMT_VULKAN;
903  frames_ctx->sw_format = sw_format;
904  frames_ctx->width = fv->s.frames->width;
905  frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
906 
907  vk_frames = frames_ctx->hwctx;
908  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
909  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
910  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
911  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
912 
914  if (err < 0) {
915  av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
916  av_get_pix_fmt_name(sw_format), av_err2str(err));
918  return err;
919  }
920 
921  return 0;
922 }
923 
924 static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
925 {
926  int err;
927  VulkanEncodeFFv1Context *fv = avctx->priv_data;
928  FFVulkanShader *shd = &fv->rct_search;
929 
930  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
931  (uint32_t []) { 32, 32, 1 }, 0);
932 
934  VK_SHADER_STAGE_COMPUTE_BIT);
935 
936  const FFVulkanDescriptorSetBinding desc_set_const[] = {
937  { /* rangecoder_buf */
938  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
939  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
940  },
941  };
942  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
943 
944  const FFVulkanDescriptorSetBinding desc_set[] = {
945  { /* slice_data_buf */
946  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
947  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
948  },
949  { /* src */
950  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
951  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
952  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
953  },
954  };
955  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0);
956 
957  RET(ff_vk_shader_link(&fv->s, shd,
960 
961  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
962 
963 fail:
964  return err;
965 }
966 
967 static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
968 {
969  int err;
970  VulkanEncodeFFv1Context *fv = avctx->priv_data;
971  FFVulkanShader *shd = &fv->sort32;
972 
973  uint32_t wg_x = FFMIN(fv->max_pixels_per_slice, 256);
974  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
975  (uint32_t []) { wg_x, 1, 1 }, 0);
976 
978  VK_SHADER_STAGE_COMPUTE_BIT);
979 
980  const FFVulkanDescriptorSetBinding desc_set_const[] = {
981  { /* rangecoder_buf */
982  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
983  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
984  },
985  };
986  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
987 
988  const FFVulkanDescriptorSetBinding desc_set[] = {
989  { /* slice_data_buf */
990  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
991  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
992  },
993  { /* src */
994  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
995  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
996  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
997  },
998  { /* units */
999  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1000  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1001  },
1002  };
1003  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0, 0);
1004 
1005  RET(ff_vk_shader_link(&fv->s, shd,
1008 
1009  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1010 
1011 fail:
1012  return err;
1013 }
1014 
1015 static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1016 {
1017  int err;
1018  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1019  FFVulkanShader *shd = &fv->remap;
1020 
1021  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1022  (uint32_t []) { 32, 32, 1 }, 0);
1023 
1025  VK_SHADER_STAGE_COMPUTE_BIT);
1026 
1027  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1028  { /* rangecoder_buf */
1029  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1030  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1031  },
1032  };
1033  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
1034 
1035  const FFVulkanDescriptorSetBinding desc_set[] = {
1036  { /* slice_data_buf */
1037  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1038  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1039  },
1040  { /* src */
1041  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1042  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1043  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1044  },
1045  { /* fltmap */
1046  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1047  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1048  },
1049  };
1050  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0, 0);
1051 
1052  RET(ff_vk_shader_link(&fv->s, shd,
1055 
1056  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1057 
1058 fail:
1059  return err;
1060 }
1061 
1062 static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1063 {
1064  int err;
1065  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1066  FFVulkanShader *shd = &fv->setup;
1067 
1068  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1069  (uint32_t []) { 1, 1, 1 }, 0);
1070 
1072  VK_SHADER_STAGE_COMPUTE_BIT);
1073 
1074  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1075  { /* rangecoder_buf */
1076  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1077  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1078  },
1079  };
1080  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
1081 
1082  const FFVulkanDescriptorSetBinding desc_set[] = {
1083  { /* slice_data_buf */
1084  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1085  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1086  },
1087  { /* fltmap */
1088  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1089  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1090  },
1091  };
1092  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0);
1093 
1094  RET(ff_vk_shader_link(&fv->s, shd,
1097 
1098  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1099 
1100 fail:
1101  return err;
1102 }
1103 
1104 static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1105 {
1106  int err;
1107  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1108  FFVulkanShader *shd = &fv->reset;
1109 
1110  int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1111 
1112  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1113  (uint32_t []) { wg_dim, 1, 1 }, 0);
1114 
1116  VK_SHADER_STAGE_COMPUTE_BIT);
1117 
1118  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1119  { /* rangecoder_buf */
1120  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1121  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1122  },
1123  };
1124  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
1125 
1126  const FFVulkanDescriptorSetBinding desc_set[] = {
1127  { /* slice_data_buf */
1128  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1129  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1130  },
1131  { /* slice_state_buf */
1132  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1133  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1134  },
1135  };
1136  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0);
1137 
1138  if (fv->ctx.ac == AC_GOLOMB_RICE)
1139  RET(ff_vk_shader_link(&fv->s, shd,
1142  else
1143  RET(ff_vk_shader_link(&fv->s, shd,
1146 
1147  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1148 
1149 fail:
1150  return err;
1151 }
1152 
1153 static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1154 {
1155  int err;
1156  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1157  FFV1Context *f = &fv->ctx;
1158  FFVulkanShader *shd = &fv->enc;
1159 
1160  uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1161  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1162  (uint32_t []) { wg_x, 1, 1 }, 0);
1163 
1165  VK_SHADER_STAGE_COMPUTE_BIT);
1166 
1167  const FFVulkanDescriptorSetBinding desc_set_const[] = {
1168  { /* rangecoder_buf */
1169  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1170  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1171  },
1172  { /* quant_buf */
1173  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1174  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1175  },
1176  { /* crc_ieee_buf */
1177  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1178  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1179  },
1180  };
1181  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1, 0);
1182 
1183  const FFVulkanDescriptorSetBinding desc_set[] = {
1184  { /* slice_data_buf */
1185  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1186  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1187  },
1188  { /* slice_results_buf */
1189  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1190  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1191  },
1192  { /* slice_state_buf */
1193  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1194  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1195  },
1196  { /* src */
1197  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1198  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1199  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1200  },
1201  { /* tmp */
1202  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1203  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1204  },
1205  { /* fltmap */
1206  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1207  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1208  },
1209  };
1210  ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1211  4 + fv->is_rgb + !!f->remap_mode, 0, 0);
1212 
1213  if (f->remap_mode) {
1214  if (fv->ctx.ac == AC_GOLOMB_RICE)
1215  ff_vk_shader_link(&fv->s, shd,
1218  else
1219  ff_vk_shader_link(&fv->s, shd,
1222  } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1223  if (fv->is_rgb)
1224  ff_vk_shader_link(&fv->s, shd,
1227  else
1228  ff_vk_shader_link(&fv->s, shd,
1231  } else {
1232  if (fv->is_rgb)
1233  ff_vk_shader_link(&fv->s, shd,
1236  else
1237  ff_vk_shader_link(&fv->s, shd,
1239  ff_ffv1_enc_comp_spv_len, "main");
1240  }
1241 
1242  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1243 
1244 fail:
1245  return err;
1246 }
1247 
1249 {
1250  int err;
1251  size_t maxsize, max_heap_size, max_host_size;
1252  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1253  FFV1Context *f = &fv->ctx;
1254 
1255  if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1256  return err;
1257 
1258  if (f->ac == 1)
1259  f->ac = AC_RANGE_CUSTOM_TAB;
1260 
1261  err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1262  if (err < 0)
1263  return err;
1264 
1265  /* Target version 3 by default */
1266  f->version = 3;
1267 
1268  err = ff_ffv1_encode_init(avctx);
1269  if (err < 0)
1270  return err;
1271 
1272  /* Rice coding did not support high bit depths */
1273  if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1274  if (f->ac == AC_GOLOMB_RICE) {
1275  av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1276  "forcing range coder\n");
1277  f->ac = AC_RANGE_CUSTOM_TAB;
1278  }
1279  }
1280 
1281  if (f->version < 4 && avctx->gop_size > 1) {
1282  av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1283  return AVERROR_INVALIDDATA;
1284  }
1285 
1286  if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1287  av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1288  return AVERROR_INVALIDDATA;
1289  }
1290 
1291  /* We target version 4.3 */
1292  if (f->version == 4)
1293  f->micro_version = f->remap_mode ? 9 : 3;
1294 
1295  f->num_h_slices = fv->num_h_slices;
1296  f->num_v_slices = fv->num_v_slices;
1297 
1298  if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1299  if (avctx->slices) {
1300  err = ff_ffv1_encode_determine_slices(avctx);
1301  if (err < 0)
1302  return err;
1303  } else {
1304  f->num_h_slices = 32;
1305  f->num_v_slices = 32;
1306  }
1307  } else if (f->num_h_slices && f->num_v_slices <= 0) {
1308  f->num_v_slices = MAX_SLICES / f->num_h_slices;
1309  } else if (f->num_v_slices && f->num_h_slices <= 0) {
1310  f->num_h_slices = MAX_SLICES / f->num_v_slices;
1311  }
1312 
1313  f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1314  f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1315 
1316  if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1317  av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1318  "by the standard is %i\n",
1319  f->num_h_slices * f->num_v_slices, MAX_SLICES);
1320  return AVERROR_PATCHWELCOME;
1321  }
1322 
1323  f->max_slice_count = f->num_h_slices * f->num_v_slices;
1324 
1325  if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1326  return err;
1327 
1328  if (f->version < 4) {
1329  if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1330  ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1331  av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1332  "dimensions is only supported in version 4 (-level 4)\n");
1333  return AVERROR_PATCHWELCOME;
1334  }
1335  }
1336 
1337  if (fv->force_pcm) {
1338  if (f->version < 4) {
1339  av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1340  return AVERROR_INVALIDDATA;
1341  } else if (f->ac == AC_GOLOMB_RICE) {
1342  av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1343  return AVERROR_INVALIDDATA;
1344  }
1345  }
1346 
1347  /* Init Vulkan */
1348  err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1349  if (err < 0)
1350  return err;
1351 
1352  fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1353  if (!fv->qf) {
1354  av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1355  return err;
1356  }
1357 
1358  /* Try to measure VRAM size */
1359  max_heap_size = 0;
1360  max_host_size = 0;
1361  for (int i = 0; i < fv->s.mprops.memoryHeapCount; i++) {
1362  if (fv->s.mprops.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
1363  max_heap_size = FFMAX(fv->max_heap_size,
1364  fv->s.mprops.memoryHeaps[i].size);
1365  if (!(fv->s.mprops.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT))
1366  max_host_size = FFMAX(max_host_size,
1367  fv->s.mprops.memoryHeaps[i].size);
1368  }
1369  fv->max_heap_size = max_heap_size;
1370 
1371  maxsize = ff_ffv1_encode_buffer_size(avctx);
1372  if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1373  av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1374  "than maximum device allocation (%zu), clipping\n",
1375  maxsize, fv->s.props_11.maxMemoryAllocationSize);
1376  maxsize = fv->s.props_11.maxMemoryAllocationSize;
1377  }
1378 
1379  if (max_heap_size < maxsize) {
1380  av_log(avctx, AV_LOG_WARNING, "Encoding buffer (%zu) larger than VRAM (%zu), "
1381  "using host memory (slower)\n",
1382  maxsize, fv->max_heap_size);
1383 
1384  /* Keep 1/2th of RAM as headroom */
1385  max_heap_size = max_host_size - (max_host_size >> 1);
1386  } else {
1387  /* Keep 1/8th of VRAM as headroom */
1388  max_heap_size = max_heap_size - (max_heap_size >> 3);
1389  }
1390 
1391  av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1392  maxsize / (1024*1024),
1393  (fv->async_depth * maxsize) / (1024*1024),
1394  fv->async_depth);
1395 
1396  err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1397  fv->async_depth,
1398  0, 0, 0, NULL);
1399  if (err < 0)
1400  return err;
1401 
1402  fv->transfer_qf = ff_vk_qf_find(&fv->s, VK_QUEUE_TRANSFER_BIT, 0);
1403  if (!fv->transfer_qf) {
1404  av_log(avctx, AV_LOG_ERROR, "Device has no transfer queues!\n");
1405  return err;
1406  }
1407 
1408  err = ff_vk_exec_pool_init(&fv->s, fv->transfer_qf, &fv->transfer_exec_pool,
1409  1,
1410  0, 0, 0, NULL);
1411  if (err < 0)
1412  return err;
1413 
1414  /* Detect the special RGB coding mode */
1415  fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1416  !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1417 
1418  fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1419  avctx->sw_pix_fmt == AV_PIX_FMT_GBRAPF32);
1420 
1421  if (fv->is_float32) {
1422  /* Compute the worst-case slice geometry. With version >= 4 the slice
1423  * boundaries are computed via slice_coord() which rounds up, so any
1424  * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1425  * pixels. */
1426  uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1427  uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1428  /* Round up to next pow2 for bitonic sort */
1429  uint32_t n = 1;
1430  uint32_t pn = mw*mh;
1431  while (n < pn)
1432  n <<= 1;
1433  if (n < 2)
1434  n = 2;
1435  fv->max_pixels_per_slice = n;
1436  }
1437 
1438  /* Init rct search shader */
1439  fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1440  !fv->force_pcm && fv->optimize_rct;
1441 
1442  /* Init shader specialization consts */
1443  SPEC_LIST_CREATE(sl, 19, 19*sizeof(uint32_t))
1444  SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1445  SPEC_LIST_ADD(sl, 1, 32, f->ec);
1446  ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1447  SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1448  SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1449  SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1450  SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1451 
1452  if (fv->optimize_rct) {
1453  err = init_rct_search_shader(avctx, sl);
1454  if (err < 0)
1455  return err;
1456  }
1457 
1458  if (f->remap_mode) {
1459  if (fv->is_float32)
1460  err = init_sort32_shader(avctx, sl);
1461  else
1462  err = init_remap_shader(avctx, sl);
1463  if (err < 0)
1464  return err;
1465  }
1466 
1467  /* Init setup shader */
1468  err = init_setup_shader(avctx, sl);
1469  if (err < 0)
1470  return err;
1471 
1472  /* Init reset shader */
1473  err = init_reset_shader(avctx, sl);
1474  if (err < 0)
1475  return err;
1476 
1477  if (fv->is_rgb)
1478  RET(init_indirect(avctx, fv->ctx.use32bit ?
1480 
1481  /* Encode shader */
1482  err = init_encode_shader(avctx, sl);
1483  if (err < 0)
1484  return err;
1485 
1486  /* Constant data */
1487  err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1488  if (err < 0)
1489  return err;
1490 
1491  /* Update setup global descriptors */
1493  &fv->setup, 0, 0, 0,
1494  &fv->consts_buf,
1495  256*sizeof(uint32_t), 512*sizeof(uint8_t),
1496  VK_FORMAT_UNDEFINED));
1497 
1498  /* Update encode global descriptors */
1500  &fv->enc, 0, 0, 0,
1501  &fv->consts_buf,
1502  256*sizeof(uint32_t), 512*sizeof(uint8_t),
1503  VK_FORMAT_UNDEFINED));
1505  &fv->enc, 0, 1, 0,
1506  &fv->consts_buf,
1507  256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1508  VK_WHOLE_SIZE,
1509  VK_FORMAT_UNDEFINED));
1511  &fv->enc, 0, 2, 0,
1512  &fv->consts_buf,
1513  0, 256*sizeof(uint32_t),
1514  VK_FORMAT_UNDEFINED));
1515 
1516  /* Temporary frame */
1517  fv->frame = av_frame_alloc();
1518  if (!fv->frame)
1519  return AVERROR(ENOMEM);
1520 
1521  /* Async data pool */
1522  fv->async_depth = fv->exec_pool.pool_size;
1523  fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1524  if (!fv->exec_ctx_info)
1525  return AVERROR(ENOMEM);
1526  for (int i = 0; i < fv->async_depth; i++)
1527  fv->exec_pool.contexts[i].opaque = &fv->exec_ctx_info[i];
1528 
1529  fv->buf_regions = av_malloc_array(f->max_slice_count, sizeof(*fv->buf_regions));
1530  if (!fv->buf_regions)
1531  return AVERROR(ENOMEM);
1532 
1533  /* Buffers */
1534  RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1535  fv->async_depth*f->max_slice_count*sizeof(uint32_t),
1536  NULL, NULL,
1537  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1538  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1539  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1540  RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1541 
1542 fail:
1543  return err;
1544 }
1545 
1547 {
1548  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1549 
1550  ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1552 
1553  ff_vk_shader_free(&fv->s, &fv->enc);
1554  ff_vk_shader_free(&fv->s, &fv->reset);
1555  ff_vk_shader_free(&fv->s, &fv->setup);
1556  ff_vk_shader_free(&fv->s, &fv->remap);
1557  ff_vk_shader_free(&fv->s, &fv->sort32);
1558  ff_vk_shader_free(&fv->s, &fv->rct_search);
1559 
1560  if (fv->exec_ctx_info) {
1561  for (int i = 0; i < fv->async_depth; i++) {
1565  }
1566  }
1567  av_free(fv->exec_ctx_info);
1568 
1570 
1572 
1576 
1577  ff_vk_free_buf(&fv->s, &fv->results_buf);
1578 
1579  ff_vk_free_buf(&fv->s, &fv->consts_buf);
1580 
1581  av_free(fv->buf_regions);
1582  av_frame_free(&fv->frame);
1583  ff_vk_uninit(&fv->s);
1584 
1585  return 0;
1586 }
1587 
1588 #define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1589 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1591  { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1592  { .i64 = -1 }, -1, 2, VE },
1593  { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1594  { .i64 = 0 }, 0, 1, VE },
1595  { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1596  { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1597  { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1598  { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1599  { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1600  { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1601  { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1602  { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1603  { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1604  { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1605  { "default", NULL, 0, AV_OPT_TYPE_CONST,
1606  { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1607  { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1608  { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1609  { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1610  { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1611 
1612  { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1613  { .i64 = -1 }, -1, MAX_SLICES, VE },
1614  { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1615  { .i64 = -1 }, -1, MAX_SLICES, VE },
1616 
1617  { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1618  { .i64 = 0 }, 0, 1, VE },
1619 
1620  { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1621  { .i64 = 1 }, 0, 1, VE },
1622 
1623  { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1624  { .i64 = 1 }, 1, INT_MAX, VE },
1625 
1626  { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1627  { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1628  { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1629  { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1630  { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1631  { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1632  { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1633  { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1634  { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1635  { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1636 
1637  { NULL }
1638 };
1639 
1641  { "g", "1" },
1642  { NULL },
1643 };
1644 
1646  .class_name = "ffv1_vulkan",
1647  .item_name = av_default_item_name,
1648  .option = vulkan_encode_ffv1_options,
1649  .version = LIBAVUTIL_VERSION_INT,
1650 };
1651 
1653  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1654  NULL,
1655 };
1656 
1658  .p.name = "ffv1_vulkan",
1659  CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1660  .p.type = AVMEDIA_TYPE_VIDEO,
1661  .p.id = AV_CODEC_ID_FFV1,
1662  .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1665  .close = &vulkan_encode_ffv1_close,
1666  .p.priv_class = &vulkan_encode_ffv1_class,
1667  .p.capabilities = AV_CODEC_CAP_DELAY |
1673  .defaults = vulkan_encode_ffv1_defaults,
1675  .hw_configs = vulkan_encode_ffv1_hw_configs,
1676  .p.wrapper_name = "vulkan",
1677 };
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:392
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
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2845
QTABLE_8BIT
@ QTABLE_8BIT
Definition: ffv1enc.h:30
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:130
RET
#define RET(x)
Definition: vulkan.h:68
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:104
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
int64_t
long long int64_t
Definition: coverity.c:34
VulkanEncodeFFv1Context::in_flight
int in_flight
Definition: ffv1enc_vulkan.c:69
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:459
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:108
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:184
AVOption
AVOption.
Definition: opt.h:429
encode.h
mh
#define mh
Definition: vf_colormatrix.c:105
VulkanEncodeFFv1Context::rct_search
FFVulkanShader rct_search
Definition: ffv1enc_vulkan.c:73
ff_source_ffv1_vlc_comp
const char * ff_source_ffv1_vlc_comp
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:2883
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:2871
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:703
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
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:1015
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:2822
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:658
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:126
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:84
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:687
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:1645
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:315
VulkanEncodeFFv1FrameData::key_frame
int key_frame
Definition: ffv1enc_vulkan.c:52
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:100
fail
#define fail()
Definition: checkasm.h:225
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:2773
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:220
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:2085
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:2638
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
VulkanEncodeFFv1Context::ppi
int ppi
Definition: ffv1enc_vulkan.c:107
ff_vk_host_map_buffer
int ff_vk_host_map_buffer(FFVulkanContext *s, AVBufferRef **dst, uint8_t *src_data, const AVBufferRef *src_buf, VkBufferUsageFlags usage)
Maps a system RAM buffer into a Vulkan buffer.
Definition: vulkan.c:1411
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:151
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:88
VulkanEncodeFFv1FrameData::frame_opaque_ref
AVBufferRef * frame_opaque_ref
Definition: ffv1enc_vulkan.c:50
AVRational::num
int num
Numerator.
Definition: rational.h:59
ff_ffv1_vulkan_encoder
const FFCodec ff_ffv1_vulkan_encoder
Definition: ffv1enc_vulkan.c:1657
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:60
VulkanEncodeFFv1FrameData
Definition: ffv1enc_vulkan.c:42
vulkan_encode_ffv1_hw_configs
const AVCodecHWConfigInternal *const vulkan_encode_ffv1_hw_configs[]
Definition: ffv1enc_vulkan.c:1652
get_packet
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:743
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:68
av_cold
#define av_cold
Definition: attributes.h:119
VulkanEncodeFFv1Context::setup
FFVulkanShader setup
Definition: ffv1enc_vulkan.c:76
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
FFV1Context::use32bit
int use32bit
Definition: ffv1.h:160
QTABLE_GT8BIT
@ QTABLE_GT8BIT
Definition: ffv1enc.h:31
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:144
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:71
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:273
vulkan_encode_ffv1_receive_packet
static int vulkan_encode_ffv1_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:835
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
VulkanEncodeFFv1Context::transfer_qf
AVVulkanDeviceQueueFamily * transfer_qf
Definition: ffv1enc_vulkan.c:64
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
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:332
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:58
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:76
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:153
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:1153
FFV1Context::num_v_slices
int num_v_slices
Definition: ffv1.h:176
VulkanEncodeFFv1Context::force_pcm
int force_pcm
Definition: ffv1enc_vulkan.c:101
VulkanEncodeFFv1Context::consts_buf
FFVkBuffer consts_buf
Definition: ffv1enc_vulkan.c:81
VulkanEncodeFFv1FrameData::idx
int idx
Definition: ffv1enc_vulkan.c:53
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:367
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:2411
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:240
SPEC_LIST_CREATE
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition: vulkan.h:76
transfer_slices
static int transfer_slices(AVCodecContext *avctx, VkBufferCopy *buf_regions, int nb_regions, VulkanEncodeFFv1FrameData *fd, uint8_t *dst, AVBufferRef *dst_ref)
Definition: ffv1enc_vulkan.c:678
ff_ffv1_enc_rgb_golomb_comp_spv_data
const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[]
ffv1_vulkan.h
VulkanEncodeFFv1Context::num_h_slices
int num_h_slices
Definition: ffv1enc_vulkan.c:99
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:134
FFVulkanContext
Definition: vulkan.h:312
VulkanEncodeFFv1FrameData::duration
int64_t duration
Definition: ffv1enc_vulkan.c:48
VulkanEncodeFFv1Context
Definition: ffv1enc_vulkan.c:56
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
f
f
Definition: af_crystalizer.c:122
VulkanEncodeFFv1Context::slice_data_pool
AVBufferPool * slice_data_pool
Definition: ffv1enc_vulkan.c:87
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:52
VulkanEncodeFFv1Context::ctx
FFV1Context ctx
Definition: ffv1enc_vulkan.c:57
AVVkFrame::access
VkAccessFlagBits access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
Definition: hwcontext_vulkan.h:339
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:2812
AVPacket::size
int size
Definition: packet.h:604
FFVulkanDescriptorSetBinding
Definition: vulkan.h:112
VulkanEncodeFFv1FrameData::pts
int64_t pts
Definition: ffv1enc_vulkan.c:47
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
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
AVVkFrame
Definition: hwcontext_vulkan.h:310
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
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:460
init_indirect
static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
Definition: ffv1enc_vulkan.c:889
FFVulkanShader
Definition: vulkan.h:225
VulkanEncodeFFv1Context::optimize_rct
int optimize_rct
Definition: ffv1enc_vulkan.c:102
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:2786
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
VulkanEncodeFFv1Context::sort32
FFVulkanShader sort32
Definition: ffv1enc_vulkan.c:75
ff_ffv1_enc_rct_search_comp_spv_data
const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[]
VulkanEncodeFFv1Context::enc
FFVulkanShader enc
Definition: ffv1enc_vulkan.c:78
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:1589
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_VK_EXT_EXTERNAL_HOST_MEMORY
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY
Definition: vulkan_functions.h:36
ff_source_ffv1_enc_comp
const char * ff_source_ffv1_enc_comp
VulkanEncodeFFv1Context::remap_data_pool
AVBufferPool * remap_data_pool
Definition: ffv1enc_vulkan.c:91
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:580
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
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_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
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
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
vulkan_encode_ffv1_close
static av_cold int vulkan_encode_ffv1_close(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1546
FFVulkanContext::props
VkPhysicalDeviceProperties2 props
Definition: vulkan.h:318
FFVulkanContext::extensions
FFVulkanExtensions extensions
Definition: vulkan.h:317
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition: vulkan.c:1264
QTABLE_DEFAULT
@ QTABLE_DEFAULT
Definition: ffv1enc.h:29
AVCodecContext::height
int height
Definition: avcodec.h:604
init_setup_shader
static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1062
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:682
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
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:1858
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
ff_vk_create_imageviews
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
Definition: vulkan.c:2002
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:316
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:62
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:97
VulkanEncodeFFv1FrameData::frame_opaque
void * frame_opaque
Definition: ffv1enc_vulkan.c:49
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:556
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:1590
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:156
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:2538
VulkanEncodeFFv1Context::transfer_exec_pool
FFVkExecPool transfer_exec_pool
Definition: ffv1enc_vulkan.c:65
init_reset_shader
static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:1104
RGB_LINECACHE
#define RGB_LINECACHE
Definition: ffv1enc_vulkan.c:40
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:105
VulkanEncodeFFv1Context::reset
FFVulkanShader reset
Definition: ffv1enc_vulkan.c:77
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:215
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:579
VulkanEncodeFFv1Context::async_depth
int async_depth
Definition: ffv1enc_vulkan.c:70
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:76
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:246
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:229
VulkanEncodeFFv1Context::qf
AVVulkanDeviceQueueFamily * qf
Definition: ffv1enc_vulkan.c:61
vulkan_encode_ffv1_defaults
static const FFCodecDefault vulkan_encode_ffv1_defaults[]
Definition: ffv1enc_vulkan.c:1640
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
VulkanEncodeFFv1Context::buf_regions
VkBufferCopy * buf_regions
Definition: ffv1enc_vulkan.c:67
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:340
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:105
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:327
VulkanEncodeFFv1Context::max_pixels_per_slice
uint32_t max_pixels_per_slice
Definition: ffv1enc_vulkan.c:106
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:1248
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:1588
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:74
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:299
init_sort32_shader
static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
Definition: ffv1enc_vulkan.c:967
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:2128
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:924
VulkanEncodeFFv1Context::out_data_pool
AVBufferPool * out_data_pool
Definition: ffv1enc_vulkan.c:94
ff_source_rangecoder_comp
const char * ff_source_rangecoder_comp