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 
53  .queue_flags = VK_QUEUE_COMPUTE_BIT,
54 };
55 
56 typedef struct FFv1VulkanDecodePicture {
58 
60  uint32_t plane_state_size;
61  uint32_t slice_state_size;
62  uint32_t slice_data_size;
63 
65  uint32_t *slice_offset;
66  int slice_num;
69 
70 typedef struct FFv1VulkanDecodeContext {
72 
76 
78 
82 
84  const AVBufferRef *buffer_ref,
85  av_unused const uint8_t *buffer,
86  av_unused uint32_t size)
87 {
88  int err;
91  FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
92  FFV1Context *f = avctx->priv_data;
93 
94  FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
95  FFVulkanDecodePicture *vp = &fp->vp;
96 
98  enum AVPixelFormat sw_format = hwfc->sw_format;
99 
100  int max_contexts;
101  int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
102  !(sw_format == AV_PIX_FMT_YA8);
103 
104  fp->slice_num = 0;
105 
106  max_contexts = 0;
107  for (int i = 0; i < f->quant_table_count; i++)
108  max_contexts = FFMAX(f->context_count[i], max_contexts);
109 
110  /* Allocate slice buffer data */
111  if (f->ac == AC_GOLOMB_RICE)
112  fp->plane_state_size = 8;
113  else
115 
116  fp->plane_state_size *= max_contexts;
117  fp->slice_state_size = fp->plane_state_size*f->plane_count;
118 
119  fp->slice_data_size = 256; /* Overestimation for the SliceContext struct */
122 
123  fp->crc_checked = f->ec && (avctx->err_recognition & AV_EF_CRCCHECK);
124 
125  /* Host map the input slices data if supported */
126  if (ctx->s.extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY)
127  ff_vk_host_map_buffer(&ctx->s, &vp->slices_buf, buffer_ref->data,
128  buffer_ref,
129  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
130  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
131 
132  /* Allocate slice state data */
133  if (f->picture.f->flags & AV_FRAME_FLAG_KEY) {
135  &fp->slice_state,
136  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
137  NULL, f->slice_count*fp->slice_state_size,
138  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
139  if (err < 0)
140  return err;
141  } else {
142  FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private;
144  if (!fp->slice_state)
145  return AVERROR(ENOMEM);
146  }
147 
148  /* Allocate slice offsets/status buffer */
150  &fp->slice_feedback_buf,
151  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
152  NULL, 2*(2*f->slice_count*sizeof(uint32_t)),
153  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
154  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
155  if (err < 0)
156  return err;
157 
158  /* Prepare frame to be used */
159  err = ff_vk_decode_prepare_frame_sdr(dec, f->picture.f, vp, 1,
160  FF_VK_REP_NATIVE, 0);
161  if (err < 0)
162  return err;
163 
164  /* Create a temporaty frame for RGB */
165  if (is_rgb) {
166  vp->dpb_frame = av_frame_alloc();
167  if (!vp->dpb_frame)
168  return AVERROR(ENOMEM);
169 
171  vp->dpb_frame, 0);
172  if (err < 0)
173  return err;
174  }
175 
176  return 0;
177 }
178 
180  const uint8_t *data,
181  uint32_t size)
182 {
183  FFV1Context *f = avctx->priv_data;
184 
185  FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
186  FFVulkanDecodePicture *vp = &fp->vp;
187 
188  FFVkBuffer *slice_offset = (FFVkBuffer *)fp->slice_feedback_buf->data;
189  FFVkBuffer *slices_buf = vp->slices_buf ? (FFVkBuffer *)vp->slices_buf->data : NULL;
190 
191  if (slices_buf && slices_buf->host_ref) {
192  AV_WN32(slice_offset->mapped_mem + (2*fp->slice_num + 0)*sizeof(uint32_t),
193  data - slices_buf->mapped_mem);
194  AV_WN32(slice_offset->mapped_mem + (2*fp->slice_num + 1)*sizeof(uint32_t),
195  size);
196 
197  fp->slice_num++;
198  } else {
199  int err = ff_vk_decode_add_slice(avctx, vp, data, size, 0,
200  &fp->slice_num,
201  (const uint32_t **)&fp->slice_offset);
202  if (err < 0)
203  return err;
204 
205  AV_WN32(slice_offset->mapped_mem + (2*(fp->slice_num - 1) + 0)*sizeof(uint32_t),
206  fp->slice_offset[fp->slice_num - 1]);
207  AV_WN32(slice_offset->mapped_mem + (2*(fp->slice_num - 1) + 1)*sizeof(uint32_t),
208  size);
209  }
210 
211  return 0;
212 }
213 
215 {
216  int err;
219  FFVulkanFunctions *vk = &ctx->s.vkfn;
220 
221  FFV1Context *f = avctx->priv_data;
222  FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
223 
225  enum AVPixelFormat sw_format = hwfc->sw_format;
226 
227  int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
228  !(sw_format == AV_PIX_FMT_YA8);
229  int color_planes = av_pix_fmt_desc_get(avctx->sw_pix_fmt)->nb_components;
230 
231  FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
232  FFVulkanDecodePicture *vp = &fp->vp;
233 
234  FFVkBuffer *slices_buf = (FFVkBuffer *)vp->slices_buf->data;
235  FFVkBuffer *slice_state = (FFVkBuffer *)fp->slice_state->data;
236  FFVkBuffer *slice_feedback = (FFVkBuffer *)fp->slice_feedback_buf->data;
237 
238  VkImageView rct_image_views[AV_NUM_DATA_POINTERS];
239 
240  VkImageMemoryBarrier2 img_bar[37];
241  int nb_img_bar = 0;
242  VkBufferMemoryBarrier2 buf_bar[8];
243  int nb_buf_bar = 0;
244 
245  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
246  ff_vk_exec_start(&ctx->s, exec);
247 
248  /* Prepare deps */
249  RET(ff_vk_exec_add_dep_frame(&ctx->s, exec, f->picture.f,
250  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
251  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
252 
253  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
254  f->picture.f);
255  if (err < 0)
256  return err;
257 
258  if (is_rgb) {
259  RET(ff_vk_create_imageviews(&ctx->s, exec, rct_image_views,
261  RET(ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
262  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
263  VK_PIPELINE_STAGE_2_CLEAR_BIT));
264  }
265 
266  if (!(f->picture.f->flags & AV_FRAME_FLAG_KEY)) {
267  FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private;
268  FFVulkanDecodePicture *vpl = &fpl->vp;
269 
270  /* Wait on the previous frame */
271  RET(ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, vpl->sem_value,
272  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT));
273  }
274 
275  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_state, 1, 1));
276  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_feedback_buf, 1, 1));
277  RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0));
278  vp->slices_buf = NULL;
279 
280  AVVkFrame *vkf = (AVVkFrame *)f->picture.f->data[0];
281  for (int i = 0; i < ff_vk_count_images(vkf); i++) {
282  vkf->layout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
283  vkf->access[i] = VK_ACCESS_2_NONE;
284  }
285 
286  /* Setup shader */
287  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
288  1, 0, 0,
289  slice_state,
290  0, fp->slice_data_size*f->slice_count,
291  VK_FORMAT_UNDEFINED);
292  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
293  1, 1, 0,
294  slice_feedback,
295  0, 2*f->slice_count*sizeof(uint32_t),
296  VK_FORMAT_UNDEFINED);
297  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
298  1, 2, 0,
299  slice_feedback,
300  2*f->slice_count*sizeof(uint32_t),
301  VK_WHOLE_SIZE,
302  VK_FORMAT_UNDEFINED);
303 
304  ff_vk_exec_bind_shader(&ctx->s, exec, &fv->setup);
305 
306  FFv1ShaderParams pd = {
307  .slice_data = slices_buf->address,
308 
309  .img_size[0] = f->picture.f->width,
310  .img_size[1] = f->picture.f->height,
311 
312  .plane_state_size = fp->plane_state_size,
313  .key_frame = f->picture.f->flags & AV_FRAME_FLAG_KEY,
314  .crcref = f->crcref,
315  .micro_version = f->micro_version,
316  };
317 
318  for (int i = 0; i < f->quant_table_count; i++) {
319  pd.context_count[i] = f->context_count[i];
320  pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
321  f->quant_tables[i][4][127];
322  }
323 
324  /* For some reason the C FFv1 encoder/decoder treats these differently */
325  if (sw_format == AV_PIX_FMT_GBRP10 || sw_format == AV_PIX_FMT_GBRP12 ||
326  sw_format == AV_PIX_FMT_GBRP14)
327  memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
328  else
329  ff_vk_set_perm(sw_format, pd.fmt_lut, 0);
330 
331  ff_vk_shader_update_push_const(&ctx->s, exec, &fv->setup,
332  VK_SHADER_STAGE_COMPUTE_BIT,
333  0, sizeof(FFv1ShaderParams), &pd);
334 
335  vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices, 1);
336 
337  if (is_rgb) {
338  vkf = (AVVkFrame *)vp->dpb_frame->data[0];
339  for (int i = 0; i < 4; i++) {
340  vkf->layout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
341  vkf->access[i] = VK_ACCESS_2_NONE;
342  }
343 
344  ff_vk_frame_barrier(&ctx->s, exec, vp->dpb_frame, img_bar, &nb_img_bar,
345  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
346  VK_PIPELINE_STAGE_2_CLEAR_BIT,
347  VK_ACCESS_2_TRANSFER_WRITE_BIT,
348  VK_IMAGE_LAYOUT_GENERAL,
349  VK_QUEUE_FAMILY_IGNORED);
350 
351  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
352  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
353  .pImageMemoryBarriers = img_bar,
354  .imageMemoryBarrierCount = nb_img_bar,
355  .pBufferMemoryBarriers = buf_bar,
356  .bufferMemoryBarrierCount = nb_buf_bar,
357  });
358  nb_img_bar = 0;
359  nb_buf_bar = 0;
360 
361  for (int i = 0; i < color_planes; i++)
362  vk->CmdClearColorImage(exec->buf, vkf->img[i], VK_IMAGE_LAYOUT_GENERAL,
363  &((VkClearColorValue) { 0 }),
364  1, &((VkImageSubresourceRange) {
365  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
366  .levelCount = 1,
367  .layerCount = 1,
368  }));
369  }
370 
371  /* Sync between setup and reset shaders */
372  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
373  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
374  SHADER_STORAGE_WRITE_BIT,
375  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT, NONE_KHR,
376  0, fp->slice_data_size*f->slice_count);
377 
378  /* Probability data barrier for P-frames */
379  if (!(f->picture.f->flags & AV_FRAME_FLAG_KEY))
380  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
381  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
382  SHADER_STORAGE_WRITE_BIT,
383  COMPUTE_SHADER_BIT, SHADER_STORAGE_WRITE_BIT, NONE_KHR,
384  fp->slice_data_size*f->slice_count, VK_WHOLE_SIZE);
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_buf_bar = 0;
394  nb_img_bar = 0;
395 
396  /* Reset shader */
397  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->reset,
398  1, 0, 0,
399  slice_state,
400  0, fp->slice_data_size*f->slice_count,
401  VK_FORMAT_UNDEFINED);
402  ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->reset,
403  1, 1, 0,
404  slice_state,
405  f->slice_count*fp->slice_data_size,
406  VK_WHOLE_SIZE,
407  VK_FORMAT_UNDEFINED);
408 
409  ff_vk_exec_bind_shader(&ctx->s, exec, &fv->reset);
410  ff_vk_shader_update_push_const(&ctx->s, exec, &fv->reset,
411  VK_SHADER_STAGE_COMPUTE_BIT,
412  0, sizeof(FFv1ShaderParams), &pd);
413 
414  vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices,
415  f->plane_count);
416 
417  /* Sync probabilities between reset and decode shaders */
418  ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
419  COMPUTE_SHADER_BIT, SHADER_STORAGE_WRITE_BIT, NONE_KHR,
420  COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
421  SHADER_STORAGE_WRITE_BIT,
422  fp->slice_data_size*f->slice_count, VK_WHOLE_SIZE);
423 
424  /* Input frame barrier */
425  ff_vk_frame_barrier(&ctx->s, exec, f->picture.f, img_bar, &nb_img_bar,
426  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
427  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
428  VK_ACCESS_SHADER_WRITE_BIT |
429  (!is_rgb ? VK_ACCESS_SHADER_READ_BIT : 0),
430  VK_IMAGE_LAYOUT_GENERAL,
431  VK_QUEUE_FAMILY_IGNORED);
432  if (is_rgb)
433  ff_vk_frame_barrier(&ctx->s, exec, vp->dpb_frame, img_bar, &nb_img_bar,
434  VK_PIPELINE_STAGE_2_CLEAR_BIT,
435  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
436  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
437  VK_IMAGE_LAYOUT_GENERAL,
438  VK_QUEUE_FAMILY_IGNORED);
439 
440  vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
441  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
442  .pImageMemoryBarriers = img_bar,
443  .imageMemoryBarrierCount = nb_img_bar,
444  .pBufferMemoryBarriers = buf_bar,
445  .bufferMemoryBarrierCount = nb_buf_bar,
446  });
447  nb_img_bar = 0;
448  nb_buf_bar = 0;
449 
450  /* Decode */
452  1, 0, 0,
453  slice_state,
454  0, fp->slice_data_size*f->slice_count,
455  VK_FORMAT_UNDEFINED);
457  1, 1, 0,
458  slice_feedback,
459  0, 2*f->slice_count*sizeof(uint32_t),
460  VK_FORMAT_UNDEFINED);
462  1, 2, 0,
463  slice_feedback,
464  2*f->slice_count*sizeof(uint32_t),
465  VK_WHOLE_SIZE,
466  VK_FORMAT_UNDEFINED);
468  1, 3, 0,
469  slice_state,
470  f->slice_count*fp->slice_data_size,
471  VK_WHOLE_SIZE,
472  VK_FORMAT_UNDEFINED);
473 
474  AVFrame *decode_dst = is_rgb ? vp->dpb_frame : f->picture.f;
475  VkImageView *decode_dst_view = is_rgb ? rct_image_views : vp->view.out;
476  ff_vk_shader_update_img_array(&ctx->s, exec, &fv->decode,
477  decode_dst, decode_dst_view,
478  1, 4,
479  VK_IMAGE_LAYOUT_GENERAL,
480  VK_NULL_HANDLE);
481  if (is_rgb)
482  ff_vk_shader_update_img_array(&ctx->s, exec, &fv->decode,
483  f->picture.f, vp->view.out,
484  1, 5,
485  VK_IMAGE_LAYOUT_GENERAL,
486  VK_NULL_HANDLE);
487 
488  ff_vk_exec_bind_shader(&ctx->s, exec, &fv->decode);
489  ff_vk_shader_update_push_const(&ctx->s, exec, &fv->decode,
490  VK_SHADER_STAGE_COMPUTE_BIT,
491  0, sizeof(FFv1ShaderParams), &pd);
492 
493  vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices, 1);
494 
495  err = ff_vk_exec_submit(&ctx->s, exec);
496  if (err < 0)
497  return err;
498 
499  /* We don't need the temporary frame after decoding */
500  av_frame_free(&vp->dpb_frame);
501 
502 fail:
503  return 0;
504 }
505 
507  FFVkExecPool *pool, FFVulkanShader *shd,
508  VkSpecializationInfo *sl)
509 {
510  int err;
511 
512  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
513  (uint32_t []) { 1, 1, 1 }, 0);
514 
516  VK_SHADER_STAGE_COMPUTE_BIT);
517 
518  const FFVulkanDescriptorSetBinding desc_set_const[] = {
519  { /* rangecoder_buf */
520  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
521  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
522  },
523  { /* crc_ieee_buf */
524  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
525  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
526  },
527  };
528  ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 2, 1, 0);
529 
530  const FFVulkanDescriptorSetBinding desc_set[] = {
531  { /* slice_data_buf */
532  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
533  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
534  },
535  { /* slice_offsets_buf */
536  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
537  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
538  },
539  { /* slice_status_buf */
540  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
541  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
542  },
543  };
544  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 3, 0, 0);
545 
546  RET(ff_vk_shader_link(s, shd,
549 
550  RET(ff_vk_shader_register_exec(s, pool, shd));
551 
552 fail:
553  return err;
554 }
555 
557  FFVkExecPool *pool, FFVulkanShader *shd,
558  VkSpecializationInfo *sl, int ac)
559 {
560  int err;
561  int wg_dim = FFMIN(s->props.properties.limits.maxComputeWorkGroupSize[0], 1024);
562 
563  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
564  (uint32_t []) { wg_dim, 1, 1 }, 0);
565 
567  VK_SHADER_STAGE_COMPUTE_BIT);
568 
569  const FFVulkanDescriptorSetBinding desc_set_const[] = {
570  { /* rangecoder_buf */
571  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
572  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
573  },
574  };
575  ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 1, 1, 0);
576 
577  const FFVulkanDescriptorSetBinding desc_set[] = {
578  { /* slice_data_buf */
579  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
580  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
581  },
582  { /* slice_state_buf */
583  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
584  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
585  },
586  };
587  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 2, 0, 0);
588 
589  if (ac == AC_GOLOMB_RICE)
590  RET(ff_vk_shader_link(s, shd,
593  else
594  RET(ff_vk_shader_link(s, shd,
597 
598  RET(ff_vk_shader_register_exec(s, pool, shd));
599 
600 fail:
601  return err;
602 }
603 
605  FFVkExecPool *pool, FFVulkanShader *shd,
606  AVHWFramesContext *dec_frames_ctx,
607  AVHWFramesContext *out_frames_ctx,
608  VkSpecializationInfo *sl, int ac, int rgb)
609 {
610  int err;
611 
612  uint32_t wg_x = ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
613  ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
614  (uint32_t []) { wg_x, 1, 1 }, 0);
615 
617  VK_SHADER_STAGE_COMPUTE_BIT);
618 
619  const FFVulkanDescriptorSetBinding desc_set_const[] = {
620  { /* rangecoder_buf */
621  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
622  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
623  },
624  { /* quant_buf */
625  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
626  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
627  },
628  };
629  ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 2, 1, 0);
630 
631  const FFVulkanDescriptorSetBinding desc_set[] = {
632  { /* slice_data_buf */
633  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
634  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
635  },
636  { /* slice_offsets_buf */
637  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
638  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
639  },
640  { /* slice_status_buf */
641  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
642  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
643  },
644  { /* slice_state_buf */
645  .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
646  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
647  },
648  { /* dec */
649  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
650  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
651  .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
652  },
653  { /* dst */
654  .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
655  .stages = VK_SHADER_STAGE_COMPUTE_BIT,
656  .elems = av_pix_fmt_count_planes(out_frames_ctx->sw_format),
657  },
658  };
659  ff_vk_shader_add_descriptor_set(s, shd, desc_set, 5 + rgb, 0, 0);
660 
661  if (ac == AC_GOLOMB_RICE) {
662  if (rgb)
663  ff_vk_shader_link(s, shd,
666  else
667  ff_vk_shader_link(s, shd,
670  } else {
671  if (rgb)
672  ff_vk_shader_link(s, shd,
675  else
676  ff_vk_shader_link(s, shd,
678  ff_ffv1_dec_comp_spv_len, "main");
679  }
680 
681  RET(ff_vk_shader_register_exec(s, pool, shd));
682 
683 fail:
684  return err;
685 }
686 
688  AVBufferRef **dst, enum AVPixelFormat sw_format)
689 {
690  int err;
691  AVHWFramesContext *frames_ctx;
692  AVVulkanFramesContext *vk_frames;
693  FFV1Context *f = avctx->priv_data;
694 
695  *dst = av_hwframe_ctx_alloc(s->device_ref);
696  if (!(*dst))
697  return AVERROR(ENOMEM);
698 
699  frames_ctx = (AVHWFramesContext *)((*dst)->data);
700  frames_ctx->format = AV_PIX_FMT_VULKAN;
701  frames_ctx->sw_format = sw_format;
702  frames_ctx->width = s->frames->width;
703  frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
704 
705  vk_frames = frames_ctx->hwctx;
706  vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
707  vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
708  vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
709  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
710 
711  err = av_hwframe_ctx_init(*dst);
712  if (err < 0) {
713  av_log(avctx, AV_LOG_ERROR,
714  "Unable to initialize frame pool with format %s: %s\n",
715  av_get_pix_fmt_name(sw_format), av_err2str(err));
717  return err;
718  }
719 
720  return 0;
721 }
722 
724 {
725  FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
726 
728 
729  ff_vk_shader_free(&ctx->s, &fv->setup);
730  ff_vk_shader_free(&ctx->s, &fv->reset);
731  ff_vk_shader_free(&ctx->s, &fv->decode);
732 
733  ff_vk_free_buf(&ctx->s, &fv->consts_buf);
734 
737 
738  av_freep(&fv);
739 }
740 
742 {
743  int err;
744  FFV1Context *f = avctx->priv_data;
748 
749  if (f->version < 3 ||
750  (f->version == 4 && f->micro_version > 3))
751  return AVERROR(ENOTSUP);
752 
753  err = ff_vk_decode_init(avctx);
754  if (err < 0)
755  return err;
756  ctx = dec->shared_ctx;
757 
758  fv = ctx->sd_ctx = av_mallocz(sizeof(*fv));
759  if (!fv) {
760  err = AVERROR(ENOMEM);
761  goto fail;
762  }
763 
764  ctx->sd_ctx_free = &vk_decode_ffv1_uninit;
765 
767  AVHWFramesContext *dctx = hwfc;
768  enum AVPixelFormat sw_format = hwfc->sw_format;
769  int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
770  !(sw_format == AV_PIX_FMT_YA8);
771 
772  /* Intermediate frame pool for RCT */
773  if (is_rgb) {
774  RET(init_indirect(avctx, &ctx->s, &fv->intermediate_frames_ref,
775  f->use32bit ? AV_PIX_FMT_GBRAP32 : AV_PIX_FMT_GBRAP16));
777  }
778 
779  SPEC_LIST_CREATE(sl, 15, 15*sizeof(uint32_t))
780  ff_ffv1_vk_set_common_sl(avctx, f, sl, sw_format);
781 
782  if (RGB_LINECACHE != 2)
783  SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
784 
785  if (f->ec && !!(avctx->err_recognition & AV_EF_CRCCHECK))
786  SPEC_LIST_ADD(sl, 1, 32, 1);
787 
788  /* Setup shader */
789  RET(init_setup_shader(f, &ctx->s, &ctx->exec_pool, &fv->setup, sl));
790 
791  /* Reset shader */
792  RET(init_reset_shader(f, &ctx->s, &ctx->exec_pool, &fv->reset, sl, f->ac));
793 
794  /* Decode shaders */
795  RET(init_decode_shader(f, &ctx->s, &ctx->exec_pool, &fv->decode,
796  dctx, hwfc, sl, f->ac, is_rgb));
797 
798  /* Init static data */
800 
801  /* Update setup global descriptors */
802  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
803  &fv->setup, 0, 0, 0,
804  &fv->consts_buf,
805  256*sizeof(uint32_t), 512*sizeof(uint8_t),
806  VK_FORMAT_UNDEFINED));
807  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
808  &fv->setup, 0, 1, 0,
809  &fv->consts_buf,
810  0, 256*sizeof(uint32_t),
811  VK_FORMAT_UNDEFINED));
812 
813  /* Update decode global descriptors */
814  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
815  &fv->decode, 0, 0, 0,
816  &fv->consts_buf,
817  256*sizeof(uint32_t), 512*sizeof(uint8_t),
818  VK_FORMAT_UNDEFINED));
819  RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
820  &fv->decode, 0, 1, 0,
821  &fv->consts_buf,
822  256*sizeof(uint32_t) + 512*sizeof(uint8_t),
823  VK_WHOLE_SIZE,
824  VK_FORMAT_UNDEFINED));
825 
826 fail:
827  return err;
828 }
829 
831 {
832  AVHWDeviceContext *dev_ctx = _hwctx.nc;
833  AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
834 
836  FFVulkanDecodePicture *vp = &fp->vp;
837  FFVkBuffer *slice_feedback = (FFVkBuffer *)fp->slice_feedback_buf->data;
838  uint8_t *ssp = slice_feedback->mapped_mem + 2*fp->slice_num*sizeof(uint32_t);
839 
840  ff_vk_decode_free_frame(dev_ctx, vp);
841 
842  /* Invalidate slice/output data if needed */
843  if (!(slice_feedback->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
844  VkMappedMemoryRange invalidate_data = {
845  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
846  .memory = slice_feedback->mem,
847  .offset = 0,
848  .size = 2*fp->slice_num*sizeof(uint32_t),
849  };
851  1, &invalidate_data);
852  }
853 
854  int slice_error_cnt = 0;
855  int crc_mismatch_cnt = 0;
856  uint32_t max_overread = 0;
857  for (int i = 0; i < fp->slice_num; i++) {
858  uint32_t crc_res = 0;
859  if (fp->crc_checked)
860  crc_res = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 0);
861  uint32_t overread = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 4);
862  max_overread = FFMAX(overread, max_overread);
863  slice_error_cnt += !!overread;
864  crc_mismatch_cnt += !!crc_res;
865  }
866  if (slice_error_cnt || crc_mismatch_cnt)
867  av_log(dev_ctx, AV_LOG_ERROR, "Decode status: %i slices overread (%i bytes max), "
868  "%i CRCs mismatched\n",
869  slice_error_cnt, max_overread, crc_mismatch_cnt);
870 
873 }
874 
876  .p.name = "ffv1_vulkan",
877  .p.type = AVMEDIA_TYPE_VIDEO,
878  .p.id = AV_CODEC_ID_FFV1,
879  .p.pix_fmt = AV_PIX_FMT_VULKAN,
880  .start_frame = &vk_ffv1_start_frame,
881  .decode_slice = &vk_ffv1_decode_slice,
882  .end_frame = &vk_ffv1_end_frame,
883  .free_frame_priv = &vk_ffv1_free_frame_priv,
884  .frame_priv_data_size = sizeof(FFv1VulkanDecodePicture),
888  .frame_params = &ff_vk_frame_params,
889  .priv_data_size = sizeof(FFVulkanDecodeContext),
891 };
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
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:80
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:2789
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:1406
AVRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
av_unused
#define av_unused
Definition: attributes.h:151
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:62
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:64
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:546
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
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
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:778
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:79
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:307
FFv1VulkanDecodeContext::reset
FFVulkanShader reset
Definition: vulkan_ffv1.c:74
fail
#define fail()
Definition: checkasm.h:218
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:687
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:2717
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:212
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:2029
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:2582
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:1381
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:45
FFv1VulkanDecodeContext::consts_buf
FFVkBuffer consts_buf
Definition: vulkan_ffv1.c:77
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:556
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:877
ff_ffv1_dec_setup_comp_spv_len
const unsigned int ff_ffv1_dec_setup_comp_spv_len
FFv1VulkanDecodeContext
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:1561
AVVulkanFramesContext::img_flags
VkImageCreateFlags img_flags
Flags to set during image creation.
Definition: hwcontext_vulkan.h:265
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:57
vk_ffv1_decode_slice
static int vk_ffv1_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
Definition: vulkan_ffv1.c:179
FFv1VulkanDecodePicture
Definition: vulkan_ffv1.c:56
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:618
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:723
FFv1VulkanDecodePicture::slice_state
AVBufferRef * slice_state
Definition: vulkan_ffv1.c:59
FFv1VulkanDecodePicture::plane_state_size
uint32_t plane_state_size
Definition: vulkan_ffv1.c:60
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:695
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:214
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:2355
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:232
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_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_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:331
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:2756
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:302
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:830
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:604
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:71
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:2730
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:1957
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
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@332 view
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:558
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFv1VulkanDecodePicture::slice_state_size
uint32_t slice_state_size
Definition: vulkan_ffv1.c:61
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
ff_vk_free_buf
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition: vulkan.c:1234
ff_ffv1_dec_reset_golomb_comp_spv_len
const unsigned int ff_ffv1_dec_reset_golomb_comp_spv_len
ff_vk_exec_bind_shader
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd)
Bind a shader.
Definition: vulkan.c:2766
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:1461
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:875
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:1946
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:1479
init_setup_shader
static int init_setup_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, VkSpecializationInfo *sl)
Definition: vulkan_ffv1.c:506
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:2482
FFv1VulkanDecodeContext::decode
FFVulkanShader decode
Definition: vulkan_ffv1.c:75
ff_vk_dec_ffv1_desc
const FFVulkanDecodeDescriptor ff_vk_dec_ffv1_desc
Definition: vulkan_ffv1.c:51
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:65
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:221
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:332
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:73
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:903
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:67
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:2072
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:1276
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:83
vk_decode_ffv1_init
static int vk_decode_ffv1_init(AVCodecContext *avctx)
Definition: vulkan_ffv1.c:741
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:66