FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 #include "libavutil/vulkan_spirv.h"
24 
25 #include "avcodec.h"
26 #include "internal.h"
27 #include "hwconfig.h"
28 #include "encode.h"
29 #include "libavutil/opt.h"
30 #include "codec_internal.h"
31 
32 #include "ffv1.h"
33 #include "ffv1enc.h"
34 #include "ffv1_vulkan.h"
35 
36 /* Parallel Golomb alignment */
37 #define LG_ALIGN_W 32
38 #define LG_ALIGN_H 32
39 
40 typedef struct VulkanEncodeFFv1FrameData {
41  /* Output data */
43 
44  /* Results data */
46 
47  /* Copied from the source */
50  void *frame_opaque;
52 
53  int key_frame;
55 
56 typedef struct VulkanEncodeFFv1Context {
59 
63 
66 
67  VkBufferCopy *buf_regions;
69  int in_flight;
71  size_t max_heap_size;
72 
77 
78  /* Constant read-only buffers */
82 
83  /* Slice data buffer pool */
86 
87  /* Output data buffer */
90 
91  /* Temporary data buffer */
93 
94  /* Slice results buffer */
96 
97  /* Intermediate frame pool */
99 
100  /* Representation mode */
102 
106 
107  int is_rgb;
108  int ppi;
109  int chunks;
111 
112 extern const char *ff_source_common_comp;
113 extern const char *ff_source_rangecoder_comp;
114 extern const char *ff_source_ffv1_vlc_comp;
115 extern const char *ff_source_ffv1_common_comp;
116 extern const char *ff_source_ffv1_reset_comp;
117 extern const char *ff_source_ffv1_enc_common_comp;
118 extern const char *ff_source_ffv1_enc_rct_comp;
119 extern const char *ff_source_ffv1_enc_vlc_comp;
120 extern const char *ff_source_ffv1_enc_ac_comp;
121 extern const char *ff_source_ffv1_enc_setup_comp;
122 extern const char *ff_source_ffv1_enc_comp;
123 extern const char *ff_source_ffv1_enc_rgb_comp;
124 
125 typedef struct FFv1VkParameters {
126  VkDeviceAddress slice_state;
127  VkDeviceAddress scratch_data;
128  VkDeviceAddress out_data;
129 
131  uint32_t chroma_shift[2];
132 
134  uint32_t context_count;
135  uint32_t crcref;
136  uint32_t slice_size_max;
137 
139  uint8_t context_model;
140  uint8_t version;
141  uint8_t micro_version;
142  uint8_t force_pcm;
143  uint8_t key_frame;
144  uint8_t planes;
145  uint8_t codec_planes;
146  uint8_t transparency;
147  uint8_t colorspace;
148  uint8_t pic_mode;
149  uint8_t ec;
150  uint8_t ppi;
151  uint8_t chunks;
152  uint8_t padding[2];
154 
155 static void add_push_data(FFVulkanShader *shd)
156 {
157  GLSLC(0, layout(push_constant, scalar) uniform pushConstants { );
158  GLSLC(1, u8buf slice_state; );
159  GLSLC(1, u8buf scratch_data; );
160  GLSLC(1, u8buf out_data; );
161  GLSLC(0, );
162  GLSLC(1, ivec2 sar; );
163  GLSLC(1, uvec2 chroma_shift; );
164  GLSLC(0, );
165  GLSLC(1, uint plane_state_size; );
166  GLSLC(1, uint context_count; );
167  GLSLC(1, uint32_t crcref; );
168  GLSLC(1, uint32_t slice_size_max; );
169  GLSLC(0, );
170  GLSLC(1, uint8_t bits_per_raw_sample; );
171  GLSLC(1, uint8_t context_model; );
172  GLSLC(1, uint8_t version; );
173  GLSLC(1, uint8_t micro_version; );
174  GLSLC(1, uint8_t force_pcm; );
175  GLSLC(1, uint8_t key_frame; );
176  GLSLC(1, uint8_t planes; );
177  GLSLC(1, uint8_t codec_planes; );
178  GLSLC(1, uint8_t transparency; );
179  GLSLC(1, uint8_t colorspace; );
180  GLSLC(1, uint8_t pic_mode; );
181  GLSLC(1, uint8_t ec; );
182  GLSLC(1, uint8_t ppi; );
183  GLSLC(1, uint8_t chunks; );
184  GLSLC(1, uint8_t padding[2]; );
185  GLSLC(0, }; );
187  VK_SHADER_STAGE_COMPUTE_BIT);
188 }
189 
190 static int run_rct(AVCodecContext *avctx, FFVkExecContext *exec,
191  AVFrame *enc_in, VkImageView *enc_in_views,
192  AVFrame **intermediate_frame, VkImageView *intermediate_views,
193  VkImageMemoryBarrier2 *img_bar, int *nb_img_bar,
194  VkBufferMemoryBarrier2 *buf_bar, int *nb_buf_bar,
195  FFVkBuffer *slice_data_buf, uint32_t slice_data_size)
196 {
197  int err;
198  VulkanEncodeFFv1Context *fv = avctx->priv_data;
199  FFV1Context *f = &fv->ctx;
200  FFVulkanFunctions *vk = &fv->s.vkfn;
201  AVHWFramesContext *src_hwfc = (AVHWFramesContext *)enc_in->hw_frames_ctx->data;
203 
204  /* Create a temporaty frame */
205  *intermediate_frame = av_frame_alloc();
206  if (!(*intermediate_frame))
207  return AVERROR(ENOMEM);
208 
210  *intermediate_frame, 0));
211 
212  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, *intermediate_frame,
213  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
214  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
215  RET(ff_vk_create_imageviews(&fv->s, exec, intermediate_views,
216  *intermediate_frame,
217  fv->rep_fmt));
218 
219  /* Update descriptors */
220  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->rct,
221  1, 0, 0,
222  slice_data_buf,
223  0, slice_data_size*f->slice_count,
224  VK_FORMAT_UNDEFINED);
225  ff_vk_shader_update_img_array(&fv->s, exec, &fv->rct,
226  enc_in, enc_in_views,
227  1, 1,
228  VK_IMAGE_LAYOUT_GENERAL,
229  VK_NULL_HANDLE);
230  ff_vk_shader_update_img_array(&fv->s, exec, &fv->rct,
231  *intermediate_frame, intermediate_views,
232  1, 2,
233  VK_IMAGE_LAYOUT_GENERAL,
234  VK_NULL_HANDLE);
235 
236  ff_vk_frame_barrier(&fv->s, exec, *intermediate_frame, img_bar, nb_img_bar,
237  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
238  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
239  VK_ACCESS_SHADER_WRITE_BIT,
240  VK_IMAGE_LAYOUT_GENERAL,
241  VK_QUEUE_FAMILY_IGNORED);
242 
243  /* Prep the input/output images */
244  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
245  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
246  .pImageMemoryBarriers = img_bar,
247  .imageMemoryBarrierCount = *nb_img_bar,
248  .pBufferMemoryBarriers = buf_bar,
249  .bufferMemoryBarrierCount = *nb_buf_bar,
250  });
251  *nb_img_bar = 0;
252  if (*nb_buf_bar) {
253  slice_data_buf->stage = buf_bar[0].dstStageMask;
254  slice_data_buf->access = buf_bar[0].dstAccessMask;
255  *nb_buf_bar = 0;
256  }
257 
258  /* Run the shader */
259  ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct);
260  pd = (FFv1VkRCTParameters) {
261  .offset = 1 << f->bits_per_raw_sample,
262  .bits = f->bits_per_raw_sample,
263  .planar_rgb = ff_vk_mt_is_np_rgb(src_hwfc->sw_format) &&
264  (ff_vk_count_images((AVVkFrame *)enc_in->data[0]) > 1),
265  .transparency = f->transparency,
266  };
267 
268  /* For some reason the C FFv1 encoder/decoder treats these differently */
269  if (src_hwfc->sw_format == AV_PIX_FMT_GBRP10 ||
270  src_hwfc->sw_format == AV_PIX_FMT_GBRP12 ||
271  src_hwfc->sw_format == AV_PIX_FMT_GBRP14)
272  memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
273  else
274  ff_vk_set_perm(src_hwfc->sw_format, pd.fmt_lut, 1);
275 
276  ff_vk_shader_update_push_const(&fv->s, exec, &fv->rct,
277  VK_SHADER_STAGE_COMPUTE_BIT,
278  0, sizeof(pd), &pd);
279 
280  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
281 
282  /* Add a post-dispatch barrier before encoding */
283  ff_vk_frame_barrier(&fv->s, exec, *intermediate_frame, img_bar, nb_img_bar,
284  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
285  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
286  VK_ACCESS_SHADER_READ_BIT,
287  VK_IMAGE_LAYOUT_GENERAL,
288  VK_QUEUE_FAMILY_IGNORED);
289 
290 fail:
291  return err;
292 }
293 
295  FFVkExecContext *exec,
296  const AVFrame *pict)
297 {
298  int err;
299  VulkanEncodeFFv1Context *fv = avctx->priv_data;
300  FFV1Context *f = &fv->ctx;
301  FFVulkanFunctions *vk = &fv->s.vkfn;
302 
303  VulkanEncodeFFv1FrameData *fd = exec->opaque;
304  FFv1VkParameters pd;
305 
306  AVFrame *intermediate_frame = NULL;
307 
308  /* Temporary data */
309  size_t tmp_data_size;
310  AVBufferRef *tmp_data_ref;
311  FFVkBuffer *tmp_data_buf;
312 
313  /* Slice data */
314  AVBufferRef *slice_data_ref;
315  FFVkBuffer *slice_data_buf;
316  uint32_t plane_state_size;
317  uint32_t slice_state_size;
318  uint32_t slice_data_size;
319 
320  /* Output data */
321  size_t maxsize;
322  FFVkBuffer *out_data_buf;
323 
324  /* Results data */
325  FFVkBuffer *results_data_buf;
326 
327  int has_inter = avctx->gop_size > 1;
328  uint32_t context_count = f->context_count[f->context_model];
329 
330  VkImageView in_views[AV_NUM_DATA_POINTERS];
331  VkImageView intermediate_views[AV_NUM_DATA_POINTERS];
332 
333  AVFrame *enc_in = (AVFrame *)pict;
334  VkImageView *enc_in_views = in_views;
335 
336  VkImageMemoryBarrier2 img_bar[37];
337  int nb_img_bar = 0;
338  VkBufferMemoryBarrier2 buf_bar[8];
339  int nb_buf_bar = 0;
340 
341  /* Start recording */
342  ff_vk_exec_start(&fv->s, exec);
343 
344  /* Frame state */
345  f->cur_enc_frame = pict;
346  if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
348  f->key_frame = fd->key_frame = 1;
349  f->gob_count++;
350  } else {
351  f->key_frame = fd->key_frame = 0;
352  }
353 
354  f->slice_count = f->max_slice_count;
355 
356  /* Allocate temporary data buffer */
357  tmp_data_size = f->slice_count*CONTEXT_SIZE;
359  &tmp_data_ref,
360  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
361  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
362  NULL, tmp_data_size,
363  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
364  tmp_data_buf = (FFVkBuffer *)tmp_data_ref->data;
365  ff_vk_exec_add_dep_buf(&fv->s, exec, &tmp_data_ref, 1, 0);
366 
367  /* Allocate slice buffer data */
368  if (f->ac == AC_GOLOMB_RICE)
369  plane_state_size = 8;
370  else
371  plane_state_size = CONTEXT_SIZE;
372 
373  plane_state_size *= context_count;
374  slice_state_size = plane_state_size*f->plane_count;
375 
376  slice_data_size = 256; /* Overestimation for the SliceContext struct */
377  slice_state_size += slice_data_size;
378  slice_state_size = FFALIGN(slice_state_size, 8);
379 
380  /* Allocate slice data buffer */
381  slice_data_ref = fv->keyframe_slice_data_ref;
382  if (!slice_data_ref) {
384  &slice_data_ref,
385  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
386  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
387  NULL, slice_state_size*f->slice_count,
388  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
389 
390  /* Only save it if we're going to use it again */
391  if (has_inter)
392  fv->keyframe_slice_data_ref = slice_data_ref;
393  }
394  slice_data_buf = (FFVkBuffer *)slice_data_ref->data;
395  ff_vk_exec_add_dep_buf(&fv->s, exec, &slice_data_ref, 1, has_inter);
396 
397  /* Allocate results buffer */
399  &fd->results_data_ref,
400  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
401  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
402  NULL, 2*f->slice_count*sizeof(uint64_t),
403  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
404  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
405  results_data_buf = (FFVkBuffer *)fd->results_data_ref->data;
406  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->results_data_ref, 1, 1);
407 
408  /* Output buffer size */
409  maxsize = ff_ffv1_encode_buffer_size(avctx);
410  maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
411 
412  /* Allocate output buffer */
414  &fd->out_data_ref,
415  VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
416  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
417  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
418  NULL, maxsize,
419  maxsize < fv->max_heap_size ?
420  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0));
421  out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
422  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->out_data_ref, 1, 1);
423 
424  /* Prepare input frame */
425  RET(ff_vk_exec_add_dep_frame(&fv->s, exec, enc_in,
426  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
427  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
428 
429  RET(ff_vk_create_imageviews(&fv->s, exec, enc_in_views, enc_in,
430  fv->rep_fmt));
431  ff_vk_frame_barrier(&fv->s, exec, enc_in, img_bar, &nb_img_bar,
432  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
433  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
434  VK_ACCESS_SHADER_READ_BIT,
435  VK_IMAGE_LAYOUT_GENERAL,
436  VK_QUEUE_FAMILY_IGNORED);
437 
438  /* Setup shader needs the original input */
439  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
440  1, 0, 0,
441  slice_data_buf,
442  0, slice_data_size*f->slice_count,
443  VK_FORMAT_UNDEFINED);
444  ff_vk_shader_update_img_array(&fv->s, exec, &fv->setup,
445  enc_in, enc_in_views,
446  1, 1,
447  VK_IMAGE_LAYOUT_GENERAL,
448  VK_NULL_HANDLE);
449 
450  /* Add a buffer barrier between previous and current frame */
451  if (!f->key_frame) {
452  buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
453  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
454  .srcStageMask = slice_data_buf->stage,
455  .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
456  .srcAccessMask = slice_data_buf->access,
457  .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
458  VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
459  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
460  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
461  .buffer = slice_data_buf->buf,
462  .size = VK_WHOLE_SIZE,
463  .offset = 0,
464  };
465  }
466 
467  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
468  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
469  .pImageMemoryBarriers = img_bar,
470  .imageMemoryBarrierCount = nb_img_bar,
471  .pBufferMemoryBarriers = buf_bar,
472  .bufferMemoryBarrierCount = nb_buf_bar,
473  });
474  nb_img_bar = 0;
475  if (nb_buf_bar) {
476  slice_data_buf->stage = buf_bar[0].dstStageMask;
477  slice_data_buf->access = buf_bar[0].dstAccessMask;
478  nb_buf_bar = 0;
479  }
480 
481  /* Run setup shader */
482  ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
483  pd = (FFv1VkParameters) {
484  .slice_state = slice_data_buf->address + f->slice_count*256,
485  .scratch_data = tmp_data_buf->address,
486  .out_data = out_data_buf->address,
487  .bits_per_raw_sample = f->bits_per_raw_sample,
488  .sar[0] = pict->sample_aspect_ratio.num,
489  .sar[1] = pict->sample_aspect_ratio.den,
490  .chroma_shift[0] = f->chroma_h_shift,
491  .chroma_shift[1] = f->chroma_v_shift,
492  .plane_state_size = plane_state_size,
493  .context_count = context_count,
494  .crcref = f->crcref,
495  .slice_size_max = out_data_buf->size / f->slice_count,
496  .context_model = fv->ctx.context_model,
497  .version = f->version,
498  .micro_version = f->micro_version,
499  .force_pcm = fv->force_pcm,
500  .key_frame = f->key_frame,
501  .planes = av_pix_fmt_count_planes(avctx->sw_pix_fmt),
502  .codec_planes = f->plane_count,
503  .transparency = f->transparency,
504  .colorspace = f->colorspace,
505  .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
506  !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
507  .ec = f->ec,
508  .ppi = fv->ppi,
509  .chunks = fv->chunks,
510  };
511  ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
512  VK_SHADER_STAGE_COMPUTE_BIT,
513  0, sizeof(pd), &pd);
514  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
515 
516  /* Setup shader modified the slice data buffer */
517  buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
518  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
519  .srcStageMask = slice_data_buf->stage,
520  .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
521  .srcAccessMask = slice_data_buf->access,
522  .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
523  VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
524  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
525  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
526  .buffer = slice_data_buf->buf,
527  .size = slice_data_size*f->slice_count,
528  .offset = 0,
529  };
530 
531  if (f->key_frame || f->version > 3) {
532  FFv1VkResetParameters pd_reset;
533 
534  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
535  1, 0, 0,
536  slice_data_buf,
537  0, slice_data_size*f->slice_count,
538  VK_FORMAT_UNDEFINED);
539 
540  /* Run setup shader */
541  ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
542  pd_reset = (FFv1VkResetParameters) {
543  .slice_state = slice_data_buf->address + f->slice_count*256,
544  .plane_state_size = plane_state_size,
545  .codec_planes = f->plane_count,
546  .key_frame = f->key_frame,
547  };
548  for (int i = 0; i < f->quant_table_count; i++)
549  pd_reset.context_count[i] = f->context_count[i];
550 
551  ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
552  VK_SHADER_STAGE_COMPUTE_BIT,
553  0, sizeof(pd_reset), &pd_reset);
554 
555  /* Sync between setup and reset shaders */
556  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
557  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
558  .pBufferMemoryBarriers = buf_bar,
559  .bufferMemoryBarrierCount = nb_buf_bar,
560  });
561  slice_data_buf->stage = buf_bar[0].dstStageMask;
562  slice_data_buf->access = buf_bar[0].dstAccessMask;
563  nb_buf_bar = 0;
564 
565  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
566  f->plane_count);
567  }
568 
569  /* Run RCT shader */
570  if (fv->is_rgb) {
571  RET(run_rct(avctx, exec,
572  enc_in, enc_in_views,
573  &intermediate_frame, intermediate_views,
574  img_bar, &nb_img_bar, buf_bar, &nb_buf_bar,
575  slice_data_buf, slice_data_size));
576 
577  /* Use the new frame */
578  enc_in = intermediate_frame;
579  enc_in_views = intermediate_views;
580  }
581 
582  /* If the reset shader ran, insert a barrier now. */
583  if (f->key_frame || f->version > 3) {
584  /* Reset shader modified the slice data buffer */
585  buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
586  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
587  .srcStageMask = slice_data_buf->stage,
588  .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
589  .srcAccessMask = slice_data_buf->access,
590  .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
591  VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
592  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
593  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
594  .buffer = slice_data_buf->buf,
595  .size = slice_data_buf->size - slice_data_size*f->slice_count,
596  .offset = slice_data_size*f->slice_count,
597  };
598  }
599 
600  /* Final barrier before encoding */
601  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
602  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
603  .pImageMemoryBarriers = img_bar,
604  .imageMemoryBarrierCount = nb_img_bar,
605  .pBufferMemoryBarriers = buf_bar,
606  .bufferMemoryBarrierCount = nb_buf_bar,
607  });
608  nb_img_bar = 0;
609  if (nb_buf_bar) {
610  slice_data_buf->stage = buf_bar[0].dstStageMask;
611  slice_data_buf->access = buf_bar[0].dstAccessMask;
612  nb_buf_bar = 0;
613  }
614 
615  /* Main encode shader */
616  ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
617  1, 0, 0,
618  slice_data_buf,
619  0, slice_data_size*f->slice_count,
620  VK_FORMAT_UNDEFINED);
621  ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
622  enc_in, enc_in_views,
623  1, 1,
624  VK_IMAGE_LAYOUT_GENERAL,
625  VK_NULL_HANDLE);
627  &fv->enc, 1, 2, 0,
628  results_data_buf,
629  0, results_data_buf->size,
630  VK_FORMAT_UNDEFINED);
631 
632  ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
633  ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
634  VK_SHADER_STAGE_COMPUTE_BIT,
635  0, sizeof(pd), &pd);
636  vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
637 
638  /* Submit */
639  err = ff_vk_exec_submit(&fv->s, exec);
640  if (err < 0)
641  return err;
642 
643  f->picture_number++;
644 
645  /* This, if needed, was referenced by the execution context
646  * as it was declared as a dependency. */
647  av_frame_free(&intermediate_frame);
648  return 0;
649 
650 fail:
651  av_frame_free(&intermediate_frame);
652  ff_vk_exec_discard_deps(&fv->s, exec);
653 
654  return err;
655 }
656 
657 static int download_slices(AVCodecContext *avctx,
658  VkBufferCopy *buf_regions, int nb_regions,
660  AVBufferRef *pkt_data_ref)
661 {
662  int err;
663  VulkanEncodeFFv1Context *fv = avctx->priv_data;
664  FFVulkanFunctions *vk = &fv->s.vkfn;
665  FFVkExecContext *exec;
666 
667  FFVkBuffer *out_data_buf = (FFVkBuffer *)fd->out_data_ref->data;
668  FFVkBuffer *pkt_data_buf = (FFVkBuffer *)pkt_data_ref->data;
669 
670  VkBufferMemoryBarrier2 buf_bar[8];
671  int nb_buf_bar = 0;
672 
673  /* Transfer the slices */
674  exec = ff_vk_exec_get(&fv->s, &fv->transfer_exec_pool);
675  ff_vk_exec_start(&fv->s, exec);
676 
677  ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->out_data_ref, 1, 0);
678  fd->out_data_ref = NULL; /* Ownership passed */
679 
680  ff_vk_exec_add_dep_buf(&fv->s, exec, &pkt_data_ref, 1, 1);
681 
682  /* Ensure the output buffer is finished */
683  buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
684  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
685  .srcStageMask = out_data_buf->stage,
686  .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
687  .srcAccessMask = out_data_buf->access,
688  .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
689  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
690  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
691  .buffer = out_data_buf->buf,
692  .size = VK_WHOLE_SIZE,
693  .offset = 0,
694  };
695  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
696  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
697  .pBufferMemoryBarriers = buf_bar,
698  .bufferMemoryBarrierCount = nb_buf_bar,
699  });
700  out_data_buf->stage = buf_bar[0].dstStageMask;
701  out_data_buf->access = buf_bar[0].dstAccessMask;
702  nb_buf_bar = 0;
703 
704  vk->CmdCopyBuffer(exec->buf,
705  out_data_buf->buf, pkt_data_buf->buf,
706  nb_regions, buf_regions);
707 
708  /* Submit */
709  err = ff_vk_exec_submit(&fv->s, exec);
710  if (err < 0)
711  return err;
712 
713  /* We need the encoded data immediately */
714  ff_vk_exec_wait(&fv->s, exec);
715 
716  /* Invalidate slice/output data if needed */
717  if (!(pkt_data_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
718  VkMappedMemoryRange invalidate_data = {
719  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
720  .memory = pkt_data_buf->mem,
721  .offset = 0,
722  .size = VK_WHOLE_SIZE,
723  };
724  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
725  1, &invalidate_data);
726  }
727 
728  return 0;
729 }
730 
731 static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec,
732  AVPacket *pkt)
733 {
734  int err;
735  VulkanEncodeFFv1Context *fv = avctx->priv_data;
736  FFV1Context *f = &fv->ctx;
737  FFVulkanFunctions *vk = &fv->s.vkfn;
738 
739  /* Packet data */
740  AVBufferRef *pkt_data_ref;
741  FFVkBuffer *pkt_data_buf;
742 
743  VulkanEncodeFFv1FrameData *fd = exec->opaque;
744 
745  FFVkBuffer *results_data_buf = (FFVkBuffer *)fd->results_data_ref->data;
746  uint64_t *sc;
747 
748  /* Make sure encoding's done */
749  ff_vk_exec_wait(&fv->s, exec);
750 
751  /* Invalidate slice/output data if needed */
752  if (!(results_data_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
753  VkMappedMemoryRange invalidate_data = {
754  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
755  .memory = results_data_buf->mem,
756  .offset = 0,
757  .size = VK_WHOLE_SIZE,
758  };
759  vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
760  1, &invalidate_data);
761  }
762 
763  /* Calculate final size */
764  pkt->size = 0;
765  for (int i = 0; i < f->slice_count; i++) {
766  sc = &((uint64_t *)results_data_buf->mapped_mem)[i*2];
767  av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %"PRIu64", "
768  "src offset = %"PRIu64"\n",
769  i, sc[0], sc[1]);
770 
771  fv->buf_regions[i] = (VkBufferCopy) {
772  .srcOffset = sc[1],
773  .dstOffset = pkt->size,
774  .size = sc[0],
775  };
776  pkt->size += sc[0];
777  }
778  av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
779  av_buffer_unref(&fd->results_data_ref); /* No need for this buffer anymore */
780 
781  /* Allocate packet buffer */
782  err = ff_vk_get_pooled_buffer(&fv->s, &fv->pkt_data_pool,
783  &pkt_data_ref,
784  VK_BUFFER_USAGE_TRANSFER_DST_BIT,
785  NULL, pkt->size,
786  VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
787  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
788  if (err < 0)
789  return err;
790  pkt_data_buf = (FFVkBuffer *)pkt_data_ref->data;
791 
792  /* Setup packet data */
793  pkt->data = pkt_data_buf->mapped_mem;
794  pkt->buf = pkt_data_ref;
795 
796  pkt->pts = fd->pts;
797  pkt->dts = fd->pts;
798  pkt->duration = fd->duration;
800 
801  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
802  pkt->opaque = fd->frame_opaque;
804  fd->frame_opaque_ref = NULL;
805  }
806 
807  return download_slices(avctx, fv->buf_regions, f->slice_count, fd,
808  pkt_data_ref);
809 }
810 
812  AVPacket *pkt)
813 {
814  int err;
815  VulkanEncodeFFv1Context *fv = avctx->priv_data;
817  FFVkExecContext *exec;
818  AVFrame *frame;
819 
820  while (1) {
821  /* Roll an execution context */
822  exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
823 
824  /* If it had a frame, immediately output it */
825  if (exec->had_submission) {
826  exec->had_submission = 0;
827  fv->in_flight--;
828  return get_packet(avctx, exec, pkt);
829  }
830 
831  /* Get next frame to encode */
832  frame = fv->frame;
833  err = ff_encode_get_frame(avctx, frame);
834  if (err < 0 && err != AVERROR_EOF) {
835  return err;
836  } else if (err == AVERROR_EOF) {
837  if (!fv->in_flight)
838  return err;
839  continue;
840  }
841 
842  /* Encode frame */
843  fd = exec->opaque;
844  fd->pts = frame->pts;
845  fd->duration = frame->duration;
846  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
847  fd->frame_opaque = frame->opaque;
848  fd->frame_opaque_ref = frame->opaque_ref;
849  frame->opaque_ref = NULL;
850  }
851 
852  err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
854  if (err < 0)
855  return err;
856 
857  fv->in_flight++;
858  if (fv->in_flight < fv->async_depth)
859  return AVERROR(EAGAIN);
860  }
861 
862  return 0;
863 }
864 
865 static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
866 {
867  int err;
868  VulkanEncodeFFv1Context *fv = avctx->priv_data;
869  AVHWFramesContext *frames_ctx;
870  AVVulkanFramesContext *vk_frames;
871 
873  if (!fv->intermediate_frames_ref)
874  return AVERROR(ENOMEM);
875 
876  frames_ctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data;
877  frames_ctx->format = AV_PIX_FMT_VULKAN;
878  frames_ctx->sw_format = sw_format;
879  frames_ctx->width = FFALIGN(fv->s.frames->width, 32);
880  frames_ctx->height = FFALIGN(fv->s.frames->height, 32);
881 
882  vk_frames = frames_ctx->hwctx;
883  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
884  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT;
885  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
886 
888  if (err < 0) {
889  av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
890  av_get_pix_fmt_name(sw_format), av_err2str(err));
892  return err;
893  }
894 
895  return 0;
896 }
897 
898 static int check_support(AVHWFramesConstraints *constraints,
899  enum AVPixelFormat fmt)
900 {
901  for (int i = 0; constraints->valid_sw_formats[i]; i++) {
902  if (constraints->valid_sw_formats[i] == fmt)
903  return 1;
904  }
905  return 0;
906 }
907 
909 {
910  VulkanEncodeFFv1Context *fv = avctx->priv_data;
911 
912  enum AVPixelFormat fmt;
913  AVHWFramesConstraints *constraints;
915  NULL);
916 
917  /* What we'd like to optimally have */
918  fmt = fv->ctx.use32bit ?
921  if (check_support(constraints, fmt))
922  goto end;
923 
924  if (fv->ctx.use32bit) {
925  if (check_support(constraints, (fmt = AV_PIX_FMT_RGBA128)))
926  goto end;
927  } else {
928  if (check_support(constraints, (fmt = AV_PIX_FMT_RGBA64)))
929  goto end;
930 
931  if (!fv->ctx.transparency &&
932  check_support(constraints, (fmt = AV_PIX_FMT_RGB96)))
933  goto end;
934 
935  if (check_support(constraints, (fmt = AV_PIX_FMT_RGBA128)))
936  goto end;
937  }
938 
939  fmt = AV_PIX_FMT_NONE;
940 
941 end:
942  av_hwframe_constraints_free(&constraints);
943  return fmt;
944 }
945 
947 {
948  VulkanEncodeFFv1Context *fv = avctx->priv_data;
949  FFV1Context *f = &fv->ctx;
950  int smp_bits = fv->ctx.use32bit ? 32 : 16;
951 
952  av_bprintf(&shd->src, "#define CONTEXT_SIZE %i\n" ,CONTEXT_SIZE);
953  av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_MASK 0x%x\n" ,MAX_QUANT_TABLE_MASK);
954 
955  if (f->ac == AC_GOLOMB_RICE) {
956  av_bprintf(&shd->src, "#define PB_UNALIGNED\n" );
957  av_bprintf(&shd->src, "#define GOLOMB\n" );
958  }
959 
960  GLSLF(0, #define TYPE int%i_t ,smp_bits);
961  GLSLF(0, #define VTYPE2 i%ivec2 ,smp_bits);
962  GLSLF(0, #define VTYPE3 i%ivec3 ,smp_bits);
964 
965  if (f->ac == AC_GOLOMB_RICE)
967 
969 }
970 
972 {
973  int err;
974  VulkanEncodeFFv1Context *fv = avctx->priv_data;
975  FFVulkanShader *shd = &fv->setup;
977 
978  uint8_t *spv_data;
979  size_t spv_len;
980  void *spv_opaque = NULL;
981 
982  RET(ff_vk_shader_init(&fv->s, shd, "ffv1_setup",
983  VK_SHADER_STAGE_COMPUTE_BIT,
984  (const char *[]) { "GL_EXT_buffer_reference",
985  "GL_EXT_buffer_reference2" }, 2,
986  1, 1, 1,
987  0));
988 
989  /* Common codec header */
991  add_push_data(shd);
992 
993  av_bprintf(&shd->src, "#define MAX_QUANT_TABLES %i\n", MAX_QUANT_TABLES);
994  av_bprintf(&shd->src, "#define MAX_CONTEXT_INPUTS %i\n", MAX_CONTEXT_INPUTS);
995  av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_SIZE %i\n", MAX_QUANT_TABLE_SIZE);
996 
997  desc_set = (FFVulkanDescriptorSetBinding []) {
998  {
999  .name = "rangecoder_static_buf",
1000  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1001  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1002  .mem_layout = "scalar",
1003  .buf_content = "uint8_t zero_one_state[512];",
1004  },
1005  { /* This descriptor is never used */
1006  .name = "quant_buf",
1007  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1008  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1009  .mem_layout = "scalar",
1010  .buf_content = "int16_t quant_table[MAX_QUANT_TABLES]"
1011  "[MAX_CONTEXT_INPUTS][MAX_QUANT_TABLE_SIZE];",
1012  },
1013  };
1014  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 1, 0));
1015 
1016  define_shared_code(avctx, shd);
1017 
1018  desc_set = (FFVulkanDescriptorSetBinding []) {
1019  {
1020  .name = "slice_data_buf",
1021  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1022  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1023  .buf_content = "SliceContext slice_ctx[1024];",
1024  },
1025  {
1026  .name = "src",
1027  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1028  .dimensions = 2,
1029  .mem_layout = ff_vk_shader_rep_fmt(fv->s.frames->sw_format,
1030  fv->rep_fmt),
1031  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1032  .mem_quali = "readonly",
1033  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1034  },
1035  };
1036  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0));
1037 
1039 
1040  RET(spv->compile_shader(&fv->s, spv, shd, &spv_data, &spv_len, "main",
1041  &spv_opaque));
1042  RET(ff_vk_shader_link(&fv->s, shd, spv_data, spv_len, "main"));
1043 
1044  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1045 
1046 fail:
1047  if (spv_opaque)
1048  spv->free_shader(spv, &spv_opaque);
1049 
1050  return err;
1051 }
1052 
1054 {
1055  int err;
1056  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1057  FFVulkanShader *shd = &fv->reset;
1058  FFVulkanDescriptorSetBinding *desc_set;
1059 
1060  uint8_t *spv_data;
1061  size_t spv_len;
1062  void *spv_opaque = NULL;
1063  int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1064 
1065  RET(ff_vk_shader_init(&fv->s, shd, "ffv1_reset",
1066  VK_SHADER_STAGE_COMPUTE_BIT,
1067  (const char *[]) { "GL_EXT_buffer_reference",
1068  "GL_EXT_buffer_reference2" }, 2,
1069  wg_dim, 1, 1,
1070  0));
1071 
1072  /* Common codec header */
1074 
1075  GLSLC(0, layout(push_constant, scalar) uniform pushConstants { );
1076  GLSLF(1, uint context_count[%i]; ,MAX_QUANT_TABLES);
1077  GLSLC(1, u8buf slice_state; );
1078  GLSLC(1, uint plane_state_size; );
1079  GLSLC(1, uint8_t codec_planes; );
1080  GLSLC(1, uint8_t key_frame; );
1081  GLSLC(1, uint8_t version; );
1082  GLSLC(1, uint8_t micro_version; );
1083  GLSLC(1, uint8_t padding[1]; );
1084  GLSLC(0, }; );
1086  VK_SHADER_STAGE_COMPUTE_BIT);
1087 
1088  av_bprintf(&shd->src, "#define MAX_QUANT_TABLES %i\n", MAX_QUANT_TABLES);
1089  av_bprintf(&shd->src, "#define MAX_CONTEXT_INPUTS %i\n", MAX_CONTEXT_INPUTS);
1090  av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_SIZE %i\n", MAX_QUANT_TABLE_SIZE);
1091 
1092  desc_set = (FFVulkanDescriptorSetBinding []) {
1093  {
1094  .name = "rangecoder_static_buf",
1095  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1096  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1097  .mem_layout = "scalar",
1098  .buf_content = "uint8_t zero_one_state[512];",
1099  },
1100  {
1101  .name = "quant_buf",
1102  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1103  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1104  .mem_layout = "scalar",
1105  .buf_content = "int16_t quant_table[MAX_QUANT_TABLES]"
1106  "[MAX_CONTEXT_INPUTS][MAX_QUANT_TABLE_SIZE];",
1107  },
1108  };
1109  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 1, 0));
1110 
1111  define_shared_code(avctx, shd);
1112 
1113  desc_set = (FFVulkanDescriptorSetBinding []) {
1114  {
1115  .name = "slice_data_buf",
1116  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1117  .mem_quali = "readonly",
1118  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1119  .buf_content = "SliceContext slice_ctx[1024];",
1120  },
1121  };
1122  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0, 0));
1123 
1125 
1126  RET(spv->compile_shader(&fv->s, spv, shd, &spv_data, &spv_len, "main",
1127  &spv_opaque));
1128  RET(ff_vk_shader_link(&fv->s, shd, spv_data, spv_len, "main"));
1129 
1130  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1131 
1132 fail:
1133  if (spv_opaque)
1134  spv->free_shader(spv, &spv_opaque);
1135 
1136  return err;
1137 }
1138 
1140 {
1141  int err;
1142  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1143  FFVulkanShader *shd = &fv->rct;
1144  FFVulkanDescriptorSetBinding *desc_set;
1145 
1146  uint8_t *spv_data;
1147  size_t spv_len;
1148  void *spv_opaque = NULL;
1149  int wg_count = sqrt(fv->s.props.properties.limits.maxComputeWorkGroupInvocations);
1150 
1151  enum AVPixelFormat intermediate_fmt = get_supported_rgb_buffer_fmt(avctx);
1152  if (intermediate_fmt == AV_PIX_FMT_NONE) {
1153  av_log(avctx, AV_LOG_ERROR, "Unable to find a supported compatible "
1154  "pixel format for RCT buffer!\n");
1155  return AVERROR(ENOTSUP);
1156  }
1157 
1158  RET(init_indirect(avctx, intermediate_fmt));
1159 
1160  RET(ff_vk_shader_init(&fv->s, shd, "ffv1_rct",
1161  VK_SHADER_STAGE_COMPUTE_BIT,
1162  (const char *[]) { "GL_EXT_buffer_reference",
1163  "GL_EXT_buffer_reference2" }, 2,
1164  wg_count, wg_count, 1,
1165  0));
1166 
1167  /* Common codec header */
1169 
1170  GLSLC(0, layout(push_constant, scalar) uniform pushConstants { );
1171  GLSLC(1, ivec4 fmt_lut; );
1172  GLSLC(1, int offset; );
1173  GLSLC(1, uint8_t bits; );
1174  GLSLC(1, uint8_t planar_rgb; );
1175  GLSLC(1, uint8_t color_planes; );
1176  GLSLC(1, uint8_t transparency; );
1177  GLSLC(1, uint8_t version; );
1178  GLSLC(1, uint8_t micro_version; );
1179  GLSLC(1, uint8_t padding[2]; );
1180  GLSLC(0, }; );
1182  VK_SHADER_STAGE_COMPUTE_BIT);
1183 
1184  av_bprintf(&shd->src, "#define MAX_QUANT_TABLES %i\n", MAX_QUANT_TABLES);
1185  av_bprintf(&shd->src, "#define MAX_CONTEXT_INPUTS %i\n", MAX_CONTEXT_INPUTS);
1186  av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_SIZE %i\n", MAX_QUANT_TABLE_SIZE);
1187 
1188  desc_set = (FFVulkanDescriptorSetBinding []) {
1189  {
1190  .name = "rangecoder_static_buf",
1191  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1192  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1193  .mem_layout = "scalar",
1194  .buf_content = "uint8_t zero_one_state[512];",
1195  },
1196  {
1197  .name = "quant_buf",
1198  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1199  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1200  .mem_layout = "scalar",
1201  .buf_content = "int16_t quant_table[MAX_QUANT_TABLES]"
1202  "[MAX_CONTEXT_INPUTS][MAX_QUANT_TABLE_SIZE];",
1203  },
1204  };
1205  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 1, 0));
1206 
1207  define_shared_code(avctx, shd);
1208 
1209  desc_set = (FFVulkanDescriptorSetBinding []) {
1210  {
1211  .name = "slice_data_buf",
1212  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1213  .mem_quali = "readonly",
1214  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1215  .buf_content = "SliceContext slice_ctx[1024];",
1216  },
1217  {
1218  .name = "src",
1219  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1220  .dimensions = 2,
1221  .mem_layout = ff_vk_shader_rep_fmt(fv->s.frames->sw_format,
1222  fv->rep_fmt),
1223  .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
1224  .mem_quali = "readonly",
1225  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1226  },
1227  {
1228  .name = "dst",
1229  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1230  .dimensions = 2,
1231  .mem_layout = ff_vk_shader_rep_fmt(intermediate_fmt,
1232  fv->rep_fmt),
1233  .elems = av_pix_fmt_count_planes(intermediate_fmt),
1234  .mem_quali = "writeonly",
1235  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1236  },
1237  };
1238  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0, 0));
1239 
1241 
1242  RET(spv->compile_shader(&fv->s, spv, shd, &spv_data, &spv_len, "main",
1243  &spv_opaque));
1244  RET(ff_vk_shader_link(&fv->s, shd, spv_data, spv_len, "main"));
1245 
1246  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1247 
1248 fail:
1249  if (spv_opaque)
1250  spv->free_shader(spv, &spv_opaque);
1251 
1252  return err;
1253 }
1254 
1256 {
1257  int err;
1258  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1259  FFV1Context *f = &fv->ctx;
1260  FFVulkanShader *shd = &fv->enc;
1261  FFVulkanDescriptorSetBinding *desc_set;
1262 
1263  AVHWFramesContext *frames_ctx = fv->intermediate_frames_ref ?
1265  fv->s.frames;
1266 
1267  uint8_t *spv_data;
1268  size_t spv_len;
1269  void *spv_opaque = NULL;
1270 
1271  RET(ff_vk_shader_init(&fv->s, shd, "ffv1_enc",
1272  VK_SHADER_STAGE_COMPUTE_BIT,
1273  (const char *[]) { "GL_EXT_buffer_reference",
1274  "GL_EXT_buffer_reference2" }, 2,
1275  1, 1, 1,
1276  0));
1277 
1278  /* Common codec header */
1280 
1281  add_push_data(shd);
1282 
1283  av_bprintf(&shd->src, "#define MAX_QUANT_TABLES %i\n", MAX_QUANT_TABLES);
1284  av_bprintf(&shd->src, "#define MAX_CONTEXT_INPUTS %i\n", MAX_CONTEXT_INPUTS);
1285  av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_SIZE %i\n", MAX_QUANT_TABLE_SIZE);
1286 
1287  desc_set = (FFVulkanDescriptorSetBinding []) {
1288  {
1289  .name = "rangecoder_static_buf",
1290  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1291  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1292  .mem_layout = "scalar",
1293  .buf_content = "uint8_t zero_one_state[512];",
1294  },
1295  {
1296  .name = "quant_buf",
1297  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1298  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1299  .mem_layout = "scalar",
1300  .buf_content = "int16_t quant_table[MAX_QUANT_TABLES]"
1301  "[MAX_CONTEXT_INPUTS][MAX_QUANT_TABLE_SIZE];",
1302  },
1303  {
1304  .name = "crc_ieee_buf",
1305  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1306  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1307  .mem_layout = "scalar",
1308  .buf_content = "uint32_t crc_ieee[256];",
1309  },
1310  };
1311 
1312  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 1, 0));
1313 
1314  define_shared_code(avctx, shd);
1315 
1316  desc_set = (FFVulkanDescriptorSetBinding []) {
1317  {
1318  .name = "slice_data_buf",
1319  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1320  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1321  .buf_content = "SliceContext slice_ctx[1024];",
1322  },
1323  {
1324  .name = "src",
1325  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1326  .dimensions = 2,
1327  .mem_layout = ff_vk_shader_rep_fmt(frames_ctx->sw_format,
1328  fv->rep_fmt),
1329  .elems = av_pix_fmt_count_planes(frames_ctx->sw_format),
1330  .mem_quali = "readonly",
1331  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1332  },
1333  {
1334  .name = "results_data_buf",
1335  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1336  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1337  .mem_quali = "writeonly",
1338  .buf_content = "uint64_t slice_results[2048];",
1339  },
1340  };
1341  RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0, 0));
1342 
1343  /* Assemble the shader body */
1345 
1346  if (f->ac == AC_GOLOMB_RICE)
1348  else
1350 
1351  if (fv->is_rgb)
1353  else
1355 
1356  RET(spv->compile_shader(&fv->s, spv, shd, &spv_data, &spv_len, "main",
1357  &spv_opaque));
1358  RET(ff_vk_shader_link(&fv->s, shd, spv_data, spv_len, "main"));
1359 
1360  RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1361 
1362 fail:
1363  if (spv_opaque)
1364  spv->free_shader(spv, &spv_opaque);
1365 
1366  return err;
1367 }
1368 
1370 {
1371  int err;
1372  size_t maxsize, max_heap_size, max_host_size;
1373  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1374  FFV1Context *f = &fv->ctx;
1375  FFVkSPIRVCompiler *spv;
1376 
1377  if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1378  return err;
1379 
1380  if (f->ac == 1)
1381  f->ac = AC_RANGE_CUSTOM_TAB;
1382 
1383  err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1384  if (err < 0)
1385  return err;
1386 
1387  /* Target version 3 by default */
1388  f->version = 3;
1389 
1390  err = ff_ffv1_encode_init(avctx);
1391  if (err < 0)
1392  return err;
1393 
1394  /* Rice coding did not support high bit depths */
1395  if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1396  if (f->ac == AC_GOLOMB_RICE) {
1397  av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1398  "forcing range coder\n");
1399  f->ac = AC_RANGE_CUSTOM_TAB;
1400  }
1401  }
1402 
1403  if (f->version < 4 && avctx->gop_size > 1) {
1404  av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1405  return AVERROR_INVALIDDATA;
1406  }
1407 
1408  if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1409  av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1410  return AVERROR_INVALIDDATA;
1411  }
1412 
1413  /* We target version 4.3 */
1414  if (f->version == 4 && f->micro_version > 4)
1415  f->micro_version = 3;
1416 
1417  //if (fv->ctx.ac == AC_GOLOMB_RICE) {
1418  if (0) {
1419  int w_a = FFALIGN(avctx->width, LG_ALIGN_W);
1420  int h_a = FFALIGN(avctx->height, LG_ALIGN_H);
1421  int w_sl, h_sl;
1422 
1423  /* Pixels per line an invocation handles */
1424  int ppi = 0;
1425  /* Chunk size */
1426  int chunks = 0;
1427 
1428  do {
1429  if (ppi < 2)
1430  ppi++;
1431  chunks++;
1432  w_sl = w_a / (LG_ALIGN_W*ppi);
1433  h_sl = h_a / (LG_ALIGN_H*chunks);
1434  } while (w_sl > MAX_SLICES / h_sl);
1435 
1436  av_log(avctx, AV_LOG_VERBOSE, "Slice config: %ix%i, %i total\n",
1437  LG_ALIGN_W*ppi, LG_ALIGN_H*chunks, w_sl*h_sl);
1438  av_log(avctx, AV_LOG_VERBOSE, "Horizontal slices: %i (%i pixels per invoc)\n",
1439  w_sl, ppi);
1440  av_log(avctx, AV_LOG_VERBOSE, "Vertical slices: %i (%i chunks)\n",
1441  h_sl, chunks);
1442 
1443  f->num_h_slices = w_sl;
1444  f->num_v_slices = h_sl;
1445 
1446  fv->ppi = ppi;
1447  fv->chunks = chunks;
1448  } else {
1449  f->num_h_slices = fv->num_h_slices;
1450  f->num_v_slices = fv->num_v_slices;
1451 
1452  if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1453  if (avctx->slices) {
1454  err = ff_ffv1_encode_determine_slices(avctx);
1455  if (err < 0)
1456  return err;
1457  } else {
1458  f->num_h_slices = 32;
1459  f->num_v_slices = 32;
1460  }
1461  } else if (f->num_h_slices && f->num_v_slices <= 0) {
1462  f->num_v_slices = 1024 / f->num_h_slices;
1463  } else if (f->num_v_slices && f->num_h_slices <= 0) {
1464  f->num_h_slices = 1024 / f->num_v_slices;
1465  }
1466 
1467  f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1468  f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1469 
1470  if (f->num_h_slices * f->num_v_slices > 1024) {
1471  av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1472  "by the standard is 1024\n",
1473  f->num_h_slices * f->num_v_slices);
1474  return AVERROR_PATCHWELCOME;
1475  }
1476  }
1477 
1478  if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1479  return err;
1480 
1481  if (f->version < 4) {
1482  if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1483  ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1484  av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1485  "dimensions is only supported in version 4 (-level 4)\n");
1486  return AVERROR_PATCHWELCOME;
1487  }
1488  }
1489 
1490  if (fv->force_pcm) {
1491  if (f->version < 4) {
1492  av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1493  return AVERROR_INVALIDDATA;
1494  } else if (f->ac == AC_GOLOMB_RICE) {
1495  av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1496  return AVERROR_INVALIDDATA;
1497  }
1498  }
1499 
1500  /* Init Vulkan */
1501  err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1502  if (err < 0)
1503  return err;
1504 
1505  fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1506  if (!fv->qf) {
1507  av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1508  return err;
1509  }
1510 
1511  /* Try to measure VRAM size */
1512  max_heap_size = 0;
1513  max_host_size = 0;
1514  for (int i = 0; i < fv->s.mprops.memoryHeapCount; i++) {
1515  if (fv->s.mprops.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
1516  max_heap_size = FFMAX(fv->max_heap_size,
1517  fv->s.mprops.memoryHeaps[i].size);
1518  if (!(fv->s.mprops.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT))
1519  max_host_size = FFMAX(max_host_size,
1520  fv->s.mprops.memoryHeaps[i].size);
1521  }
1522  fv->max_heap_size = max_heap_size;
1523 
1524  maxsize = ff_ffv1_encode_buffer_size(avctx);
1525  if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1526  av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1527  "than maximum device allocation (%zu), clipping\n",
1528  maxsize, fv->s.props_11.maxMemoryAllocationSize);
1529  maxsize = fv->s.props_11.maxMemoryAllocationSize;
1530  }
1531 
1532  if (max_heap_size < maxsize) {
1533  av_log(avctx, AV_LOG_WARNING, "Encoding buffer (%zu) larger than VRAM (%zu), "
1534  "using host memory (slower)\n",
1535  maxsize, fv->max_heap_size);
1536 
1537  /* Keep 1/2th of RAM as headroom */
1538  max_heap_size = max_host_size - (max_host_size >> 1);
1539  } else {
1540  /* Keep 1/8th of VRAM as headroom */
1541  max_heap_size = max_heap_size - (max_heap_size >> 3);
1542  }
1543 
1544  av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1545  maxsize / (1024*1024),
1546  (fv->async_depth * maxsize) / (1024*1024),
1547  fv->async_depth);
1548 
1549  err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1550  fv->async_depth,
1551  0, 0, 0, NULL);
1552  if (err < 0)
1553  return err;
1554 
1555  fv->transfer_qf = ff_vk_qf_find(&fv->s, VK_QUEUE_TRANSFER_BIT, 0);
1556  if (!fv->transfer_qf) {
1557  av_log(avctx, AV_LOG_ERROR, "Device has no transfer queues!\n");
1558  return err;
1559  }
1560 
1561  err = ff_vk_exec_pool_init(&fv->s, fv->transfer_qf, &fv->transfer_exec_pool,
1562  1,
1563  0, 0, 0, NULL);
1564  if (err < 0)
1565  return err;
1566 
1567  spv = ff_vk_spirv_init();
1568  if (!spv) {
1569  av_log(avctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n");
1570  return AVERROR_EXTERNAL;
1571  }
1572 
1573  /* Detect the special RGB coding mode */
1574  fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1575  !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1576 
1577  /* bits_per_raw_sample use regular unsigned representation,
1578  * but in higher bit depths, the data is casted to int16_t */
1579  fv->rep_fmt = FF_VK_REP_UINT;
1580  if (!fv->is_rgb && f->bits_per_raw_sample > 8)
1581  fv->rep_fmt = FF_VK_REP_INT;
1582 
1583  /* Init setup shader */
1584  err = init_setup_shader(avctx, spv);
1585  if (err < 0) {
1586  spv->uninit(&spv);
1587  return err;
1588  }
1589 
1590  /* Init reset shader */
1591  err = init_reset_shader(avctx, spv);
1592  if (err < 0) {
1593  spv->uninit(&spv);
1594  return err;
1595  }
1596 
1597  /* Init RCT shader */
1598  if (fv->is_rgb) {
1599  err = init_rct_shader(avctx, spv);
1600  if (err < 0) {
1601  spv->uninit(&spv);
1602  return err;
1603  }
1604  }
1605 
1606  /* Encode shader */
1607  err = init_encode_shader(avctx, spv);
1608  if (err < 0) {
1609  spv->uninit(&spv);
1610  return err;
1611  }
1612 
1613  spv->uninit(&spv);
1614 
1615  /* Range coder data */
1617  &fv->rangecoder_static_buf,
1618  f);
1619  if (err < 0)
1620  return err;
1621 
1622  /* Quantization table data */
1624  &fv->quant_buf,
1625  f);
1626  if (err < 0)
1627  return err;
1628 
1629  /* CRC table buffer */
1630  err = ff_ffv1_vk_init_crc_table_data(&fv->s,
1631  &fv->crc_tab_buf,
1632  f);
1633  if (err < 0)
1634  return err;
1635 
1636  /* Update setup global descriptors */
1638  &fv->setup, 0, 0, 0,
1639  &fv->rangecoder_static_buf,
1640  0, fv->rangecoder_static_buf.size,
1641  VK_FORMAT_UNDEFINED));
1642 
1643  /* Update encode global descriptors */
1645  &fv->enc, 0, 0, 0,
1646  &fv->rangecoder_static_buf,
1647  0, fv->rangecoder_static_buf.size,
1648  VK_FORMAT_UNDEFINED));
1650  &fv->enc, 0, 1, 0,
1651  &fv->quant_buf,
1652  0, fv->quant_buf.size,
1653  VK_FORMAT_UNDEFINED));
1655  &fv->enc, 0, 2, 0,
1656  &fv->crc_tab_buf,
1657  0, fv->crc_tab_buf.size,
1658  VK_FORMAT_UNDEFINED));
1659 
1660  /* Temporary frame */
1661  fv->frame = av_frame_alloc();
1662  if (!fv->frame)
1663  return AVERROR(ENOMEM);
1664 
1665  /* Async data pool */
1666  fv->async_depth = fv->exec_pool.pool_size;
1667  fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1668  if (!fv->exec_ctx_info)
1669  return AVERROR(ENOMEM);
1670  for (int i = 0; i < fv->async_depth; i++)
1671  fv->exec_pool.contexts[i].opaque = &fv->exec_ctx_info[i];
1672 
1673  f->max_slice_count = f->num_h_slices * f->num_v_slices;
1674  fv->buf_regions = av_malloc_array(f->max_slice_count, sizeof(*fv->buf_regions));
1675  if (!fv->buf_regions)
1676  return AVERROR(ENOMEM);
1677 
1678 fail:
1679  return err;
1680 }
1681 
1683 {
1684  VulkanEncodeFFv1Context *fv = avctx->priv_data;
1685 
1686  ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1688 
1689  ff_vk_shader_free(&fv->s, &fv->enc);
1690  ff_vk_shader_free(&fv->s, &fv->rct);
1691  ff_vk_shader_free(&fv->s, &fv->reset);
1692  ff_vk_shader_free(&fv->s, &fv->setup);
1693 
1694  if (fv->exec_ctx_info) {
1695  for (int i = 0; i < fv->async_depth; i++) {
1700  }
1701  }
1702  av_free(fv->exec_ctx_info);
1703 
1705 
1707 
1711 
1714 
1715  ff_vk_free_buf(&fv->s, &fv->quant_buf);
1717  ff_vk_free_buf(&fv->s, &fv->crc_tab_buf);
1718 
1719  av_free(fv->buf_regions);
1720  av_frame_free(&fv->frame);
1721  ff_vk_uninit(&fv->s);
1722 
1723  return 0;
1724 }
1725 
1726 #define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1727 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1729  { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_BOOL,
1730  { .i64 = -1 }, -1, 1, VE },
1731  { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1732  { .i64 = 0 }, 0, 1, VE },
1733  { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1734  { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1735  { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1736  { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1737  { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1738  { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1739  { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1740  { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1741  { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1742  { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1743  { "default", NULL, 0, AV_OPT_TYPE_CONST,
1744  { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1745  { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1746  { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1747  { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1748  { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1749 
1750  { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1751  { .i64 = -1 }, -1, 1024, VE },
1752  { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1753  { .i64 = -1 }, -1, 1024, VE },
1754 
1755  { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1756  { .i64 = 0 }, 0, 1, VE },
1757 
1758  { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1759  { .i64 = 1 }, 1, INT_MAX, VE },
1760 
1761  { NULL }
1762 };
1763 
1765  { "g", "1" },
1766  { NULL },
1767 };
1768 
1770  .class_name = "ffv1_vulkan",
1771  .item_name = av_default_item_name,
1772  .option = vulkan_encode_ffv1_options,
1773  .version = LIBAVUTIL_VERSION_INT,
1774 };
1775 
1777  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1778  NULL,
1779 };
1780 
1782  .p.name = "ffv1_vulkan",
1783  CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1784  .p.type = AVMEDIA_TYPE_VIDEO,
1785  .p.id = AV_CODEC_ID_FFV1,
1786  .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1789  .close = &vulkan_encode_ffv1_close,
1790  .p.priv_class = &vulkan_encode_ffv1_class,
1791  .p.capabilities = AV_CODEC_CAP_DELAY |
1797  .defaults = vulkan_encode_ffv1_defaults,
1799  .hw_configs = vulkan_encode_ffv1_hw_configs,
1800  .p.wrapper_name = "vulkan",
1801 };
VulkanEncodeFFv1Context::rct
FFVulkanShader rct
Definition: ffv1enc_vulkan.c:75
hwconfig.h
VulkanEncodeFFv1Context::rangecoder_static_buf
FFVkBuffer rangecoder_static_buf
Definition: ffv1enc_vulkan.c:80
CODEC_PIXFMTS
#define CODEC_PIXFMTS(...)
Definition: codec_internal.h:386
FFv1VkResetParameters::context_count
uint32_t context_count[MAX_QUANT_TABLES]
Definition: ffv1_vulkan.h:52
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
FFv1VkParameters::planes
uint8_t planes
Definition: ffv1enc_vulkan.c:144
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_ffv1_encode_determine_slices
int ff_ffv1_encode_determine_slices(AVCodecContext *avctx)
Definition: ffv1enc.c:564
run_rct
static int run_rct(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, AVFrame **intermediate_frame, VkImageView *intermediate_views, VkImageMemoryBarrier2 *img_bar, int *nb_img_bar, VkBufferMemoryBarrier2 *buf_bar, int *nb_buf_bar, FFVkBuffer *slice_data_buf, uint32_t slice_data_size)
Definition: ffv1enc_vulkan.c:190
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:42
add_push_data
static void add_push_data(FFVulkanShader *shd)
Definition: ffv1enc_vulkan.c:155
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
FFVulkanContext::props_11
VkPhysicalDeviceVulkan11Properties props_11
Definition: vulkan.h:281
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2841
ff_vk_shader_init
int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name, VkPipelineStageFlags stage, const char *extensions[], int nb_extensions, int lg_x, int lg_y, int lg_z, uint32_t required_subgroup_size)
Initialize a shader object, with a specific set of extensions, type+bind, local group size,...
Definition: vulkan.c:1975
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:88
FFVulkanContext::device_ref
AVBufferRef * device_ref
Definition: vulkan.h:301
FFVkExecPool::contexts
FFVkExecContext * contexts
Definition: vulkan.h:253
FFv1VkParameters::scratch_data
VkDeviceAddress scratch_data
Definition: ffv1enc_vulkan.c:127
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:66
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:300
VulkanEncodeFFv1Context::is_rgb
int is_rgb
Definition: ffv1enc_vulkan.c:107
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:198
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:89
FFVkBuffer::access
VkAccessFlags2 access
Definition: vulkan.h:96
int64_t
long long int64_t
Definition: coverity.c:34
download_slices
static int download_slices(AVCodecContext *avctx, VkBufferCopy *buf_regions, int nb_regions, VulkanEncodeFFv1FrameData *fd, AVBufferRef *pkt_data_ref)
Definition: ffv1enc_vulkan.c:657
VulkanEncodeFFv1Context::in_flight
int in_flight
Definition: ffv1enc_vulkan.c:69
FFVkBuffer::stage
VkPipelineStageFlags2 stage
Definition: vulkan.h:95
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
FFv1VkParameters::key_frame
uint8_t key_frame
Definition: ffv1enc_vulkan.c:143
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:333
ff_ffv1_vk_init_quant_table_data
int ff_ffv1_vk_init_quant_table_data(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
Definition: ffv1_vulkan.c:72
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
FFv1VkParameters::slice_state
VkDeviceAddress slice_state
Definition: ffv1enc_vulkan.c:126
VulkanEncodeFFv1Context::chunks
int chunks
Definition: ffv1enc_vulkan.c:109
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:259
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:535
AVOption
AVOption.
Definition: opt.h:429
encode.h
FFVulkanShader::src
AVBPrint src
Definition: vulkan.h:195
MAX_QUANT_TABLE_SIZE
#define MAX_QUANT_TABLE_SIZE
Definition: ffv1.h:48
ff_source_ffv1_vlc_comp
const char * ff_source_ffv1_vlc_comp
AV_PIX_FMT_RGBA128
#define AV_PIX_FMT_RGBA128
Definition: pixfmt.h:613
ff_ffv1_write_extradata
av_cold int ff_ffv1_write_extradata(AVCodecContext *avctx)
Definition: ffv1enc.c:445
FFCodec
Definition: codec_internal.h:127
FFv1VkResetParameters::slice_state
VkDeviceAddress slice_state
Definition: ffv1_vulkan.h:53
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
FFV1Context::num_h_slices
int num_h_slices
Definition: ffv1.h:173
FFVkBuffer::address
VkDeviceAddress address
Definition: vulkan.h:92
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:553
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:2893
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:491
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2882
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: defs.h:62
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:654
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
FFVkSPIRVCompiler::uninit
void(* uninit)(struct FFVkSPIRVCompiler **ctx)
Definition: vulkan_spirv.h:32
FF_VK_REP_INT
@ FF_VK_REP_INT
Definition: vulkan.h:392
define_shared_code
static void define_shared_code(AVCodecContext *avctx, FFVulkanShader *shd)
Definition: ffv1enc_vulkan.c:946
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:218
av_hwdevice_get_hwframe_constraints
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
Definition: hwcontext.c:577
AC_RANGE_CUSTOM_TAB
#define AC_RANGE_CUSTOM_TAB
Definition: ffv1.h:54
FFv1VkParameters::micro_version
uint8_t micro_version
Definition: ffv1enc_vulkan.c:141
ff_source_ffv1_reset_comp
const char * ff_source_ffv1_reset_comp
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:590
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:723
FFVkShaderRepFormat
FFVkShaderRepFormat
Returns the format to use for images in shaders.
Definition: vulkan.h:386
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:431
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:88
VulkanEncodeFFv1Context::pkt_data_pool
AVBufferPool * pkt_data_pool
Definition: ffv1enc_vulkan.c:89
ff_source_ffv1_enc_rct_comp
const char * ff_source_ffv1_enc_rct_comp
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:442
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:638
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3381
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:1769
MAX_QUANT_TABLE_MASK
#define MAX_QUANT_TABLE_MASK
Definition: ffv1.h:49
FFCodecDefault
Definition: codec_internal.h:96
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:546
VulkanEncodeFFv1FrameData::key_frame
int key_frame
Definition: ffv1enc_vulkan.c:53
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:571
VulkanEncodeFFv1Context::num_v_slices
int num_v_slices
Definition: ffv1enc_vulkan.c:104
FFv1VkParameters::sar
int32_t sar[2]
Definition: ffv1enc_vulkan.c:130
fail
#define fail()
Definition: checkasm.h:194
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:544
FFv1VkParameters::out_data
VkDeviceAddress out_data
Definition: ffv1enc_vulkan.c:128
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:2718
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:208
FFv1VkParameters::transparency
uint8_t transparency
Definition: ffv1enc_vulkan.c:146
VulkanEncodeFFv1Context::crc_tab_buf
FFVkBuffer crc_tab_buf
Definition: ffv1enc_vulkan.c:81
FFv1VkParameters::force_pcm
uint8_t force_pcm
Definition: ffv1enc_vulkan.c:142
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:2481
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:488
VulkanEncodeFFv1Context::ppi
int ppi
Definition: ffv1enc_vulkan.c:108
FFv1VkParameters::plane_state_size
uint32_t plane_state_size
Definition: ffv1enc_vulkan.c:133
MAX_SLICES
#define MAX_SLICES
Definition: d3d12va_hevc.c:33
ff_vk_shader_add_descriptor_set
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, FFVulkanDescriptorSetBinding *desc, int nb, int singular, int print_to_shader_only)
Add descriptor to a shader.
Definition: vulkan.c:2346
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:45
FFv1VkParameters::pic_mode
uint8_t pic_mode
Definition: ffv1enc_vulkan.c:148
AV_CODEC_CAP_ENCODER_FLUSH
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition: codec.h:151
VulkanEncodeFFv1Context::keyframe_slice_data_ref
AVBufferRef * keyframe_slice_data_ref
Definition: ffv1enc_vulkan.c:85
ff_source_ffv1_enc_setup_comp
const char * ff_source_ffv1_enc_setup_comp
VulkanEncodeFFv1FrameData::frame_opaque_ref
AVBufferRef * frame_opaque_ref
Definition: ffv1enc_vulkan.c:51
AVRational::num
int num
Numerator.
Definition: rational.h:59
ff_ffv1_vulkan_encoder
const FFCodec ff_ffv1_vulkan_encoder
Definition: ffv1enc_vulkan.c:1781
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:51
VulkanEncodeFFv1Context::s
FFVulkanContext s
Definition: ffv1enc_vulkan.c:60
GLSLC
#define GLSLC(N, S)
Definition: vulkan.h:43
VulkanEncodeFFv1FrameData
Definition: ffv1enc_vulkan.c:40
vulkan_encode_ffv1_hw_configs
const AVCodecHWConfigInternal *const vulkan_encode_ffv1_hw_configs[]
Definition: ffv1enc_vulkan.c:1776
get_packet
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:731
pkt
AVPacket * pkt
Definition: movenc.c:60
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::results_data_pool
AVBufferPool * results_data_pool
Definition: ffv1enc_vulkan.c:95
av_cold
#define av_cold
Definition: attributes.h:90
VulkanEncodeFFv1Context::tmp_data_pool
AVBufferPool * tmp_data_pool
Definition: ffv1enc_vulkan.c:92
VulkanEncodeFFv1Context::setup
FFVulkanShader setup
Definition: ffv1enc_vulkan.c:73
AVHWFramesContext::height
int height
Definition: hwcontext.h:218
FFv1VkParameters::codec_planes
uint8_t codec_planes
Definition: ffv1enc_vulkan.c:145
AVHWFramesConstraints::valid_sw_formats
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:454
FFV1Context::use32bit
int use32bit
Definition: ffv1.h:156
LG_ALIGN_W
#define LG_ALIGN_W
Definition: ffv1enc_vulkan.c:37
av_hwframe_constraints_free
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:602
AV_PIX_FMT_RGB96
#define AV_PIX_FMT_RGB96
Definition: pixfmt.h:612
FFv1VkParameters::bits_per_raw_sample
uint8_t bits_per_raw_sample
Definition: ffv1enc_vulkan.c:138
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:496
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:1483
bits
uint8_t bits
Definition: vp3data.h:128
VulkanEncodeFFv1Context::max_heap_size
size_t max_heap_size
Definition: ffv1enc_vulkan.c:71
AVVulkanFramesContext::img_flags
VkImageCreateFlags img_flags
Flags to set during image creation.
Definition: hwcontext_vulkan.h:260
vulkan_encode_ffv1_receive_packet
static int vulkan_encode_ffv1_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: ffv1enc_vulkan.c:811
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
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:563
GLSLD
#define GLSLD(D)
Definition: vulkan.h:58
ff_ffv1_encode_setup_plane_info
av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, enum AVPixelFormat pix_fmt)
Definition: ffv1enc.c:798
FFv1VkParameters::crcref
uint32_t crcref
Definition: ffv1enc_vulkan.c:135
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:233
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:560
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:326
if
if(ret)
Definition: filter_design.txt:179
FFv1VkParameters::chroma_shift
uint32_t chroma_shift[2]
Definition: ffv1enc_vulkan.c:131
VulkanEncodeFFv1Context::frame
AVFrame * frame
Definition: ffv1enc_vulkan.c:58
TYPE
#define TYPE
Definition: ffv1dec.c:91
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:518
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:518
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
ff_vk_shader_rep_fmt
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt, enum FFVkShaderRepFormat rep_fmt)
Definition: vulkan.c:1521
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:211
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
FFv1VkParameters::ppi
uint8_t ppi
Definition: ffv1enc_vulkan.c:150
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
VulkanEncodeFFv1Context::rep_fmt
enum FFVkShaderRepFormat rep_fmt
Definition: ffv1enc_vulkan.c:101
FFV1Context::num_v_slices
int num_v_slices
Definition: ffv1.h:172
VulkanEncodeFFv1Context::force_pcm
int force_pcm
Definition: ffv1enc_vulkan.c:105
FFv1VkParameters::version
uint8_t version
Definition: ffv1enc_vulkan.c:140
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:361
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
FFVkExecContext::had_submission
int had_submission
Definition: vulkan.h:114
FFVkBuffer::size
size_t size
Definition: vulkan.h:91
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:227
ffv1_vulkan.h
VulkanEncodeFFv1Context::num_h_slices
int num_h_slices
Definition: ffv1enc_vulkan.c:103
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:100
FFVulkanContext
Definition: vulkan.h:274
init_rct_shader
static int init_rct_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
Definition: ffv1enc_vulkan.c:1139
VulkanEncodeFFv1FrameData::duration
int64_t duration
Definition: ffv1enc_vulkan.c:49
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:84
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
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
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:2797
AVPacket::size
int size
Definition: packet.h:536
FFVulkanDescriptorSetBinding
Definition: vulkan.h:74
VulkanEncodeFFv1FrameData::pts
int64_t pts
Definition: ffv1enc_vulkan.c:48
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1005
FFv1VkParameters::padding
uint8_t padding[2]
Definition: ffv1enc_vulkan.c:152
codec_internal.h
AVVkFrame
Definition: hwcontext_vulkan.h:297
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_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:514
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:411
init_indirect
static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
Definition: ffv1enc_vulkan.c:865
FFVulkanShader
Definition: vulkan.h:190
ff_ffv1_vk_init_crc_table_data
int ff_ffv1_vk_init_crc_table_data(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
Definition: ffv1_vulkan.c:100
AVCodecHWConfigInternal
Definition: hwconfig.h:25
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:90
ff_source_ffv1_enc_ac_comp
const char * ff_source_ffv1_enc_ac_comp
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:534
ff_source_common_comp
const char * ff_source_common_comp
FFVkSPIRVCompiler::compile_shader
int(* compile_shader)(FFVulkanContext *s, struct FFVkSPIRVCompiler *ctx, FFVulkanShader *shd, uint8_t **data, size_t *size, const char *entrypoint, void **opaque)
Definition: vulkan_spirv.h:28
VulkanEncodeFFv1FrameData::out_data_ref
AVBufferRef * out_data_ref
Definition: ffv1enc_vulkan.c:42
init_setup_shader
static int init_setup_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
Definition: ffv1enc_vulkan.c:971
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
FFVkExecContext
Definition: vulkan.h:111
init_reset_shader
static int init_reset_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
Definition: ffv1enc_vulkan.c:1053
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:2731
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:541
FFVulkanDescriptorSetBinding::name
const char * name
Definition: vulkan.h:75
version
version
Definition: libkvazaar.c:315
VulkanEncodeFFv1Context::enc
FFVulkanShader enc
Definition: ffv1enc_vulkan.c:76
ff_vk_mt_is_np_rgb
int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt)
Returns 1 if pixfmt is a usable RGB format.
Definition: vulkan.c:1462
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
VulkanEncodeFFv1Context::quant_buf
FFVkBuffer quant_buf
Definition: ffv1enc_vulkan.c:79
FFVkSPIRVCompiler
Definition: vulkan_spirv.h:26
VE
#define VE
Definition: ffv1enc_vulkan.c:1727
ff_source_ffv1_enc_rgb_comp
const char * ff_source_ffv1_enc_rgb_comp
layout
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 layout
Definition: filter_design.txt:18
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:98
ff_source_ffv1_enc_comp
const char * ff_source_ffv1_enc_comp
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:503
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:528
VulkanEncodeFFv1FrameData::results_data_ref
AVBufferRef * results_data_ref
Definition: ffv1enc_vulkan.c:45
FF_VK_REP_UINT
@ FF_VK_REP_UINT
Definition: vulkan.h:394
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:545
init_encode_shader
static int init_encode_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
Definition: ffv1enc_vulkan.c:1255
ff_vk_frame_barrier
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage, VkAccessFlagBits new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition: vulkan.c:1932
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
ff_vk_shader_link
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, uint8_t *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition: vulkan.c:2271
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:498
FFVkBuffer::mem
VkDeviceMemory mem
Definition: vulkan.h:89
planes
static const struct @493 planes[]
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
vulkan_spirv.h
vulkan_encode_ffv1_close
static av_cold int vulkan_encode_ffv1_close(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1682
FFVulkanContext::props
VkPhysicalDeviceProperties2 props
Definition: vulkan.h:280
QTABLE_8BIT
@ QTABLE_8BIT
Definition: ffv1enc.h:30
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition: vulkan.c:1146
AVCodecContext::height
int height
Definition: avcodec.h:592
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:633
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MAX_CONTEXT_INPUTS
#define MAX_CONTEXT_INPUTS
Definition: ffv1.h:50
FFVkSPIRVCompiler::free_shader
void(* free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque)
Definition: vulkan_spirv.h:31
FFVulkanContext::mprops
VkPhysicalDeviceMemoryProperties mprops
Definition: vulkan.h:283
ff_vk_exec_bind_shader
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd)
Bind a shader.
Definition: vulkan.c:2807
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:1453
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
QTABLE_GT8BIT
@ QTABLE_GT8BIT
Definition: ffv1enc.h:31
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:1671
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:264
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:1849
FFVulkanContext::vkfn
FFVulkanFunctions vkfn
Definition: vulkan.h:278
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:151
AVCodecContext::strict_std_compliance
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition: avcodec.h:1357
VulkanEncodeFFv1Context::exec_pool
FFVkExecPool exec_pool
Definition: ffv1enc_vulkan.c:62
FFVkExecContext::opaque
void * opaque
Definition: vulkan.h:128
FFVkExecPool
Definition: vulkan.h:252
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
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:1392
VulkanEncodeFFv1Context::intermediate_frames_ref
AVBufferRef * intermediate_frames_ref
Definition: ffv1enc_vulkan.c:98
VulkanEncodeFFv1FrameData::frame_opaque
void * frame_opaque
Definition: ffv1enc_vulkan.c:50
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:507
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:220
vulkan_encode_ffv1_options
static const AVOption vulkan_encode_ffv1_options[]
Definition: ffv1enc_vulkan.c:1728
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:707
AVCodecContext
main external API structure.
Definition: avcodec.h:431
VulkanEncodeFFv1Context::transfer_exec_pool
FFVkExecPool transfer_exec_pool
Definition: ffv1enc_vulkan.c:65
check_support
static int check_support(AVHWFramesConstraints *constraints, enum AVPixelFormat fmt)
Definition: ffv1enc_vulkan.c:898
ff_source_ffv1_enc_common_comp
const char * ff_source_ffv1_enc_common_comp
ff_ffv1_vk_init_state_transition_data
int ff_ffv1_vk_init_state_transition_data(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
Definition: ffv1_vulkan.c:65
FFV1Context::context_model
int context_model
Definition: ffv1.h:161
VulkanEncodeFFv1Context::reset
FFVulkanShader reset
Definition: ffv1enc_vulkan.c:74
GLSLF
#define GLSLF(N, S,...)
Definition: vulkan.h:53
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
VulkanEncodeFFv1Context::async_depth
int async_depth
Definition: ffv1enc_vulkan.c:70
FFv1VkParameters::context_model
uint8_t context_model
Definition: ffv1enc_vulkan.c:139
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:294
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:217
FFv1VkResetParameters
Definition: ffv1_vulkan.h:51
FFv1VkParameters::colorspace
uint8_t colorspace
Definition: ffv1enc_vulkan.c:147
VulkanEncodeFFv1Context::qf
AVVulkanDeviceQueueFamily * qf
Definition: ffv1enc_vulkan.c:61
vulkan_encode_ffv1_defaults
static const FFCodecDefault vulkan_encode_ffv1_defaults[]
Definition: ffv1enc_vulkan.c:1764
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFVulkanContext::hwctx
AVVulkanDeviceContext * hwctx
Definition: vulkan.h:303
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:205
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
MAX_QUANT_TABLES
#define MAX_QUANT_TABLES
Definition: ffv1.h:47
ff_ffv1_encode_init
av_cold int ff_ffv1_encode_init(AVCodecContext *avctx)
Definition: ffv1enc.c:599
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:84
FFV1Context
Definition: ffv1.h:122
LG_ALIGN_H
#define LG_ALIGN_H
Definition: ffv1enc_vulkan.c:38
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFV1Context::transparency
int transparency
Definition: ffv1.h:133
QTABLE_DEFAULT
@ QTABLE_DEFAULT
Definition: ffv1enc.h:29
ff_vk_count_images
static int ff_vk_count_images(AVVkFrame *f)
Definition: vulkan.h:320
ff_vk_exec_discard_deps
void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:535
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1021
AVPacket
This structure stores compressed data.
Definition: packet.h:512
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
FFVkBuffer
Definition: vulkan.h:87
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
vulkan_encode_ffv1_init
static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:1369
int32_t
int32_t
Definition: audioconvert.c:56
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:848
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVVulkanDeviceQueueFamily
Definition: hwcontext_vulkan.h:33
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
FFVulkanContext::frames
AVHWFramesContext * frames
Definition: vulkan.h:307
FFv1VkParameters
Definition: ffv1enc_vulkan.c:125
get_supported_rgb_buffer_fmt
static enum AVPixelFormat get_supported_rgb_buffer_fmt(AVCodecContext *avctx)
Definition: ffv1enc_vulkan.c:908
OFFSET
#define OFFSET(x)
Definition: ffv1enc_vulkan.c:1726
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:638
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:502
FFv1VkParameters::chunks
uint8_t chunks
Definition: ffv1enc_vulkan.c:151
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
FFv1VkParameters::context_count
uint32_t context_count
Definition: ffv1enc_vulkan.c:134
FFVulkanFunctions
Definition: vulkan_functions.h:267
FFVkExecPool::pool_size
int pool_size
Definition: vulkan.h:258
FFv1VkParameters::slice_size_max
uint32_t slice_size_max
Definition: ffv1enc_vulkan.c:136
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:1188
FFv1VkRCTParameters
Definition: ffv1_vulkan.h:39
ff_source_ffv1_enc_vlc_comp
const char * ff_source_ffv1_enc_vlc_comp
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:3261
FFv1VkParameters::ec
uint8_t ec
Definition: ffv1enc_vulkan.c:149
VulkanEncodeFFv1Context::out_data_pool
AVBufferPool * out_data_pool
Definition: ffv1enc_vulkan.c:88
ff_source_rangecoder_comp
const char * ff_source_rangecoder_comp