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