FFmpeg
vulkan_ffv1.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 "vulkan_decode.h"
22 #include "hwaccel_internal.h"
23 
24 #include "ffv1.h"
25 #include "ffv1_vulkan.h"
26 #include "libavutil/mem.h"
27 
28 #define RGB_LINECACHE 2
29 
30 extern const unsigned char ff_ffv1_dec_setup_comp_spv_data[];
31 extern const unsigned int ff_ffv1_dec_setup_comp_spv_len;
32 
33 extern const unsigned char ff_ffv1_dec_reset_comp_spv_data[];
34 extern const unsigned int ff_ffv1_dec_reset_comp_spv_len;
35 
36 extern const unsigned char ff_ffv1_dec_reset_golomb_comp_spv_data[];
37 extern const unsigned int ff_ffv1_dec_reset_golomb_comp_spv_len;
38 
39 extern const unsigned char ff_ffv1_dec_comp_spv_data[];
40 extern const unsigned int ff_ffv1_dec_comp_spv_len;
41 
42 extern const unsigned char ff_ffv1_dec_rgb_comp_spv_data[];
43 extern const unsigned int ff_ffv1_dec_rgb_comp_spv_len;
44 
45 extern const unsigned char ff_ffv1_dec_golomb_comp_spv_data[];
46 extern const unsigned int ff_ffv1_dec_golomb_comp_spv_len;
47 
48 extern const unsigned char ff_ffv1_dec_rgb_golomb_comp_spv_data[];
49 extern const unsigned int ff_ffv1_dec_rgb_golomb_comp_spv_len;
50 
51 extern const unsigned char ff_ffv1_dec_rgb_float_comp_spv_data[];
52 extern const unsigned int ff_ffv1_dec_rgb_float_comp_spv_len;
53 
54 extern const unsigned char ff_ffv1_dec_rgb_float_golomb_comp_spv_data[];
55 extern const unsigned int ff_ffv1_dec_rgb_float_golomb_comp_spv_len;
56 
59  .queue_flags = VK_QUEUE_COMPUTE_BIT,
60 };
61 
62 typedef struct FFv1VulkanDecodePicture {
64 
66  uint32_t plane_state_size;
67  uint32_t slice_state_size;
68  uint32_t slice_data_size;
69 
72  uint32_t *slice_offset;
73  int slice_num;
76 
77 typedef struct FFv1VulkanDecodeContext {
79 
83 
85 
90 
92  const AVBufferRef *buffer_ref,
93  av_unused const uint8_t *buffer,
94  av_unused uint32_t size)
95 {
96  int err;
99  FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
100  FFV1Context *f = avctx->priv_data;
101 
102  FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
103  FFVulkanDecodePicture *vp = &fp->vp;
104 
106  enum AVPixelFormat sw_format = hwfc->sw_format;
107 
108  int max_contexts;
109  int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
110  !(sw_format == AV_PIX_FMT_YA8);
111 
112  fp->slice_num = 0;
113 
114  max_contexts = 0;
115  for (int i = 0; i < f->quant_table_count; i++)
116  max_contexts = FFMAX(f->context_count[i], max_contexts);
117 
118  /* Allocate slice buffer data */
119  if (f->ac == AC_GOLOMB_RICE)
120  fp->plane_state_size = 8;
121  else
123 
124  fp->plane_state_size *= max_contexts;
125  fp->slice_state_size = fp->plane_state_size*f->plane_count;
126 
127  fp->slice_data_size = 256; /* Overestimation for the SliceContext struct */
130 
131  fp->crc_checked = f->ec && (avctx->err_recognition & AV_EF_CRCCHECK);
132 
133  /* Host map the input slices data if supported */
134  if (ctx->s.extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY)
135  ff_vk_host_map_buffer(&ctx->s, &vp->slices_buf, buffer_ref->data,
136  buffer_ref,
137  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
138  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
139 
140  /* Allocate slice state data */
141  if (f->picture.f->flags & AV_FRAME_FLAG_KEY) {
143  &fp->slice_state,
144  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
145  NULL, f->slice_count*fp->slice_state_size,
146  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
147  if (err < 0)
148  return err;
149  } else {
150  FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private;
152  if (!fp->slice_state)
153  return AVERROR(ENOMEM);
154  }
155 
156  /* Allocate slice offsets/status buffer */
158  &fp->slice_feedback_buf,
159  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
160  NULL, 2*(2*f->slice_count*sizeof(uint32_t)),
161  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
162  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
163  if (err < 0)
164  return err;
165 
166  /* Allocate slice offsets/status buffer */
167  if (f->version >=4 && f->micro_version >= 9) {
169  &fp->slice_fltmap_buf,
170  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
171  NULL, 65536*4*f->slice_count*sizeof(uint32_t),
172  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
173  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
174  if (err < 0)
175  return err;
176  }
177 
178  /* Prepare frame to be used */
179  err = ff_vk_decode_prepare_frame_sdr(dec, f->picture.f, vp, 1,
180  FF_VK_REP_NATIVE, 0);
181  if (err < 0)
182  return err;
183 
184  /* Create a temporaty frame for RGB */
185  if (is_rgb) {
186  vp->dpb_frame = av_frame_alloc();
187  if (!vp->dpb_frame)
188  return AVERROR(ENOMEM);
189 
191  vp->dpb_frame, 0);
192  if (err < 0)
193  return err;
194  }
195 
196  return 0;
197 }
198 
200  const uint8_t *data,
201  uint32_t size)
202 {
203  FFV1Context *f = avctx->priv_data;
204 
205  FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
206  FFVulkanDecodePicture *vp = &fp->vp;
207 
208  FFVkBuffer *slice_offset = (FFVkBuffer *)fp->slice_feedback_buf->data;
209  FFVkBuffer *slices_buf = vp->slices_buf ? (FFVkBuffer *)vp->slices_buf->data : NULL;
210 
211  if (slices_buf && slices_buf->host_ref) {
212  AV_WN32(slice_offset->mapped_mem + (2*fp->slice_num + 0)*sizeof(uint32_t),
213  data - slices_buf->mapped_mem);
214  AV_WN32(slice_offset->mapped_mem + (2*fp->slice_num + 1)*sizeof(uint32_t),
215  size);
216 
217  fp->slice_num++;
218  } else {
219  int err = ff_vk_decode_add_slice(avctx, vp, data, size, 0,
220  &fp->slice_num,
221  (const uint32_t **)&fp->slice_offset);
222  if (err < 0)
223  return err;
224 
225  AV_WN32(slice_offset->mapped_mem + (2*(fp->slice_num - 1) + 0)*sizeof(uint32_t),
226  fp->slice_offset[fp->slice_num - 1]);
227  AV_WN32(slice_offset->mapped_mem + (2*(fp->slice_num - 1) + 1)*sizeof(uint32_t),
228  size);
229  }
230 
231  return 0;
232 }
233 
235 {
236  int err;
239  FFVulkanFunctions *vk = &ctx->s.vkfn;
240 
241  FFV1Context *f = avctx->priv_data;
242  FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
243 
245  enum AVPixelFormat sw_format = hwfc->sw_format;
246 
247  int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
248  !(sw_format == AV_PIX_FMT_YA8);
249  int color_planes = av_pix_fmt_desc_get(avctx->sw_pix_fmt)->nb_components;
250 
251  FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
252  FFVulkanDecodePicture *vp = &fp->vp;
253 
254  FFVkBuffer *slices_buf = (FFVkBuffer *)vp->slices_buf->data;
255  FFVkBuffer *slice_state = (FFVkBuffer *)fp->slice_state->data;
256  FFVkBuffer *slice_feedback = (FFVkBuffer *)fp->slice_feedback_buf->data;
257  FFVkBuffer *fltmap_buf = NULL;
258  if (fp->slice_fltmap_buf)
259  fltmap_buf = (FFVkBuffer *)fp->slice_fltmap_buf->data;
260 
261  VkImageView rct_image_views[AV_NUM_DATA_POINTERS];
262 
263  VkImageMemoryBarrier2 img_bar[37];
264  int nb_img_bar = 0;
265  VkBufferMemoryBarrier2 buf_bar[8];
266  int nb_buf_bar = 0;
267 
268  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
269  ff_vk_exec_start(&ctx->s, exec);
270 
271  /* Prepare deps */
272  RET(ff_vk_exec_add_dep_frame(&ctx->s, exec, f->picture.f,
273  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
274  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
275 
276  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
277  f->picture.f);
278  if (err < 0)
279  return err;
280 
281  if (is_rgb) {
282  RET(ff_vk_create_imageviews(&ctx->s, exec, rct_image_views,
284  RET(ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
285  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
286  VK_PIPELINE_STAGE_2_CLEAR_BIT));
287  }
288 
289  if (!(f->picture.f->flags & AV_FRAME_FLAG_KEY)) {
290  FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private;
291  FFVulkanDecodePicture *vpl = &fpl->vp;
292 
293  /* Wait on the previous frame */
294  RET(ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, vpl->sem_value,
295  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT));
296  }
297 
298  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_state, 1, 1));
299  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_feedback_buf, 1, 1));
300  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0));
301  vp->slices_buf = NULL;
302 
303  if (fp->slice_fltmap_buf) {
304  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_fltmap_buf, 1, 0));
305  fp->slice_fltmap_buf = NULL;
306  }
307 
308  AVVkFrame *vkf = (AVVkFrame *)f->picture.f->data[0];
309  for (int i = 0; i < ff_vk_count_images(vkf); i++) {
310  vkf->layout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
311  vkf->access[i] = VK_ACCESS_2_NONE;
312  }
313 
314  /* Setup shader */
315  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
316  1, 0, 0,
317  slice_state,
318  0, fp->slice_data_size*f->slice_count,
319  VK_FORMAT_UNDEFINED);
320  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
321  1, 1, 0,
322  slice_feedback,
323  0, 2*f->slice_count*sizeof(uint32_t),
324  VK_FORMAT_UNDEFINED);
325  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
326  1, 2, 0,
327  slice_feedback,
328  2*f->slice_count*sizeof(uint32_t),
329  VK_WHOLE_SIZE,
330  VK_FORMAT_UNDEFINED);
331  if (fltmap_buf)
332  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
333  1, 3, 0,
334  fltmap_buf,
335  0,
336  VK_WHOLE_SIZE,
337  VK_FORMAT_UNDEFINED);
338 
339  ff_vk_exec_bind_shader(&ctx->s, exec, &fv->setup);
340 
341  FFv1ShaderParams pd = {
342  .slice_data = slices_buf->address,
343 
344  .img_size[0] = f->picture.f->width,
345  .img_size[1] = f->picture.f->height,
346 
347  .plane_state_size = fp->plane_state_size,
348  .key_frame = f->picture.f->flags & AV_FRAME_FLAG_KEY,
349  .crcref = f->crcref,
350  .micro_version = f->micro_version,
351  };
352 
353  for (int i = 0; i < f->quant_table_count; i++) {
354  pd.context_count[i] = f->context_count[i];
355  pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
356  f->quant_tables[i][4][127];
357  }
358 
359  /* For some reason the C FFv1 encoder/decoder treats these differently */
360  if (sw_format == AV_PIX_FMT_GBRP10 || sw_format == AV_PIX_FMT_GBRP12 ||
361  sw_format == AV_PIX_FMT_GBRP14)
362  memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
363  else
364  ff_vk_set_perm(sw_format, pd.fmt_lut, 0);
365 
366  ff_vk_shader_update_push_const(&ctx->s, exec, &fv->setup,
367  VK_SHADER_STAGE_COMPUTE_BIT,
368  0, sizeof(FFv1ShaderParams), &pd);
369 
370  vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices, 1);
371 
372  if (is_rgb) {
373  vkf = (AVVkFrame *)vp->dpb_frame->data[0];
374  for (int i = 0; i < 4; i++) {
375  vkf->layout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
376  vkf->access[i] = VK_ACCESS_2_NONE;
377  }
378 
379  ff_vk_frame_barrier(&ctx->s, exec, vp->dpb_frame, img_bar, &nb_img_bar,
380  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
381  VK_PIPELINE_STAGE_2_CLEAR_BIT,
382  VK_ACCESS_2_TRANSFER_WRITE_BIT,
383  VK_IMAGE_LAYOUT_GENERAL,
384  VK_QUEUE_FAMILY_IGNORED);
385 
386  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
387  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
388  .pImageMemoryBarriers = img_bar,
389  .imageMemoryBarrierCount = nb_img_bar,
390  .pBufferMemoryBarriers = buf_bar,
391  .bufferMemoryBarrierCount = nb_buf_bar,
392  });
393  nb_img_bar = 0;
394  nb_buf_bar = 0;
395 
396  for (int i = 0; i < color_planes; i++)
397  vk->CmdClearColorImage(exec->buf, vkf->img[i], VK_IMAGE_LAYOUT_GENERAL,
398  &((VkClearColorValue) { 0 }),
399  1, &((VkImageSubresourceRange) {
400  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
401  .levelCount = 1,
402  .layerCount = 1,
403  }));
404  }
405 
406  /* Sync between setup and reset shaders */
407  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
408  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
409  SHADER_STORAGE_WRITE_BIT,
410  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT, NONE_KHR,
411  0, fp->slice_data_size*f->slice_count);
412 
413  /* Probability data barrier for P-frames */
414  if (!(f->picture.f->flags & AV_FRAME_FLAG_KEY))
415  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
416  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
417  SHADER_STORAGE_WRITE_BIT,
418  COMPUTE_SHADER_BIT, SHADER_STORAGE_WRITE_BIT, NONE_KHR,
419  fp->slice_data_size*f->slice_count, VK_WHOLE_SIZE);
420 
421  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
422  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
423  .pImageMemoryBarriers = img_bar,
424  .imageMemoryBarrierCount = nb_img_bar,
425  .pBufferMemoryBarriers = buf_bar,
426  .bufferMemoryBarrierCount = nb_buf_bar,
427  });
428  nb_buf_bar = 0;
429  nb_img_bar = 0;
430 
431  /* Reset shader */
432  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->reset,
433  1, 0, 0,
434  slice_state,
435  0, fp->slice_data_size*f->slice_count,
436  VK_FORMAT_UNDEFINED);
437  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->reset,
438  1, 1, 0,
439  slice_state,
440  f->slice_count*fp->slice_data_size,
441  VK_WHOLE_SIZE,
442  VK_FORMAT_UNDEFINED);
443 
444  ff_vk_exec_bind_shader(&ctx->s, exec, &fv->reset);
445  ff_vk_shader_update_push_const(&ctx->s, exec, &fv->reset,
446  VK_SHADER_STAGE_COMPUTE_BIT,
447  0, sizeof(FFv1ShaderParams), &pd);
448 
449  vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices,
450  f->plane_count);
451 
452  /* Sync probabilities between reset and decode shaders */
453  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
454  COMPUTE_SHADER_BIT, SHADER_STORAGE_WRITE_BIT, NONE_KHR,
455  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
456  SHADER_STORAGE_WRITE_BIT,
457  fp->slice_data_size*f->slice_count, VK_WHOLE_SIZE);
458 
459  /* Input frame barrier */
460  ff_vk_frame_barrier(&ctx->s, exec, f->picture.f, img_bar, &nb_img_bar,
461  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
462  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
463  VK_ACCESS_SHADER_WRITE_BIT |
464  (!is_rgb ? VK_ACCESS_SHADER_READ_BIT : 0),
465  VK_IMAGE_LAYOUT_GENERAL,
466  VK_QUEUE_FAMILY_IGNORED);
467  if (is_rgb)
468  ff_vk_frame_barrier(&ctx->s, exec, vp->dpb_frame, img_bar, &nb_img_bar,
469  VK_PIPELINE_STAGE_2_CLEAR_BIT,
470  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
471  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
472  VK_IMAGE_LAYOUT_GENERAL,
473  VK_QUEUE_FAMILY_IGNORED);
474 
475  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
476  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
477  .pImageMemoryBarriers = img_bar,
478  .imageMemoryBarrierCount = nb_img_bar,
479  .pBufferMemoryBarriers = buf_bar,
480  .bufferMemoryBarrierCount = nb_buf_bar,
481  });
482  nb_img_bar = 0;
483  nb_buf_bar = 0;
484 
485  /* Decode */
487  1, 0, 0,
488  slice_state,
489  0, fp->slice_data_size*f->slice_count,
490  VK_FORMAT_UNDEFINED);
492  1, 1, 0,
493  slice_feedback,
494  0, 2*f->slice_count*sizeof(uint32_t),
495  VK_FORMAT_UNDEFINED);
497  1, 2, 0,
498  slice_feedback,
499  2*f->slice_count*sizeof(uint32_t),
500  VK_WHOLE_SIZE,
501  VK_FORMAT_UNDEFINED);
503  1, 3, 0,
504  slice_state,
505  f->slice_count*fp->slice_data_size,
506  VK_WHOLE_SIZE,
507  VK_FORMAT_UNDEFINED);
508 
509  AVFrame *decode_dst = is_rgb ? vp->dpb_frame : f->picture.f;
510  VkImageView *decode_dst_view = is_rgb ? rct_image_views : vp->view.out;
511  ff_vk_shader_update_img_array(&ctx->s, exec, &fv->decode,
512  decode_dst, decode_dst_view,
513  1, 4,
514  VK_IMAGE_LAYOUT_GENERAL,
515  VK_NULL_HANDLE);
516  if (is_rgb)
517  ff_vk_shader_update_img_array(&ctx->s, exec, &fv->decode,
518  f->picture.f, vp->view.out,
519  1, 5,
520  VK_IMAGE_LAYOUT_GENERAL,
521  VK_NULL_HANDLE);
522  if (fltmap_buf)
524  1, 6, 0,
525  fltmap_buf,
526  0,
527  VK_WHOLE_SIZE,
528  VK_FORMAT_UNDEFINED);
529 
530  ff_vk_exec_bind_shader(&ctx->s, exec, &fv->decode);
531  ff_vk_shader_update_push_const(&ctx->s, exec, &fv->decode,
532  VK_SHADER_STAGE_COMPUTE_BIT,
533  0, sizeof(FFv1ShaderParams), &pd);
534 
535  vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices, 1);
536 
537  err = ff_vk_exec_submit(&ctx->s, exec);
538  if (err < 0)
539  return err;
540 
541  /* We don't need the temporary frame after decoding */
542  av_frame_free(&vp->dpb_frame);
543 
544 fail:
545  return 0;
546 }
547 
549  FFVkExecPool *pool, FFVulkanShader *shd,
550  VkSpecializationInfo *sl)
551 {
552  int err;
553 
554  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
555  (uint32_t []) { 1, 1, 1 }, 0);
556 
558  VK_SHADER_STAGE_COMPUTE_BIT);
559 
560  const FFVulkanDescriptorSetBinding desc_set_const[] = {
561  { /* rangecoder_buf */
562  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
563  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
564  },
565  { /* crc_ieee_buf */
566  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
567  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
568  },
569  };
570  ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 2, 1, 0);
571 
572  const FFVulkanDescriptorSetBinding desc_set[] = {
573  { /* slice_data_buf */
574  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
575  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
576  },
577  { /* slice_offsets_buf */
578  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
579  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
580  },
581  { /* slice_status_buf */
582  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
583  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
584  },
585  { /* fltmap_buf */
586  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
587  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
588  },
589  };
590  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 4, 0, 0);
591 
592  RET(ff_vk_shader_link(s, shd,
595 
596  RET(ff_vk_shader_register_exec(s, pool, shd));
597 
598 fail:
599  return err;
600 }
601 
603  FFVkExecPool *pool, FFVulkanShader *shd,
604  VkSpecializationInfo *sl, int ac)
605 {
606  int err;
607  int wg_dim = FFMIN(s->props.properties.limits.maxComputeWorkGroupSize[0], 1024);
608 
609  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
610  (uint32_t []) { wg_dim, 1, 1 }, 0);
611 
613  VK_SHADER_STAGE_COMPUTE_BIT);
614 
615  const FFVulkanDescriptorSetBinding desc_set_const[] = {
616  { /* rangecoder_buf */
617  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
618  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
619  },
620  };
621  ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 1, 1, 0);
622 
623  const FFVulkanDescriptorSetBinding desc_set[] = {
624  { /* slice_data_buf */
625  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
626  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
627  },
628  { /* slice_state_buf */
629  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
630  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
631  },
632  };
633  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 2, 0, 0);
634 
635  if (ac == AC_GOLOMB_RICE)
636  RET(ff_vk_shader_link(s, shd,
639  else
640  RET(ff_vk_shader_link(s, shd,
643 
644  RET(ff_vk_shader_register_exec(s, pool, shd));
645 
646 fail:
647  return err;
648 }
649 
651  FFVkExecPool *pool, FFVulkanShader *shd,
652  AVHWFramesContext *dec_frames_ctx,
653  AVHWFramesContext *out_frames_ctx,
654  VkSpecializationInfo *sl, int ac, int rgb)
655 {
656  int err;
657 
658  uint32_t wg_x = ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
659  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
660  (uint32_t []) { wg_x, 1, 1 }, 0);
661 
663  VK_SHADER_STAGE_COMPUTE_BIT);
664 
665  const FFVulkanDescriptorSetBinding desc_set_const[] = {
666  { /* rangecoder_buf */
667  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
668  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
669  },
670  { /* quant_buf */
671  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
672  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
673  },
674  };
675  ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 2, 1, 0);
676 
677  const FFVulkanDescriptorSetBinding desc_set[] = {
678  { /* slice_data_buf */
679  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
680  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
681  },
682  { /* slice_offsets_buf */
683  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
684  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
685  },
686  { /* slice_status_buf */
687  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
688  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
689  },
690  { /* slice_state_buf */
691  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
692  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
693  },
694  { /* dec */
695  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
696  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
697  .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
698  },
699  { /* dst */
700  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
701  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
702  .elems = av_pix_fmt_count_planes(out_frames_ctx->sw_format),
703  },
704  { /* fltmap_buf */
705  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
706  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
707  },
708  };
709  ff_vk_shader_add_descriptor_set(s, shd, desc_set,
710  5 + rgb + (f->micro_version >= 9),
711  0, 0);
712 
713  if (f->version >=4 && f->micro_version >= 9) {
714  if (ac == AC_GOLOMB_RICE)
715  ff_vk_shader_link(s, shd,
718  else
719  ff_vk_shader_link(s, shd,
722  } else if (ac == AC_GOLOMB_RICE) {
723  if (rgb)
724  ff_vk_shader_link(s, shd,
727  else
728  ff_vk_shader_link(s, shd,
731  } else {
732  if (rgb)
733  ff_vk_shader_link(s, shd,
736  else
737  ff_vk_shader_link(s, shd,
739  ff_ffv1_dec_comp_spv_len, "main");
740  }
741 
742  RET(ff_vk_shader_register_exec(s, pool, shd));
743 
744 fail:
745  return err;
746 }
747 
749  AVBufferRef **dst, enum AVPixelFormat sw_format)
750 {
751  int err;
752  AVHWFramesContext *frames_ctx;
753  AVVulkanFramesContext *vk_frames;
754  FFV1Context *f = avctx->priv_data;
755 
756  *dst = av_hwframe_ctx_alloc(s->device_ref);
757  if (!(*dst))
758  return AVERROR(ENOMEM);
759 
760  frames_ctx = (AVHWFramesContext *)((*dst)->data);
761  frames_ctx->format = AV_PIX_FMT_VULKAN;
762  frames_ctx->sw_format = sw_format;
763  frames_ctx->width = s->frames->width;
764  frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
765 
766  vk_frames = frames_ctx->hwctx;
767  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
768  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
769  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
770  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
771 
772  err = av_hwframe_ctx_init(*dst);
773  if (err < 0) {
774  av_log(avctx, AV_LOG_ERROR,
775  "Unable to initialize frame pool with format %s: %s\n",
776  av_get_pix_fmt_name(sw_format), av_err2str(err));
778  return err;
779  }
780 
781  return 0;
782 }
783 
785 {
786  FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
787 
789 
790  ff_vk_shader_free(&ctx->s, &fv->setup);
791  ff_vk_shader_free(&ctx->s, &fv->reset);
792  ff_vk_shader_free(&ctx->s, &fv->decode);
793 
794  ff_vk_free_buf(&ctx->s, &fv->consts_buf);
795 
799 
800  av_freep(&fv);
801 }
802 
804 {
805  int err;
806  FFV1Context *f = avctx->priv_data;
810 
811  if (f->version < 3 ||
812  (f->version == 4 && f->micro_version >= 10))
813  return AVERROR(ENOTSUP);
814 
815  /* Streams with a low amount of slices will usually be much slower
816  * to decode, so warn the user. */
817  if (f->slice_count < 16)
818  av_log(avctx, AV_LOG_WARNING, "Stream has a low number of slices (%i), "
819  "decoding may be very slow\n", f->slice_count);
820 
821  err = ff_vk_decode_init(avctx);
822  if (err < 0)
823  return err;
824  ctx = dec->shared_ctx;
825 
826  fv = ctx->sd_ctx = av_mallocz(sizeof(*fv));
827  if (!fv) {
828  err = AVERROR(ENOMEM);
829  goto fail;
830  }
831 
832  ctx->sd_ctx_free = &vk_decode_ffv1_uninit;
833 
835  AVHWFramesContext *dctx = hwfc;
836  enum AVPixelFormat sw_format = hwfc->sw_format;
837  int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
838  !(sw_format == AV_PIX_FMT_YA8);
839 
840  /* Intermediate frame pool for RCT */
841  if (is_rgb) {
842  RET(init_indirect(avctx, &ctx->s, &fv->intermediate_frames_ref,
843  f->use32bit ? AV_PIX_FMT_GBRAP32 : AV_PIX_FMT_GBRAP16));
845  }
846 
847  SPEC_LIST_CREATE(sl, 15, 15*sizeof(uint32_t))
848  ff_ffv1_vk_set_common_sl(avctx, f, sl, sw_format);
849 
850  if (RGB_LINECACHE != 2)
851  SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
852 
853  if (f->ec && !!(avctx->err_recognition & AV_EF_CRCCHECK))
854  SPEC_LIST_ADD(sl, 1, 32, 1);
855 
856  /* Setup shader */
857  RET(init_setup_shader(f, &ctx->s, &ctx->exec_pool, &fv->setup, sl));
858 
859  /* Reset shader */
860  RET(init_reset_shader(f, &ctx->s, &ctx->exec_pool, &fv->reset, sl, f->ac));
861 
862  /* Decode shaders */
863  RET(init_decode_shader(f, &ctx->s, &ctx->exec_pool, &fv->decode,
864  dctx, hwfc, sl, f->ac, is_rgb));
865 
866  /* Init static data */
868 
869  /* Update setup global descriptors */
870  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
871  &fv->setup, 0, 0, 0,
872  &fv->consts_buf,
873  256*sizeof(uint32_t), 512*sizeof(uint8_t),
874  VK_FORMAT_UNDEFINED));
875  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
876  &fv->setup, 0, 1, 0,
877  &fv->consts_buf,
878  0, 256*sizeof(uint32_t),
879  VK_FORMAT_UNDEFINED));
880 
881  /* Update decode global descriptors */
882  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
883  &fv->decode, 0, 0, 0,
884  &fv->consts_buf,
885  256*sizeof(uint32_t), 512*sizeof(uint8_t),
886  VK_FORMAT_UNDEFINED));
887  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
888  &fv->decode, 0, 1, 0,
889  &fv->consts_buf,
890  256*sizeof(uint32_t) + 512*sizeof(uint8_t),
891  VK_WHOLE_SIZE,
892  VK_FORMAT_UNDEFINED));
893 
894 fail:
895  return err;
896 }
897 
899 {
900  AVHWDeviceContext *dev_ctx = _hwctx.nc;
901  AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
902 
904  FFVulkanDecodePicture *vp = &fp->vp;
905  FFVkBuffer *slice_feedback = (FFVkBuffer *)fp->slice_feedback_buf->data;
906  uint8_t *ssp = slice_feedback->mapped_mem + 2*fp->slice_num*sizeof(uint32_t);
907 
908  ff_vk_decode_free_frame(dev_ctx, vp);
909 
910  /* Invalidate slice/output data if needed */
911  if (!(slice_feedback->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
912  VkMappedMemoryRange invalidate_data = {
913  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
914  .memory = slice_feedback->mem,
915  .offset = 0,
916  .size = 2*fp->slice_num*sizeof(uint32_t),
917  };
919  1, &invalidate_data);
920  }
921 
922  int slice_error_cnt = 0;
923  int crc_mismatch_cnt = 0;
924  uint32_t max_overread = 0;
925  for (int i = 0; i < fp->slice_num; i++) {
926  uint32_t crc_res = 0;
927  if (fp->crc_checked)
928  crc_res = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 0);
929  uint32_t overread = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 4);
930  max_overread = FFMAX(overread, max_overread);
931  slice_error_cnt += !!overread;
932  crc_mismatch_cnt += !!crc_res;
933  }
934  if (slice_error_cnt || crc_mismatch_cnt)
935  av_log(dev_ctx, AV_LOG_ERROR, "Decode status: %i slices overread (%i bytes max), "
936  "%i CRCs mismatched\n",
937  slice_error_cnt, max_overread, crc_mismatch_cnt);
938 
941 }
942 
944  .p.name = "ffv1_vulkan",
945  .p.type = AVMEDIA_TYPE_VIDEO,
946  .p.id = AV_CODEC_ID_FFV1,
947  .p.pix_fmt = AV_PIX_FMT_VULKAN,
948  .start_frame = &vk_ffv1_start_frame,
949  .decode_slice = &vk_ffv1_decode_slice,
950  .end_frame = &vk_ffv1_end_frame,
951  .free_frame_priv = &vk_ffv1_free_frame_priv,
952  .frame_priv_data_size = sizeof(FFv1VulkanDecodePicture),
956  .frame_params = &ff_vk_frame_params,
957  .priv_data_size = sizeof(FFVulkanDecodeContext),
959 };
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
ff_ffv1_dec_reset_comp_spv_len
const unsigned int ff_ffv1_dec_reset_comp_spv_len
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:565
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_ffv1_dec_reset_golomb_comp_spv_data
const unsigned char ff_ffv1_dec_reset_golomb_comp_spv_data[]
FFv1VulkanDecodeContext::slice_feedback_pool
AVBufferPool * slice_feedback_pool
Definition: vulkan_ffv1.c:88
ff_ffv1_dec_rgb_golomb_comp_spv_data
const unsigned char ff_ffv1_dec_rgb_golomb_comp_spv_data[]
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
AV_PIX_FMT_YA8
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition: pixfmt.h:140
ff_vk_shader_free
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition: vulkan.c:2810
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:88
ff_vk_decode_prepare_frame_sdr
int ff_vk_decode_prepare_frame_sdr(FFVulkanDecodeContext *dec, AVFrame *pic, FFVulkanDecodePicture *vkpic, int is_current, enum FFVkShaderRepFormat rep_fmt, int alloc_dpb)
Software-defined decoder version of ff_vk_decode_prepare_frame.
Definition: vulkan_decode.c:249
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FFVulkanDecodeContext::shared_ctx
FFVulkanDecodeShared * shared_ctx
Definition: vulkan_decode.h:55
RET
#define RET(x)
Definition: vulkan.h:68
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
FFv1ShaderParams::fmt_lut
int fmt_lut[4]
Definition: ffv1_vulkan.h:39
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
AVCodecContext::err_recognition
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:1410
AVRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
av_unused
#define av_unused
Definition: attributes.h:156
FFVulkanDecodePicture::invalidate_memory_ranges
PFN_vkInvalidateMappedMemoryRanges invalidate_memory_ranges
Definition: vulkan_decode.h:105
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
FFv1VulkanDecodePicture::slice_data_size
uint32_t slice_data_size
Definition: vulkan_ffv1.c:68
data
const char data[16]
Definition: mxf.c:149
FFVulkanDecodeDescriptor::codec_id
enum AVCodecID codec_id
Definition: vulkan_decode.h:30
FFVkBuffer::address
VkDeviceAddress address
Definition: vulkan.h:130
FFv1VulkanDecodePicture::slice_feedback_buf
AVBufferRef * slice_feedback_buf
Definition: vulkan_ffv1.c:71
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:548
FF_VK_REP_NATIVE
@ FF_VK_REP_NATIVE
Definition: vulkan.h:449
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
SPEC_LIST_ADD
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition: vulkan.h:86
ff_ffv1_dec_rgb_float_golomb_comp_spv_data
const unsigned char ff_ffv1_dec_rgb_float_golomb_comp_spv_data[]
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
ff_vk_exec_bind_shader
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition: vulkan.c:2787
FFVulkanDecodeContext
Definition: vulkan_decode.h:54
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:780
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
FFv1VulkanDecodeContext::slice_state_pool
AVBufferPool * slice_state_pool
Definition: vulkan_ffv1.c:86
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3496
rgb
Definition: rpzaenc.c:60
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:560
FFHWAccel
Definition: hwaccel_internal.h:34
AVVkFrame::img
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Definition: hwcontext_vulkan.h:315
ff_ffv1_dec_rgb_float_golomb_comp_spv_len
const unsigned int ff_ffv1_dec_rgb_float_golomb_comp_spv_len
FFv1VulkanDecodeContext::reset
FFVulkanShader reset
Definition: vulkan_ffv1.c:81
fail
#define fail()
Definition: checkasm.h:223
FFVulkanDecodePicture::sem_value
uint64_t sem_value
Definition: vulkan_decode.h:85
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:558
init_indirect
static int init_indirect(AVCodecContext *avctx, FFVulkanContext *s, AVBufferRef **dst, enum AVPixelFormat sw_format)
Definition: vulkan_ffv1.c:748
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:2738
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:220
ff_vk_frame_barrier
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition: vulkan.c:2050
HWACCEL_CAP_THREAD_SAFE
#define HWACCEL_CAP_THREAD_SAFE
Definition: hwaccel_internal.h:32
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:2603
ff_vk_host_map_buffer
int ff_vk_host_map_buffer(FFVulkanContext *s, AVBufferRef **dst, uint8_t *src_data, const AVBufferRef *src_buf, VkBufferUsageFlags usage)
Maps a system RAM buffer into a Vulkan buffer.
Definition: vulkan.c:1391
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:45
FFv1VulkanDecodeContext::consts_buf
FFVkBuffer consts_buf
Definition: vulkan_ffv1.c:84
FFVulkanDecodeShared
Definition: vulkan_decode.h:38
ff_ffv1_dec_setup_comp_spv_data
const unsigned char ff_ffv1_dec_setup_comp_spv_data[]
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
FFVulkanDescriptorSetBinding::type
VkDescriptorType type
Definition: vulkan.h:114
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:642
init_reset_shader
static int init_reset_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, VkSpecializationInfo *sl, int ac)
Definition: vulkan_ffv1.c:602
s
#define s(width, name)
Definition: cbs_vp9.c:198
FFVulkanDecodePicture
Definition: vulkan_decode.h:73
ff_vk_exec_mirror_sem_value
int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore *dst, uint64_t *dst_val, AVFrame *f)
Definition: vulkan.c:879
ff_ffv1_dec_setup_comp_spv_len
const unsigned int ff_ffv1_dec_setup_comp_spv_len
FFv1VulkanDecodeContext
Definition: vulkan_ffv1.c:77
FFv1VulkanDecodePicture::slice_fltmap_buf
AVBufferRef * slice_fltmap_buf
Definition: vulkan_ffv1.c:70
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:1572
AVVulkanFramesContext::img_flags
VkImageCreateFlags img_flags
Flags to set during image creation.
Definition: hwcontext_vulkan.h:273
AV_PIX_FMT_GBRAP32
#define AV_PIX_FMT_GBRAP32
Definition: pixfmt.h:566
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
FFv1VulkanDecodePicture::vp
FFVulkanDecodePicture vp
Definition: vulkan_ffv1.c:63
vk_ffv1_decode_slice
static int vk_ffv1_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
Definition: vulkan_ffv1.c:199
FFv1VulkanDecodePicture
Definition: vulkan_ffv1.c:62
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:620
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
vk_decode_ffv1_uninit
static void vk_decode_ffv1_uninit(FFVulkanDecodeShared *ctx)
Definition: vulkan_ffv1.c:784
FFv1VulkanDecodePicture::slice_state
AVBufferRef * slice_state
Definition: vulkan_ffv1.c:65
FFv1VulkanDecodePicture::plane_state_size
uint32_t plane_state_size
Definition: vulkan_ffv1.c:66
if
if(ret)
Definition: filter_design.txt:179
FFv1ShaderParams::extend_lookup
uint32_t extend_lookup[8]
Definition: ffv1_vulkan.h:36
ff_ffv1_dec_golomb_comp_spv_len
const unsigned int ff_ffv1_dec_golomb_comp_spv_len
ff_vk_exec_add_dep_wait_sem
int ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore sem, uint64_t val, VkPipelineStageFlagBits2 stage)
Definition: vulkan.c:697
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:59
ff_ffv1_vk_init_consts
int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
Definition: ffv1_vulkan.c:76
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
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:213
AC_GOLOMB_RICE
#define AC_GOLOMB_RICE
Definition: ffv1.h:52
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
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
hwaccel_internal.h
ff_vk_decode_free_frame
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
Definition: vulkan_decode.c:676
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:474
vk_ffv1_end_frame
static int vk_ffv1_end_frame(AVCodecContext *avctx)
Definition: vulkan_ffv1.c:234
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:360
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
ff_vk_decode_uninit
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
Definition: vulkan_decode.c:1280
ff_vk_shader_link
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition: vulkan.c:2376
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:240
SPEC_LIST_CREATE
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition: vulkan.h:76
ffv1_vulkan.h
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:134
FFVulkanContext
Definition: vulkan.h:312
ff_ffv1_dec_rgb_float_comp_spv_len
const unsigned int ff_ffv1_dec_rgb_float_comp_spv_len
ff_vk_frame_params
int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Initialize hw_frames_ctx with the parameters needed to decode the stream using the parameters from av...
Definition: vulkan_decode.c:1141
AV_EF_CRCCHECK
#define AV_EF_CRCCHECK
Verify checksums embedded in the bitstream (could be of either encoded or decoded data,...
Definition: defs.h:48
ff_ffv1_dec_rgb_float_comp_spv_data
const unsigned char ff_ffv1_dec_rgb_float_comp_spv_data[]
ff_ffv1_dec_golomb_comp_spv_data
const unsigned char ff_ffv1_dec_golomb_comp_spv_data[]
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
f
f
Definition: af_crystalizer.c:122
ff_vk_buf_barrier
#define ff_vk_buf_barrier(dst, vkb, s_stage, s_access, s_access2, d_stage, d_access, d_access2, offs, bsz)
Definition: vulkan.h:551
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:550
AVVkFrame::access
VkAccessFlagBits access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
Definition: hwcontext_vulkan.h:339
ff_vk_shader_update_push_const
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Definition: vulkan.c:2777
FFVulkanDescriptorSetBinding
Definition: vulkan.h:112
AV_WN32
#define AV_WN32(p, v)
Definition: intreadwrite.h:372
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:130
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
AVVkFrame
Definition: hwcontext_vulkan.h:310
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
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
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
vk_ffv1_free_frame_priv
static void vk_ffv1_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
Definition: vulkan_ffv1.c:898
init_decode_shader
static int init_decode_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, AVHWFramesContext *dec_frames_ctx, AVHWFramesContext *out_frames_ctx, VkSpecializationInfo *sl, int ac, int rgb)
Definition: vulkan_ffv1.c:650
size
int size
Definition: twinvq_data.h:10344
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:428
FFVulkanShader
Definition: vulkan.h:225
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:128
FFv1VulkanDecodeContext::intermediate_frames_ref
AVBufferRef * intermediate_frames_ref
Definition: vulkan_ffv1.c:78
ff_ffv1_dec_rgb_comp_spv_len
const unsigned int ff_ffv1_dec_rgb_comp_spv_len
FFVkExecContext
Definition: vulkan.h:145
ff_vk_shader_update_desc_buffer
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
Definition: vulkan.c:2751
ff_ffv1_dec_comp_spv_data
const unsigned char ff_ffv1_dec_comp_spv_data[]
ff_ffv1_vk_set_common_sl
void ff_ffv1_vk_set_common_sl(AVCodecContext *avctx, FFV1Context *f, VkSpecializationInfo *sl, enum AVPixelFormat sw_format)
Definition: ffv1_vulkan.c:24
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:1961
FF_VK_EXT_EXTERNAL_HOST_MEMORY
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY
Definition: vulkan_functions.h:36
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
ff_ffv1_dec_comp_spv_len
const unsigned int ff_ffv1_dec_comp_spv_len
FFVulkanDecodePicture::out
VkImageView out[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:78
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:560
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@340 view
FFv1VulkanDecodePicture::slice_state_size
uint32_t slice_state_size
Definition: vulkan_ffv1.c:67
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:559
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ffv1.h
FFVkBuffer::mem
VkDeviceMemory mem
Definition: vulkan.h:127
FFVulkanDecodePicture::sem
VkSemaphore sem
Definition: vulkan_decode.h:84
FFv1VulkanDecodeContext::slice_fltmap_pool
AVBufferPool * slice_fltmap_pool
Definition: vulkan_ffv1.c:87
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition: vulkan.c:1244
ff_ffv1_dec_reset_golomb_comp_spv_len
const unsigned int ff_ffv1_dec_reset_golomb_comp_spv_len
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:1465
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
ff_ffv1_vulkan_hwaccel
const FFHWAccel ff_ffv1_vulkan_hwaccel
Definition: vulkan_ffv1.c:943
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:1967
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
FFVkExecPool
Definition: vulkan.h:290
ff_vk_decode_add_slice
int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp, const uint8_t *data, size_t size, int add_startcode, uint32_t *nb_slices, const uint32_t **offsets)
Add slice data to frame.
Definition: vulkan_decode.c:296
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:1489
init_setup_shader
static int init_setup_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, VkSpecializationInfo *sl)
Definition: vulkan_ffv1.c:548
AVCodecContext
main external API structure.
Definition: avcodec.h:439
ff_vk_shader_add_descriptor_set
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular, int print_to_shader_only)
Add descriptor to a shader.
Definition: vulkan.c:2503
FFv1VulkanDecodeContext::decode
FFVulkanShader decode
Definition: vulkan_ffv1.c:82
ff_vk_dec_ffv1_desc
const FFVulkanDecodeDescriptor ff_vk_dec_ffv1_desc
Definition: vulkan_ffv1.c:57
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
update_thread_context
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have update_thread_context() run it in the next thread. Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little speed gain at this point but it should work. Use ff_thread_get_buffer()(or ff_progress_frame_get_buffer() in case you have inter-frame dependencies and use the ProgressFrame API) to allocate frame buffers. Call ff_progress_frame_report() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
FFVulkanDecodeDescriptor
Definition: vulkan_decode.h:29
FFv1VulkanDecodePicture::slice_offset
uint32_t * slice_offset
Definition: vulkan_ffv1.c:72
ff_ffv1_dec_reset_comp_spv_data
const unsigned char ff_ffv1_dec_reset_comp_spv_data[]
FFVulkanDecodePicture::dpb_frame
AVFrame * dpb_frame
Definition: vulkan_decode.h:74
ff_vk_update_thread_context
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
Definition: vulkan_decode.c:134
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:229
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFVulkanDecodePicture::slices_buf
AVBufferRef * slices_buf
Definition: vulkan_decode.h:99
mem.h
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:340
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:84
vulkan_decode.h
FFV1Context
Definition: ffv1.h:122
FFv1ShaderParams
Definition: ffv1_vulkan.h:33
ff_vk_count_images
static int ff_vk_count_images(AVVkFrame *f)
Definition: vulkan.h:366
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
FFv1VulkanDecodeContext::setup
FFVulkanShader setup
Definition: vulkan_ffv1.c:80
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFVkBuffer
Definition: vulkan.h:125
FFv1ShaderParams::context_count
uint16_t context_count[8]
Definition: ffv1_vulkan.h:37
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:905
ff_ffv1_dec_rgb_golomb_comp_spv_len
const unsigned int ff_ffv1_dec_rgb_golomb_comp_spv_len
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_vk_decode_init
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
Definition: vulkan_decode.c:1291
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:646
FFv1ShaderParams::slice_data
VkDeviceAddress slice_data
Definition: ffv1_vulkan.h:34
FFv1VulkanDecodePicture::crc_checked
int crc_checked
Definition: vulkan_ffv1.c:74
ff_ffv1_dec_rgb_comp_spv_data
const unsigned char ff_ffv1_dec_rgb_comp_spv_data[]
RGB_LINECACHE
#define RGB_LINECACHE
Definition: vulkan_ffv1.c:28
av_hwframe_get_buffer
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:506
FFVulkanFunctions
Definition: vulkan_functions.h:274
ff_vk_shader_load
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
Definition: vulkan.c:2093
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:1286
vk_ffv1_start_frame
static int vk_ffv1_start_frame(AVCodecContext *avctx, const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vulkan_ffv1.c:91
vk_decode_ffv1_init
static int vk_decode_ffv1_init(AVCodecContext *avctx)
Definition: vulkan_ffv1.c:803
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3376
FFv1VulkanDecodePicture::slice_num
int slice_num
Definition: vulkan_ffv1.c:73