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