FFmpeg
vulkan_decode.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/refstruct.h"
20 #include "vulkan_video.h"
21 #include "vulkan_decode.h"
22 #include "config_components.h"
23 #include "libavutil/avassert.h"
24 #include "libavutil/mem.h"
26 
27 #define DECODER_IS_SDR(codec_id) \
28  (((codec_id) == AV_CODEC_ID_FFV1) || \
29  ((codec_id) == AV_CODEC_ID_PRORES_RAW))
30 
31 #if CONFIG_H264_VULKAN_HWACCEL
33 #endif
34 #if CONFIG_HEVC_VULKAN_HWACCEL
36 #endif
37 #if CONFIG_VP9_VULKAN_HWACCEL
39 #endif
40 #if CONFIG_AV1_VULKAN_HWACCEL
42 #endif
43 #if CONFIG_FFV1_VULKAN_HWACCEL
45 #endif
46 #if CONFIG_PRORES_RAW_VULKAN_HWACCEL
48 #endif
49 
51 #if CONFIG_H264_VULKAN_HWACCEL
53 #endif
54 #if CONFIG_HEVC_VULKAN_HWACCEL
56 #endif
57 #if CONFIG_VP9_VULKAN_HWACCEL
59 #endif
60 #if CONFIG_AV1_VULKAN_HWACCEL
62 #endif
63 #if CONFIG_FFV1_VULKAN_HWACCEL
65 #endif
66 #if CONFIG_PRORES_RAW_VULKAN_HWACCEL
68 #endif
69 };
70 
71 typedef struct FFVulkanDecodeProfileData {
72  VkVideoDecodeH264ProfileInfoKHR h264_profile;
73  VkVideoDecodeH265ProfileInfoKHR h265_profile;
74 #if CONFIG_VP9_VULKAN_HWACCEL
75  VkVideoDecodeVP9ProfileInfoKHR vp9_profile;
76 #endif
77  VkVideoDecodeAV1ProfileInfoKHR av1_profile;
78 
79  VkVideoDecodeUsageInfoKHR usage;
80  VkVideoProfileInfoKHR profile;
81  VkVideoProfileListInfoKHR profile_list;
83 
85 {
86  for (size_t i = 0; i < FF_ARRAY_ELEMS(dec_descs); i++)
87  if (dec_descs[i]->codec_id == codec_id)
88  return dec_descs[i];
89  av_assert1(!"no codec descriptor");
90  return NULL;
91 }
92 
93 static const VkVideoProfileInfoKHR *get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
94 {
95  const VkVideoProfileListInfoKHR *profile_list;
96 
97  VkStructureType profile_struct_type =
98  codec_id == AV_CODEC_ID_H264 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR :
99  codec_id == AV_CODEC_ID_HEVC ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR :
100 #if CONFIG_VP9_VULKAN_HWACCEL
101  codec_id == AV_CODEC_ID_VP9 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR :
102 #endif
103  codec_id == AV_CODEC_ID_AV1 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR :
104  VK_STRUCTURE_TYPE_MAX_ENUM;
105  if (profile_struct_type == VK_STRUCTURE_TYPE_MAX_ENUM)
106  return NULL;
107 
108  profile_list = ff_vk_find_struct(ctx->s.hwfc->create_pnext,
109  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
110  if (!profile_list)
111  return NULL;
112 
113  for (int i = 0; i < profile_list->profileCount; i++)
114  if (ff_vk_find_struct(profile_list->pProfiles[i].pNext, profile_struct_type))
115  return &profile_list->pProfiles[i];
116 
117  return NULL;
118 }
119 
121 {
122  int err;
123  FFVulkanDecodeContext *src_ctx = src->internal->hwaccel_priv_data;
124  FFVulkanDecodeContext *dst_ctx = dst->internal->hwaccel_priv_data;
125 
126  av_refstruct_replace(&dst_ctx->shared_ctx, src_ctx->shared_ctx);
127 
128  err = av_buffer_replace(&dst_ctx->session_params, src_ctx->session_params);
129  if (err < 0)
130  return err;
131 
132  dst_ctx->dedicated_dpb = src_ctx->dedicated_dpb;
133  dst_ctx->external_fg = src_ctx->external_fg;
134 
135  return 0;
136 }
137 
138 int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
139 {
142  return 0;
143 }
144 
146 {
147  int err;
148  AVFrame *avf = av_frame_alloc();
149  if (!avf)
150  return NULL;
151 
152  err = av_hwframe_get_buffer(ctx->common.dpb_hwfc_ref, avf, 0x0);
153  if (err < 0)
154  av_frame_free(&avf);
155 
156  return avf;
157 }
158 
160 {
162  FFVulkanFunctions *vk = &ctx->s.vkfn;
163 
164  vkpic->dpb_frame = NULL;
165  for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) {
166  vkpic->view.ref[i] = VK_NULL_HANDLE;
167  vkpic->view.out[i] = VK_NULL_HANDLE;
168  vkpic->view.dst[i] = VK_NULL_HANDLE;
169  }
170 
171  vkpic->destroy_image_view = vk->DestroyImageView;
172  vkpic->wait_semaphores = vk->WaitSemaphores;
173  vkpic->invalidate_memory_ranges = vk->InvalidateMappedMemoryRanges;
174 }
175 
177  FFVulkanDecodePicture *vkpic, int is_current,
178  int alloc_dpb)
179 {
180  int err;
182 
183  vkpic->slices_size = 0;
184 
185  /* If the decoder made a blank frame to make up for a missing ref, or the
186  * frame is the current frame so it's missing one, create a re-representation */
187  if (vkpic->view.ref[0])
188  return 0;
189 
190  init_frame(dec, vkpic);
191 
192  if (ctx->common.layered_dpb && alloc_dpb) {
193  vkpic->view.ref[0] = ctx->common.layered_view;
194  vkpic->view.aspect_ref[0] = ctx->common.layered_aspect;
195  } else if (alloc_dpb) {
196  AVHWFramesContext *dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
197  AVVulkanFramesContext *dpb_hwfc = dpb_frames->hwctx;
198 
199  vkpic->dpb_frame = vk_get_dpb_pool(ctx);
200  if (!vkpic->dpb_frame)
201  return AVERROR(ENOMEM);
202 
203  err = ff_vk_create_view(&ctx->s, &ctx->common,
204  &vkpic->view.ref[0], &vkpic->view.aspect_ref[0],
205  (AVVkFrame *)vkpic->dpb_frame->data[0],
206  dpb_hwfc->format[0], !is_current);
207  if (err < 0)
208  return err;
209 
210  vkpic->view.dst[0] = vkpic->view.ref[0];
211  }
212 
213  if (!alloc_dpb || is_current) {
215  AVVulkanFramesContext *hwfc = frames->hwctx;
216 
217  err = ff_vk_create_view(&ctx->s, &ctx->common,
218  &vkpic->view.out[0], &vkpic->view.aspect[0],
219  (AVVkFrame *)pic->data[0],
220  hwfc->format[0], !is_current);
221  if (err < 0)
222  return err;
223 
224  if (!alloc_dpb) {
225  vkpic->view.ref[0] = vkpic->view.out[0];
226  vkpic->view.aspect_ref[0] = vkpic->view.aspect[0];
227  }
228  }
229 
230  return 0;
231 }
232 
234  FFVulkanDecodePicture *vkpic, int is_current,
235  enum FFVkShaderRepFormat rep_fmt, int alloc_dpb)
236 {
237  int err;
240 
241  vkpic->slices_size = 0;
242 
243  if (vkpic->view.ref[0])
244  return 0;
245 
246  init_frame(dec, vkpic);
247 
248  for (int i = 0; i < av_pix_fmt_count_planes(frames->sw_format); i++) {
249  if (alloc_dpb) {
250  vkpic->dpb_frame = vk_get_dpb_pool(ctx);
251  if (!vkpic->dpb_frame)
252  return AVERROR(ENOMEM);
253 
254  err = ff_vk_create_imageview(&ctx->s,
255  &vkpic->view.ref[i], &vkpic->view.aspect_ref[i],
256  vkpic->dpb_frame, i, rep_fmt);
257  if (err < 0)
258  return err;
259 
260  vkpic->view.dst[i] = vkpic->view.ref[i];
261  }
262 
263  if (!alloc_dpb || is_current) {
264  err = ff_vk_create_imageview(&ctx->s,
265  &vkpic->view.out[i], &vkpic->view.aspect[i],
266  pic, i, rep_fmt);
267  if (err < 0)
268  return err;
269 
270  if (!alloc_dpb) {
271  vkpic->view.ref[i] = vkpic->view.out[i];
272  vkpic->view.aspect_ref[i] = vkpic->view.aspect[i];
273  }
274  }
275  }
276 
277  return 0;
278 }
279 
281  const uint8_t *data, size_t size, int add_startcode,
282  uint32_t *nb_slices, const uint32_t **offsets)
283 {
286 
287  static const uint8_t startcode_prefix[3] = { 0x0, 0x0, 0x1 };
288  const size_t startcode_len = add_startcode ? sizeof(startcode_prefix) : 0;
289  const int nb = nb_slices ? *nb_slices : 0;
290  uint8_t *slices;
291  uint32_t *slice_off;
292  FFVkBuffer *vkbuf;
293 
294  size_t new_size = vp->slices_size + startcode_len + size +
295  ctx->caps.minBitstreamBufferSizeAlignment;
296  new_size = FFALIGN(new_size, ctx->caps.minBitstreamBufferSizeAlignment);
297 
298  if (offsets) {
299  slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
300  (nb + 1)*sizeof(slice_off));
301  if (!slice_off)
302  return AVERROR(ENOMEM);
303 
304  *offsets = dec->slice_off = slice_off;
305 
306  slice_off[nb] = vp->slices_size;
307  }
308 
309  vkbuf = vp->slices_buf ? (FFVkBuffer *)vp->slices_buf->data : NULL;
310  if (!vkbuf || vkbuf->size < new_size) {
311  int err;
312  AVBufferRef *new_ref;
313  FFVkBuffer *new_buf;
314 
315  /* No point in requesting anything smaller. */
316  size_t buf_size = FFMAX(new_size, 1024*1024);
317 
318  /* Align buffer to nearest power of two. Makes fragmentation management
319  * easier, and gives us ample headroom. */
320  buf_size = 2 << av_log2(buf_size);
321 
322  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_ref,
323  DECODER_IS_SDR(avctx->codec_id) ?
324  (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
325  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) :
326  VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR,
327  ctx->s.hwfc->create_pnext, buf_size,
328  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
329  (DECODER_IS_SDR(avctx->codec_id) ?
330  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0));
331  if (err < 0)
332  return err;
333 
334  new_buf = (FFVkBuffer *)new_ref->data;
335 
336  /* Copy data from the old buffer */
337  if (vkbuf) {
338  memcpy(new_buf->mapped_mem, vkbuf->mapped_mem, vp->slices_size);
340  }
341 
342  vp->slices_buf = new_ref;
343  vkbuf = new_buf;
344  }
345  slices = vkbuf->mapped_mem;
346 
347  /* Startcode */
348  memcpy(slices + vp->slices_size, startcode_prefix, startcode_len);
349 
350  /* Slice data */
351  memcpy(slices + vp->slices_size + startcode_len, data, size);
352 
353  if (nb_slices)
354  *nb_slices = nb + 1;
355 
356  vp->slices_size += startcode_len + size;
357 
358  return 0;
359 }
360 
362 {
365 
366  FFVulkanFunctions *vk = &ctx->s.vkfn;
367  VkVideoBeginCodingInfoKHR decode_start = {
368  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
369  .videoSession = ctx->common.session,
370  .videoSessionParameters = ctx->empty_session_params,
371  };
372  VkVideoCodingControlInfoKHR decode_ctrl = {
373  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
374  .flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
375  };
376  VkVideoEndCodingInfoKHR decode_end = {
377  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
378  };
379 
380  VkCommandBuffer cmd_buf;
381  FFVkExecContext *exec;
382 
383  /* Non-video queues do not need to be reset */
384  if (!(get_codecdesc(avctx->codec_id)->decode_op))
385  return;
386 
387  exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
388  ff_vk_exec_start(&ctx->s, exec);
389  cmd_buf = exec->buf;
390 
391  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
392  vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
393  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
394  ff_vk_exec_submit(&ctx->s, exec);
395 }
396 
398  AVFrame *pic, FFVulkanDecodePicture *vp,
399  AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
400 {
401  int err;
402  VkResult ret;
403  VkCommandBuffer cmd_buf;
404  FFVkBuffer *sd_buf;
405 
408  FFVulkanFunctions *vk = &ctx->s.vkfn;
409 
410  /* Output */
411  AVVkFrame *vkf = (AVVkFrame *)pic->buf[0]->data;
412 
413  /* Quirks */
414  const int layered_dpb = ctx->common.layered_dpb;
415 
416  VkVideoBeginCodingInfoKHR decode_start = {
417  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
418  .videoSession = ctx->common.session,
419  .videoSessionParameters = dec->session_params ?
420  *((VkVideoSessionParametersKHR *)dec->session_params->data) :
421  VK_NULL_HANDLE,
422  .referenceSlotCount = vp->decode_info.referenceSlotCount,
423  .pReferenceSlots = vp->decode_info.pReferenceSlots,
424  };
425  VkVideoEndCodingInfoKHR decode_end = {
426  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
427  };
428 
429  VkImageMemoryBarrier2 img_bar[37];
430  int nb_img_bar = 0;
431  size_t data_size = FFALIGN(vp->slices_size,
432  ctx->caps.minBitstreamBufferSizeAlignment);
433 
434  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
435 
436  /* The current decoding reference has to be bound as an inactive reference */
437  VkVideoReferenceSlotInfoKHR *cur_vk_ref;
438  cur_vk_ref = (void *)&decode_start.pReferenceSlots[decode_start.referenceSlotCount];
439  cur_vk_ref[0] = vp->ref_slot;
440  cur_vk_ref[0].slotIndex = -1;
441  decode_start.referenceSlotCount++;
442 
443  sd_buf = (FFVkBuffer *)vp->slices_buf->data;
444 
445  /* Flush if needed */
446  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
447  VkMappedMemoryRange flush_buf = {
448  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
449  .memory = sd_buf->mem,
450  .offset = 0,
451  .size = FFALIGN(vp->slices_size,
452  ctx->s.props.properties.limits.nonCoherentAtomSize),
453  };
454 
455  ret = vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &flush_buf);
456  if (ret != VK_SUCCESS) {
457  av_log(avctx, AV_LOG_ERROR, "Failed to flush memory: %s\n",
458  ff_vk_ret2str(ret));
459  return AVERROR_EXTERNAL;
460  }
461  }
462 
463  vp->decode_info.srcBuffer = sd_buf->buf;
464  vp->decode_info.srcBufferOffset = 0;
465  vp->decode_info.srcBufferRange = data_size;
466 
467  /* Start command buffer recording */
468  err = ff_vk_exec_start(&ctx->s, exec);
469  if (err < 0)
470  return err;
471  cmd_buf = exec->buf;
472 
473  /* Slices */
474  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0);
475  if (err < 0)
476  return err;
477  vp->slices_buf = NULL; /* Owned by the exec buffer from now on */
478 
479  /* Parameters */
480  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &dec->session_params, 1, 1);
481  if (err < 0)
482  return err;
483 
484  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, pic,
485  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
486  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
487  if (err < 0)
488  return err;
489 
490  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
491  pic);
492  if (err < 0)
493  return err;
494 
495  /* Output image - change layout, as it comes from a pool */
496  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
497  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
498  .pNext = NULL,
499  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
500  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
501  .srcAccessMask = VK_ACCESS_2_NONE,
502  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
503  .oldLayout = vkf->layout[0],
504  .newLayout = (layered_dpb || vp->dpb_frame) ?
505  VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
506  VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, /* Spec, 07252 utter madness */
507  .srcQueueFamilyIndex = vkf->queue_family[0],
508  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
509  .image = vkf->img[0],
510  .subresourceRange = (VkImageSubresourceRange) {
511  .aspectMask = vp->view.aspect[0],
512  .layerCount = 1,
513  .levelCount = 1,
514  },
515  };
516  ff_vk_exec_update_frame(&ctx->s, exec, pic,
517  &img_bar[nb_img_bar], &nb_img_bar);
518 
519  /* Reference for the current image, if existing and not layered */
520  if (vp->dpb_frame) {
521  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
522  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
523  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
524  if (err < 0)
525  return err;
526  }
527 
528  if (!layered_dpb) {
529  /* All references (apart from the current) for non-layered refs */
530 
531  for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
532  AVFrame *ref_frame = rpic[i];
533  FFVulkanDecodePicture *rvp = rvkp[i];
534  AVFrame *ref = rvp->dpb_frame ? rvp->dpb_frame : ref_frame;
535 
536  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref,
537  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
538  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
539  if (err < 0)
540  return err;
541 
542  if (err == 0) {
543  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec,
544  &rvp->sem, &rvp->sem_value,
545  ref);
546  if (err < 0)
547  return err;
548  }
549 
550  if (!rvp->dpb_frame) {
551  AVVkFrame *rvkf = (AVVkFrame *)ref->data[0];
552 
553  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
554  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
555  .pNext = NULL,
556  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
557  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
558  .srcAccessMask = VK_ACCESS_2_NONE,
559  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR |
560  VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
561  .oldLayout = rvkf->layout[0],
562  .newLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
563  .srcQueueFamilyIndex = rvkf->queue_family[0],
564  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
565  .image = rvkf->img[0],
566  .subresourceRange = (VkImageSubresourceRange) {
567  .aspectMask = rvp->view.aspect_ref[0],
568  .layerCount = 1,
569  .levelCount = 1,
570  },
571  };
572  ff_vk_exec_update_frame(&ctx->s, exec, ref,
573  &img_bar[nb_img_bar], &nb_img_bar);
574  }
575  }
576  } else if (vp->decode_info.referenceSlotCount ||
577  vp->view.out[0] != vp->view.ref[0]) {
578  /* Single barrier for a single layered ref */
579  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
580  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
581  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
582  if (err < 0)
583  return err;
584  }
585 
586  /* Change image layout */
587  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
588  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
589  .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
590  .pImageMemoryBarriers = img_bar,
591  .imageMemoryBarrierCount = nb_img_bar,
592  });
593 
594  /* Start, use parameters, decode and end decoding */
595  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
596  vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
597  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
598 
599  /* End recording and submit for execution */
600  return ff_vk_exec_submit(&ctx->s, exec);
601 }
602 
604 {
605  AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
606 
607  VkSemaphoreWaitInfo sem_wait = (VkSemaphoreWaitInfo) {
608  .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
609  .pSemaphores = &vp->sem,
610  .pValues = &vp->sem_value,
611  .semaphoreCount = 1,
612  };
613 
614  /* We do not have to lock the frame here because we're not interested
615  * in the actual current semaphore value, but only that it's later than
616  * the time we submitted the image for decoding. */
617  if (vp->sem)
618  vp->wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
619 
620  /* Free slices data */
622 
623  /* Destroy image view (out) */
624  for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) {
625  if (vp->view.out[i] && vp->view.out[i] != vp->view.dst[i])
626  vp->destroy_image_view(hwctx->act_dev, vp->view.out[i], hwctx->alloc);
627 
628  /* Destroy image view (ref, unlayered) */
629  if (vp->view.dst[i])
630  vp->destroy_image_view(hwctx->act_dev, vp->view.dst[i], hwctx->alloc);
631  }
632 
633  av_frame_free(&vp->dpb_frame);
634 }
635 
636 static void free_common(AVRefStructOpaque unused, void *obj)
637 {
638  FFVulkanDecodeShared *ctx = obj;
639  FFVulkanContext *s = &ctx->s;
640  FFVulkanFunctions *vk = &ctx->s.vkfn;
641 
642  /* Wait on and free execution pool */
643  ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
644 
645  /* This also frees all references from this pool */
646  av_frame_free(&ctx->common.layered_frame);
647 
648  /* Destroy parameters */
649  if (ctx->empty_session_params)
650  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
651  ctx->empty_session_params,
652  s->hwctx->alloc);
653 
654  av_buffer_pool_uninit(&ctx->buf_pool);
655 
656  ff_vk_video_common_uninit(s, &ctx->common);
657 
658  if (ctx->sd_ctx_free)
659  ctx->sd_ctx_free(ctx);
660 
661  ff_vk_uninit(s);
662 }
663 
664 static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
665 {
666  int err;
668  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
670  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
671  AVVulkanDeviceContext *hwctx = device->hwctx;
673 
674  if (dec->shared_ctx)
675  return 0;
676 
677  dec->shared_ctx = av_refstruct_alloc_ext(sizeof(*ctx), 0, NULL,
678  free_common);
679  if (!dec->shared_ctx)
680  return AVERROR(ENOMEM);
681 
682  ctx = dec->shared_ctx;
683 
684  ctx->s.extensions = ff_vk_extensions_to_mask(hwctx->enabled_dev_extensions,
686 
687  if (vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
688  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_DECODE_QUEUE)) {
689  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
690  VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
692  return AVERROR(ENOSYS);
693  }
694  }
695 
696  err = ff_vk_load_functions(device, &ctx->s.vkfn, ctx->s.extensions, 1, 1);
697  if (err < 0) {
699  return err;
700  }
701 
702  return 0;
703 }
704 
705 static VkResult vulkan_setup_profile(AVCodecContext *avctx,
707  AVVulkanDeviceContext *hwctx,
708  FFVulkanFunctions *vk,
709  const FFVulkanDecodeDescriptor *vk_desc,
710  VkVideoDecodeH264CapabilitiesKHR *h264_caps,
711  VkVideoDecodeH265CapabilitiesKHR *h265_caps,
712 #if CONFIG_VP9_VULKAN_HWACCEL
713  VkVideoDecodeVP9CapabilitiesKHR *vp9_caps,
714 #endif
715  VkVideoDecodeAV1CapabilitiesKHR *av1_caps,
716  VkVideoCapabilitiesKHR *caps,
717  VkVideoDecodeCapabilitiesKHR *dec_caps,
718  int cur_profile)
719 {
720  VkVideoDecodeUsageInfoKHR *usage = &prof->usage;
721  VkVideoProfileInfoKHR *profile = &prof->profile;
722  VkVideoProfileListInfoKHR *profile_list = &prof->profile_list;
723 
724  VkVideoDecodeH264ProfileInfoKHR *h264_profile = &prof->h264_profile;
725  VkVideoDecodeH265ProfileInfoKHR *h265_profile = &prof->h265_profile;
726 #if CONFIG_VP9_VULKAN_HWACCEL
727  VkVideoDecodeVP9ProfileInfoKHR *vp9_profile = &prof->vp9_profile;
728 #endif
729  VkVideoDecodeAV1ProfileInfoKHR *av1_profile = &prof->av1_profile;
730 
732  if (!desc)
733  return AVERROR(EINVAL);
734 
735  if (avctx->codec_id == AV_CODEC_ID_H264) {
736  dec_caps->pNext = h264_caps;
737  usage->pNext = h264_profile;
738  h264_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
739 
740  /* Vulkan transmits all the constrant_set flags, rather than wanting them
741  * merged in the profile IDC */
742  h264_profile->stdProfileIdc = cur_profile & ~(AV_PROFILE_H264_CONSTRAINED |
744 
745  h264_profile->pictureLayout = avctx->field_order == AV_FIELD_UNKNOWN ||
747  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
748  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
749  } else if (avctx->codec_id == AV_CODEC_ID_H265) {
750  dec_caps->pNext = h265_caps;
751  usage->pNext = h265_profile;
752  h265_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
753  h265_profile->stdProfileIdc = cur_profile;
754 #if CONFIG_VP9_VULKAN_HWACCEL
755  } else if (avctx->codec_id == AV_CODEC_ID_VP9) {
756  dec_caps->pNext = vp9_caps;
757  usage->pNext = vp9_profile;
758  vp9_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR;
759  vp9_profile->stdProfile = cur_profile;
760 #endif
761  } else if (avctx->codec_id == AV_CODEC_ID_AV1) {
762  dec_caps->pNext = av1_caps;
763  usage->pNext = av1_profile;
764  av1_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
765  av1_profile->stdProfile = cur_profile;
766  av1_profile->filmGrainSupport = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
767  }
768 
769  usage->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR;
770  usage->videoUsageHints = VK_VIDEO_DECODE_USAGE_DEFAULT_KHR;
771 
772  profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
773  profile->pNext = usage;
774  profile->videoCodecOperation = vk_desc->decode_op;
775  profile->chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
776  profile->lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
777  profile->chromaBitDepth = profile->lumaBitDepth;
778 
779  profile_list->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
780  profile_list->profileCount = 1;
781  profile_list->pProfiles = profile;
782 
783  /* Get the capabilities of the decoder for the given profile */
784  caps->sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
785  caps->pNext = dec_caps;
786  dec_caps->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR;
787  /* dec_caps->pNext already filled in */
788 
789  return vk->GetPhysicalDeviceVideoCapabilitiesKHR(hwctx->phys_dev, profile,
790  caps);
791 }
792 
793 static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref,
794  enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt,
796  int *dpb_dedicate)
797 {
798  VkResult ret;
799  int max_level, base_profile, cur_profile;
800  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
802  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
803  AVVulkanDeviceContext *hwctx = device->hwctx;
804  enum AVPixelFormat source_format;
805  enum AVPixelFormat best_format;
806  VkFormat best_vkfmt;
807 
810  FFVulkanFunctions *vk = &ctx->s.vkfn;
811 
812  VkVideoCapabilitiesKHR *caps = &ctx->caps;
813  VkVideoDecodeCapabilitiesKHR *dec_caps = &ctx->dec_caps;
814 
815  VkVideoDecodeH264CapabilitiesKHR h264_caps = {
816  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR,
817  };
818  VkVideoDecodeH265CapabilitiesKHR h265_caps = {
819  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR,
820  };
821 #if CONFIG_VP9_VULKAN_HWACCEL
822  VkVideoDecodeVP9CapabilitiesKHR vp9_caps = {
823  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_CAPABILITIES_KHR,
824  };
825 #endif
826  VkVideoDecodeAV1CapabilitiesKHR av1_caps = {
827  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR,
828  };
829 
830  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
831  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
832  .pNext = &prof->profile_list,
833  };
834  VkVideoFormatPropertiesKHR *ret_info;
835  uint32_t nb_out_fmts = 0;
836 
837  if (!(vk_desc->decode_extension & ctx->s.extensions)) {
838  av_log(avctx, AV_LOG_ERROR, "Device does not support decoding %s!\n",
839  avcodec_get_name(avctx->codec_id));
840  return AVERROR(ENOSYS);
841  }
842 
843  cur_profile = avctx->profile;
846 #if CONFIG_VP9_VULKAN_HWACCEL
847  avctx->codec_id == AV_CODEC_ID_VP9 ? STD_VIDEO_VP9_PROFILE_0 :
848 #endif
849  avctx->codec_id == AV_CODEC_ID_AV1 ? STD_VIDEO_AV1_PROFILE_MAIN :
850  0;
851 
852  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
853  &h264_caps,
854  &h265_caps,
855 #if CONFIG_VP9_VULKAN_HWACCEL
856  &vp9_caps,
857 #endif
858  &av1_caps,
859  caps,
860  dec_caps,
861  cur_profile);
862  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR &&
864  avctx->profile != base_profile) {
865  av_log(avctx, AV_LOG_VERBOSE, "%s profile %s not supported, attempting "
866  "again with profile %s\n",
867  avcodec_get_name(avctx->codec_id),
868  avcodec_profile_name(avctx->codec_id, cur_profile),
869  avcodec_profile_name(avctx->codec_id, base_profile));
870  cur_profile = base_profile;
871  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
872  &h264_caps,
873  &h265_caps,
874 #if CONFIG_VP9_VULKAN_HWACCEL
875  &vp9_caps,
876 #endif
877  &av1_caps,
878  caps,
879  dec_caps,
880  cur_profile);
881  }
882 
883  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
884  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
885  "%s profile \"%s\" not supported!\n",
886  avcodec_get_name(avctx->codec_id),
887  avcodec_profile_name(avctx->codec_id, cur_profile));
888  return AVERROR(EINVAL);
889  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
890  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
891  "format (%s) not supported!\n",
893  return AVERROR(EINVAL);
894  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
895  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
896  return AVERROR(EINVAL);
897  } else if (ret != VK_SUCCESS) {
898  return AVERROR_EXTERNAL;
899  }
900 
901  max_level = avctx->codec_id == AV_CODEC_ID_H264 ? ff_vk_h264_level_to_av(h264_caps.maxLevelIdc) :
902  avctx->codec_id == AV_CODEC_ID_H265 ? ff_vk_h265_level_to_av(h265_caps.maxLevelIdc) :
903 #if CONFIG_VP9_VULKAN_HWACCEL
904  avctx->codec_id == AV_CODEC_ID_VP9 ? vp9_caps.maxLevel :
905 #endif
906  avctx->codec_id == AV_CODEC_ID_AV1 ? av1_caps.maxLevel :
907  0;
908 
909  av_log(avctx, AV_LOG_VERBOSE, "Decoder capabilities for %s profile \"%s\":\n",
910  avcodec_get_name(avctx->codec_id),
911  avcodec_profile_name(avctx->codec_id, cur_profile));
912  av_log(avctx, AV_LOG_VERBOSE, " Maximum level: %i (stream %i)\n",
913  max_level, avctx->level);
914  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
915  caps->minCodedExtent.width, caps->maxCodedExtent.width);
916  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
917  caps->minCodedExtent.height, caps->maxCodedExtent.height);
918  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
919  caps->pictureAccessGranularity.width);
920  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
921  caps->pictureAccessGranularity.height);
922  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
923  caps->minBitstreamBufferOffsetAlignment);
924  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
925  caps->minBitstreamBufferSizeAlignment);
926  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
927  caps->maxDpbSlots);
928  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
929  caps->maxActiveReferencePictures);
930  av_log(avctx, AV_LOG_VERBOSE, " Codec header name: '%s' (driver), '%s' (compiled)\n",
931  caps->stdHeaderVersion.extensionName,
932  vk_desc->ext_props.extensionName);
933  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
934  CODEC_VER(caps->stdHeaderVersion.specVersion),
935  CODEC_VER(vk_desc->ext_props.specVersion));
936  av_log(avctx, AV_LOG_VERBOSE, " Decode modes:%s%s%s\n",
937  dec_caps->flags ? "" :
938  " invalid",
939  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR ?
940  " reuse_dst_dpb" : "",
941  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR ?
942  " dedicated_dpb" : "");
943  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
944  caps->flags ? "" :
945  " none",
946  caps->flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
947  " protected" : "",
948  caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
949  " separate_references" : "");
950 
951  /* Check if decoding is possible with the given parameters */
952  if (avctx->coded_width < caps->minCodedExtent.width ||
953  avctx->coded_height < caps->minCodedExtent.height ||
954  avctx->coded_width > caps->maxCodedExtent.width ||
955  avctx->coded_height > caps->maxCodedExtent.height)
956  return AVERROR(EINVAL);
957 
959  avctx->level > max_level)
960  return AVERROR(EINVAL);
961 
962  /* Some basic sanity checking */
963  if (!(dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
964  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR))) {
965  av_log(avctx, AV_LOG_ERROR, "Buggy driver signals invalid decoding mode: neither "
966  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR nor "
967  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR are set!\n");
968  return AVERROR_EXTERNAL;
969  } else if ((dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
970  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ==
971  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) &&
972  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR)) {
973  av_log(avctx, AV_LOG_ERROR, "Cannot initialize Vulkan decoding session, buggy driver: "
974  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set "
975  "but VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!\n");
976  return AVERROR_EXTERNAL;
977  }
978 
979  dec->dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
980  ctx->common.layered_dpb = !dec->dedicated_dpb ? 0 :
981  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
982 
983  if (dec->dedicated_dpb) {
984  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
985  } else {
986  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
987  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
988  VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
989  VK_IMAGE_USAGE_SAMPLED_BIT;
990 
991  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
993  fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
994  }
995 
996  /* Get the format of the images necessary */
997  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
998  &fmt_info,
999  &nb_out_fmts, NULL);
1000  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1001  (!nb_out_fmts && ret == VK_SUCCESS)) {
1002  return AVERROR(EINVAL);
1003  } else if (ret != VK_SUCCESS) {
1004  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1005  ff_vk_ret2str(ret));
1006  return AVERROR_EXTERNAL;
1007  }
1008 
1009  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
1010  if (!ret_info)
1011  return AVERROR(ENOMEM);
1012 
1013  for (int i = 0; i < nb_out_fmts; i++)
1014  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1015 
1016  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1017  &fmt_info,
1018  &nb_out_fmts, ret_info);
1019  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1020  (!nb_out_fmts && ret == VK_SUCCESS)) {
1021  av_free(ret_info);
1022  return AVERROR(EINVAL);
1023  } else if (ret != VK_SUCCESS) {
1024  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1025  ff_vk_ret2str(ret));
1026  av_free(ret_info);
1027  return AVERROR_EXTERNAL;
1028  }
1029 
1030  /* Find a format to use */
1031  *pix_fmt = best_format = AV_PIX_FMT_NONE;
1032  *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
1033  source_format = avctx->sw_pix_fmt;
1034 
1035  av_log(avctx, AV_LOG_DEBUG, "Choosing best pixel format for decoding from %i:\n", nb_out_fmts);
1036  for (int i = 0; i < nb_out_fmts; i++) {
1038  if (tmp == AV_PIX_FMT_NONE) {
1039  av_log(avctx, AV_LOG_WARNING, "Invalid/unknown Vulkan format %i!\n", ret_info[i].format);
1040  continue;
1041  }
1042 
1043  best_format = av_find_best_pix_fmt_of_2(tmp, best_format, source_format, 0, NULL);
1044  if (tmp == best_format)
1045  best_vkfmt = ret_info[i].format;
1046 
1047  av_log(avctx, AV_LOG_DEBUG, " %s%s (Vulkan ID: %i)\n",
1048  av_get_pix_fmt_name(tmp), tmp == best_format ? "*" : "",
1049  ret_info[i].format);
1050  }
1051 
1052  av_free(ret_info);
1053 
1054  if (best_format == AV_PIX_FMT_NONE) {
1055  av_log(avctx, AV_LOG_ERROR, "No valid/compatible pixel format found for decoding!\n");
1056  return AVERROR(EINVAL);
1057  } else {
1058  av_log(avctx, AV_LOG_VERBOSE, "Chosen frame pixfmt: %s (Vulkan ID: %i)\n",
1059  av_get_pix_fmt_name(best_format), best_vkfmt);
1060  }
1061 
1062  *pix_fmt = best_format;
1063  *vk_fmt = best_vkfmt;
1064 
1065  *dpb_dedicate = dec->dedicated_dpb;
1066 
1067  return 0;
1068 }
1069 
1071 {
1072  av_free(hwfc->user_opaque);
1073 }
1074 
1075 int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
1076 {
1077  VkFormat vkfmt = VK_FORMAT_UNDEFINED;
1078  int err, dedicated_dpb;
1079  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
1080  AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
1083 
1084  err = vulkan_decode_bootstrap(avctx, hw_frames_ctx);
1085  if (err < 0)
1086  return err;
1087 
1088  frames_ctx->sw_format = avctx->sw_pix_fmt;
1089 
1090  if (!DECODER_IS_SDR(avctx->codec_id)) {
1091  prof = av_mallocz(sizeof(FFVulkanDecodeProfileData));
1092  if (!prof)
1093  return AVERROR(ENOMEM);
1094 
1095  err = vulkan_decode_get_profile(avctx, hw_frames_ctx,
1096  &frames_ctx->sw_format, &vkfmt,
1097  prof, &dedicated_dpb);
1098  if (err < 0) {
1099  av_free(prof);
1100  return err;
1101  }
1102 
1103  frames_ctx->user_opaque = prof;
1104  frames_ctx->free = free_profile_data;
1105 
1106  hwfc->create_pnext = &prof->profile_list;
1107  } else {
1108  switch (frames_ctx->sw_format) {
1109  case AV_PIX_FMT_GBRAP16:
1110  /* This should be more efficient for downloading and using */
1111  frames_ctx->sw_format = AV_PIX_FMT_RGBA64;
1112  break;
1113  case AV_PIX_FMT_GBRP10:
1114  /* This saves memory bandwidth when downloading */
1115  frames_ctx->sw_format = AV_PIX_FMT_X2BGR10;
1116  break;
1117  case AV_PIX_FMT_BGR0:
1118  /* mpv has issues with bgr0 mapping, so just remap it */
1119  frames_ctx->sw_format = AV_PIX_FMT_RGB0;
1120  break;
1121  default:
1122  break;
1123  }
1124  }
1125 
1126  frames_ctx->width = avctx->coded_width;
1127  frames_ctx->height = avctx->coded_height;
1128  frames_ctx->format = AV_PIX_FMT_VULKAN;
1129 
1130  hwfc->format[0] = vkfmt;
1131  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1132  hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1133  VK_IMAGE_USAGE_STORAGE_BIT |
1134  VK_IMAGE_USAGE_SAMPLED_BIT;
1135 
1136  if (prof) {
1138 
1139  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1140  if (!dec->dedicated_dpb)
1141  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1142 
1143  ctx = dec->shared_ctx;
1144  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
1146  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1147  }
1148 
1149  return err;
1150 }
1151 
1152 static void vk_decode_free_params(void *opaque, uint8_t *data)
1153 {
1154  FFVulkanDecodeShared *ctx = opaque;
1155  FFVulkanFunctions *vk = &ctx->s.vkfn;
1156  VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)data;
1157  vk->DestroyVideoSessionParametersKHR(ctx->s.hwctx->act_dev, *par,
1158  ctx->s.hwctx->alloc);
1159  av_free(par);
1160 }
1161 
1163  const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1164 {
1165  VkVideoSessionParametersKHR *par = av_malloc(sizeof(*par));
1166  const FFVulkanFunctions *vk = &ctx->s.vkfn;
1167  VkResult ret;
1168 
1169  if (!par)
1170  return AVERROR(ENOMEM);
1171 
1172  /* Create session parameters */
1173  ret = vk->CreateVideoSessionParametersKHR(ctx->s.hwctx->act_dev, session_params_create,
1174  ctx->s.hwctx->alloc, par);
1175  if (ret != VK_SUCCESS) {
1176  av_log(logctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1177  ff_vk_ret2str(ret));
1178  av_free(par);
1179  return AVERROR_EXTERNAL;
1180  }
1181  *par_ref = av_buffer_create((uint8_t *)par, sizeof(*par),
1183  if (!*par_ref) {
1184  vk_decode_free_params(ctx, (uint8_t *)par);
1185  return AVERROR(ENOMEM);
1186  }
1187 
1188  return 0;
1189 }
1190 
1192 {
1194 
1195  av_freep(&dec->hevc_headers);
1198  av_freep(&dec->slice_off);
1199  return 0;
1200 }
1201 
1204 {
1205  VkResult ret;
1206  FFVulkanContext *s = &ctx->s;
1207  FFVulkanFunctions *vk = &s->vkfn;
1208 
1209  VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
1210  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
1211  };
1212  VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
1213  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1214  };
1215  StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
1216  VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
1217  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
1218  .pStdSequenceHeader = &av1_empty_seq,
1219  };
1220  VkVideoSessionParametersCreateInfoKHR session_params_create = {
1221  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1222  .pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
1223  avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
1224  avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
1225  NULL,
1226  .videoSession = ctx->common.session,
1227  };
1228 
1229  if (avctx->codec_id == AV_CODEC_ID_VP9)
1230  return 0;
1231 
1232  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1233  s->hwctx->alloc, &ctx->empty_session_params);
1234  if (ret != VK_SUCCESS) {
1235  av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
1236  ff_vk_ret2str(ret));
1237  return AVERROR_EXTERNAL;
1238  }
1239 
1240  return 0;
1241 }
1242 
1244 {
1245  int err;
1248  FFVulkanContext *s;
1249  int async_depth;
1250  const VkVideoProfileInfoKHR *profile;
1251  const FFVulkanDecodeDescriptor *vk_desc;
1252  const VkPhysicalDeviceDriverProperties *driver_props;
1253 
1254  VkVideoSessionCreateInfoKHR session_create = {
1255  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1256  };
1257 
1259  if (err < 0)
1260  return err;
1261 
1262  /* Initialize contexts */
1263  ctx = dec->shared_ctx;
1264  s = &ctx->s;
1265 
1266  err = ff_vk_init(s, avctx, NULL, avctx->hw_frames_ctx);
1267  if (err < 0)
1268  return err;
1269 
1270  vk_desc = get_codecdesc(avctx->codec_id);
1271 
1273  if ((vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) && !profile) {
1274  av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
1275  return AVERROR(EINVAL);
1276  }
1277 
1278  /* Create queue context */
1279  vk_desc = get_codecdesc(avctx->codec_id);
1280  ctx->qf = ff_vk_qf_find(s, vk_desc->queue_flags, vk_desc->decode_op);
1281  if (!ctx->qf) {
1282  av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
1283  avcodec_get_name(avctx->codec_id));
1284  return err;
1285  }
1286 
1287  session_create.queueFamilyIndex = ctx->qf->idx;
1288  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1289  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1290  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1291  session_create.pictureFormat = s->hwfc->format[0];
1292  session_create.referencePictureFormat = session_create.pictureFormat;
1293  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1294  session_create.pVideoProfile = profile;
1295 #ifdef VK_KHR_video_maintenance2
1296  if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)
1297  session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1298 #endif
1299 
1300  /* Create decode exec context for this specific main thread.
1301  * 2 async contexts per thread was experimentally determined to be optimal
1302  * for a majority of streams. */
1303  async_depth = 2*ctx->qf->num;
1304  /* We don't need more than 2 per thread context */
1305  async_depth = FFMIN(async_depth, 2*avctx->thread_count);
1306  /* Make sure there are enough async contexts for each thread */
1307  async_depth = FFMAX(async_depth, avctx->thread_count);
1308 
1309  err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
1310  async_depth, 0, 0, 0, profile);
1311  if (err < 0)
1312  goto fail;
1313 
1314  if (!DECODER_IS_SDR(avctx->codec_id)) {
1315  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1316  if (err < 0)
1317  goto fail;
1318  }
1319 
1320  /* If doing an out-of-place decoding, create a DPB pool */
1321  if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) {
1323  AVVulkanFramesContext *dpb_hwfc;
1324 
1325  ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref);
1326  if (!ctx->common.dpb_hwfc_ref) {
1327  err = AVERROR(ENOMEM);
1328  goto fail;
1329  }
1330 
1331  dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
1332  dpb_frames->format = s->frames->format;
1333  dpb_frames->sw_format = s->frames->sw_format;
1334  dpb_frames->width = avctx->coded_width;
1335  dpb_frames->height = avctx->coded_height;
1336 
1337  dpb_hwfc = dpb_frames->hwctx;
1338  dpb_hwfc->create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1339  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1340  dpb_hwfc->format[0] = s->hwfc->format[0];
1341  dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1342  dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1343  VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */
1344 
1345  if (ctx->common.layered_dpb)
1346  dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
1347 
1348  err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref);
1349  if (err < 0)
1350  goto fail;
1351 
1352  if (ctx->common.layered_dpb) {
1353  ctx->common.layered_frame = vk_get_dpb_pool(ctx);
1354  if (!ctx->common.layered_frame) {
1355  err = AVERROR(ENOMEM);
1356  goto fail;
1357  }
1358 
1359  err = ff_vk_create_view(&ctx->s, &ctx->common,
1360  &ctx->common.layered_view,
1361  &ctx->common.layered_aspect,
1362  (AVVkFrame *)ctx->common.layered_frame->data[0],
1363  s->hwfc->format[0], 1);
1364  if (err < 0)
1365  goto fail;
1366  }
1367  }
1368 
1369  if (!DECODER_IS_SDR(avctx->codec_id)) {
1370  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
1371  err = create_empty_session_parameters(avctx, ctx);
1372  if (err < 0)
1373  return err;
1374  }
1375  } else {
1376  /* For SDR decoders, this alignment value will be 0. Since this will make
1377  * add_slice() malfunction, set it to a sane default value. */
1378  ctx->caps.minBitstreamBufferSizeAlignment = AV_INPUT_BUFFER_PADDING_SIZE;
1379  }
1380 
1381  driver_props = &dec->shared_ctx->s.driver_props;
1382  if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1383  driver_props->conformanceVersion.major == 1 &&
1384  driver_props->conformanceVersion.minor == 3 &&
1385  driver_props->conformanceVersion.subminor == 8 &&
1386  driver_props->conformanceVersion.patch < 3)
1387  dec->quirk_av1_offset = 1;
1388 
1389  ff_vk_decode_flush(avctx);
1390 
1391  av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization successful\n");
1392 
1393  return 0;
1394 
1395 fail:
1396  ff_vk_decode_uninit(avctx);
1397 
1398  return err;
1399 }
vulkan_loader.h
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
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
AVVulkanDeviceContext::phys_dev
VkPhysicalDevice phys_dev
Physical device.
Definition: hwcontext_vulkan.h:79
FFVulkanDecodePicture::slices_size
size_t slices_size
Definition: vulkan_decode.h:102
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
FFVulkanDecodeShared::s
FFVulkanContext s
Definition: vulkan_decode.h:39
FFVulkanDecodeProfileData::profile
VkVideoProfileInfoKHR profile
Definition: vulkan_decode.c:80
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_PROFILE_H264_INTRA
#define AV_PROFILE_H264_INTRA
Definition: defs.h:108
FFVulkanDecodeProfileData::h265_profile
VkVideoDecodeH265ProfileInfoKHR h265_profile
Definition: vulkan_decode.c:73
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:233
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3441
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FFVulkanDecodeContext::shared_ctx
FFVulkanDecodeShared * shared_ctx
Definition: vulkan_decode.h:57
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
ff_vk_exec_pool_init
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
Definition: vulkan.c:356
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
dpb_frames
int dpb_frames
Definition: h264_levels.c:163
FF_VK_EXT_VIDEO_MAINTENANCE_2
#define FF_VK_EXT_VIDEO_MAINTENANCE_2
Definition: vulkan_functions.h:57
AV_PROFILE_HEVC_MAIN
#define AV_PROFILE_HEVC_MAIN
Definition: defs.h:159
FFVulkanDecodePicture::invalidate_memory_ranges
PFN_vkInvalidateMappedMemoryRanges invalidate_memory_ranges
Definition: vulkan_decode.h:107
ff_vk_exec_update_frame
void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar)
Definition: vulkan.c:859
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
ff_vk_depth_from_av_depth
VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth)
Get Vulkan's bit depth from an [8:12] integer.
Definition: vulkan_video.c:128
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
ff_vk_dec_av1_desc
const FFVulkanDecodeDescriptor ff_vk_dec_av1_desc
Definition: vulkan_av1.c:26
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
AVHWFramesContext::free
void(* free)(struct AVHWFramesContext *ctx)
This field may be set by the caller before calling av_hwframe_ctx_init().
Definition: hwcontext.h:161
AVCodecContext::field_order
enum AVFieldOrder field_order
Field order.
Definition: avcodec.h:682
AVVulkanFramesContext::create_pnext
void * create_pnext
Extension data for image creation.
Definition: hwcontext_vulkan.h:238
ff_vk_find_struct
static const void * ff_vk_find_struct(const void *chain, VkStructureType stype)
Definition: vulkan.h:332
b
#define b
Definition: input.c:42
create_empty_session_parameters
static int create_empty_session_parameters(AVCodecContext *avctx, FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:1202
data
const char data[16]
Definition: mxf.c:149
ff_vk_create_view
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common, VkImageView *view, VkImageAspectFlags *aspect, AVVkFrame *src, VkFormat vkf, int is_dpb)
Creates image views for video frames.
Definition: vulkan_video.c:291
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_vk_init
int ff_vk_init(FFVulkanContext *s, void *log_parent, AVBufferRef *device_ref, AVBufferRef *frames_ref)
Initializes the AVClass, in case this context is not used as the main user's context.
Definition: vulkan.c:2976
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:547
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2964
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
avcodec_profile_name
const char * avcodec_profile_name(enum AVCodecID codec_id, int profile)
Return a name for the specified profile, if available.
Definition: utils.c:439
FFVulkanDecodePicture::dst
VkImageView dst[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:81
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
FFVulkanDecodeProfileData::av1_profile
VkVideoDecodeAV1ProfileInfoKHR av1_profile
Definition: vulkan_decode.c:77
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:604
FFVulkanDecodeContext
Definition: vulkan_decode.h:56
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:779
ff_vk_decode_prepare_frame
int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, AVFrame *pic, FFVulkanDecodePicture *vkpic, int is_current, int alloc_dpb)
Prepare a frame, creates the image view, and sets up the dpb fields.
Definition: vulkan_decode.c:176
AV_HWACCEL_FLAG_IGNORE_LEVEL
#define AV_HWACCEL_FLAG_IGNORE_LEVEL
Hardware acceleration should be used for decoding even if the codec level used is unknown or higher t...
Definition: avcodec.h:1986
FFVkShaderRepFormat
FFVkShaderRepFormat
Returns the format to use for images in shaders.
Definition: vulkan.h:404
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AV_HWDEVICE_TYPE_VULKAN
@ AV_HWDEVICE_TYPE_VULKAN
Definition: hwcontext.h:39
FFVulkanDecodeContext::session_params
AVBufferRef * session_params
Definition: vulkan_decode.h:58
ff_vk_subsampling_from_av_desc
VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFmtDescriptor *desc)
Get Vulkan's chroma subsampling from a pixfmt descriptor.
Definition: vulkan_video.c:115
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3481
AVVulkanDeviceContext::alloc
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
Definition: hwcontext_vulkan.h:63
AVVkFrame::img
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Definition: hwcontext_vulkan.h:302
FFVulkanDecodeDescriptor::decode_op
VkVideoCodecOperationFlagBitsKHR decode_op
Definition: vulkan_decode.h:33
fail
#define fail()
Definition: checkasm.h:199
FFVulkanDecodePicture::sem_value
uint64_t sem_value
Definition: vulkan_decode.h:87
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1561
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:558
frames
if it could not because there are no more frames
Definition: filter_design.txt:267
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:208
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:488
ff_vk_ret2str
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
Definition: vulkan.c:35
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:607
ff_vk_decode_frame
int ff_vk_decode_frame(AVCodecContext *avctx, AVFrame *pic, FFVulkanDecodePicture *vp, AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
Decode a frame.
Definition: vulkan_decode.c:397
FFVulkanDecodeShared
Definition: vulkan_decode.h:38
vulkan_decode_get_profile
static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref, enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt, FFVulkanDecodeProfileData *prof, int *dpb_dedicate)
Definition: vulkan_decode.c:793
init_frame
static void init_frame(FFVulkanDecodeContext *dec, FFVulkanDecodePicture *vkpic)
Definition: vulkan_decode.c:159
refstruct.h
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:51
FFVulkanDecodeContext::slice_off
uint32_t * slice_off
Definition: vulkan_decode.h:71
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FFVulkanDecodeProfileData::h264_profile
VkVideoDecodeH264ProfileInfoKHR h264_profile
Definition: vulkan_decode.c:72
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
FFVulkanDecodeProfileData::profile_list
VkVideoProfileListInfoKHR profile_list
Definition: vulkan_decode.c:81
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
FFVulkanDecodePicture::wait_semaphores
PFN_vkWaitSemaphores wait_semaphores
Definition: vulkan_decode.h:105
s
#define s(width, name)
Definition: cbs_vp9.c:198
FFVulkanDecodePicture
Definition: vulkan_decode.h:75
ff_vk_video_common_init
av_cold int ff_vk_video_common_init(AVCodecContext *avctx, FFVulkanContext *s, FFVkVideoCommon *common, VkVideoSessionCreateInfoKHR *session_create)
Initialize video session, allocating and binding necessary memory.
Definition: vulkan_video.c:365
ff_vk_decode_create_params
int ff_vk_decode_create_params(AVBufferRef **par_ref, void *logctx, FFVulkanDecodeShared *ctx, const VkVideoSessionParametersCreateInfoKHR *session_params_create)
Create VkVideoSessionParametersKHR wrapped in an AVBufferRef.
Definition: vulkan_decode.c:1162
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:878
offsets
static const int offsets[]
Definition: hevc_pel.c:34
FFVulkanContext::driver_props
VkPhysicalDeviceDriverProperties driver_props
Definition: vulkan.h:282
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1415
ff_vk_load_functions
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
Definition: vulkan_loader.h:119
ff_vk_dec_vp9_desc
const FFVulkanDecodeDescriptor ff_vk_dec_vp9_desc
Definition: vulkan_vp9.c:23
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
av_refstruct_alloc_ext
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
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:619
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:287
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
ff_decode_get_hw_frames_ctx
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition: decode.c:1041
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:441
if
if(ret)
Definition: filter_design.txt:179
get_video_profile
static const VkVideoProfileInfoKHR * get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
Definition: vulkan_decode.c:93
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:59
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:529
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
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
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
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
AVVulkanDeviceContext::nb_enabled_dev_extensions
int nb_enabled_dev_extensions
Definition: hwcontext_vulkan.h:113
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:603
tmp
static uint8_t tmp[20]
Definition: aes_ctr.c:47
ff_vk_video_common_uninit
av_cold void ff_vk_video_common_uninit(FFVulkanContext *s, FFVkVideoCommon *common)
Free video session and required resources.
Definition: vulkan_video.c:335
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:65
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:466
FFVulkanDecodeProfileData::usage
VkVideoDecodeUsageInfoKHR usage
Definition: vulkan_decode.c:79
FFVulkanDecodeDescriptor::decode_extension
FFVulkanExtensions decode_extension
Definition: vulkan_decode.h:31
AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
Hardware acceleration should still be attempted for decoding when the codec profile does not match th...
Definition: avcodec.h:2006
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:1191
AVVulkanFramesContext::format
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
Definition: hwcontext_vulkan.h:268
FFVkBuffer::size
size_t size
Definition: vulkan.h:91
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:227
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
FFVulkanDecodePicture::aspect
VkImageAspectFlags aspect[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:82
FFVulkanDecodePicture::aspect_ref
VkImageAspectFlags aspect_ref[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:83
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:100
FFVulkanContext
Definition: vulkan.h:274
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:1075
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1628
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
usage
const char * usage
Definition: floatimg_cmp.c:62
ff_vk_create_imageview
int ff_vk_create_imageview(FFVulkanContext *s, VkImageView *img_view, VkImageAspectFlags *aspect, AVFrame *f, int plane, enum FFVkShaderRepFormat rep_fmt)
Create a single imageview for a given plane.
Definition: vulkan.c:1879
AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_X2BGR10
Definition: pixfmt.h:614
free_common
static void free_common(AVRefStructOpaque unused, void *obj)
Definition: vulkan_decode.c:636
FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
Definition: vulkan_functions.h:56
ff_vk_h265_level_to_av
int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
Definition: vulkan_video.c:191
sem_wait
#define sem_wait(psem)
Definition: semaphore.h:27
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:297
FFVulkanDecodePicture::ref
VkImageView ref[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:79
size
int size
Definition: twinvq_data.h:10344
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:428
ref_frame
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
Definition: dec.c:616
ff_vk_dec_h264_desc
const FFVulkanDecodeDescriptor ff_vk_dec_h264_desc
Definition: vulkan_h264.c:24
FFVulkanDecodeContext::slice_off_max
unsigned int slice_off_max
Definition: vulkan_decode.h:72
AVVkFrame::queue_family
uint32_t queue_family[AV_NUM_DATA_POINTERS]
Queue family of the images.
Definition: hwcontext_vulkan.h:361
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
FFVkExecContext
Definition: vulkan.h:111
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
vk_decode_free_params
static void vk_decode_free_params(void *opaque, uint8_t *data)
Definition: vulkan_decode.c:1152
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@320 view
FFVulkanDecodeProfileData
Definition: vulkan_decode.c:71
FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
Definition: vulkan_functions.h:59
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
FFVulkanDecodePicture::out
VkImageView out[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:80
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:559
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFVulkanDecodeDescriptor::ext_props
VkExtensionProperties ext_props
Definition: vulkan_decode.h:35
VkFormat
enum VkFormat VkFormat
Definition: hwcontext_stub.c:25
ff_vk_h264_level_to_av
int ff_vk_h264_level_to_av(StdVideoH264LevelIdc level)
Convert level from Vulkan to AV.
Definition: vulkan_video.c:139
AVCodecContext::hwaccel_flags
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition: avcodec.h:1484
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
DECODER_IS_SDR
#define DECODER_IS_SDR(codec_id)
Definition: vulkan_decode.c:27
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FFVulkanDecodePicture::sem
VkSemaphore sem
Definition: vulkan_decode.h:86
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
FFVulkanDecodeContext::external_fg
int external_fg
Definition: vulkan_decode.h:61
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:233
profile
int profile
Definition: mxfenc.c:2278
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1453
CODEC_VER
#define CODEC_VER(ver)
Definition: vulkan_video.h:30
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
ff_vk_decode_flush
void ff_vk_decode_flush(AVCodecContext *avctx)
Flush decoder.
Definition: vulkan_decode.c:361
ret
ret
Definition: filter_design.txt:187
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
AVHWFramesContext::user_opaque
void * user_opaque
Arbitrary user data, to be used e.g.
Definition: hwcontext.h:166
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:280
AV_PROFILE_H264_CONSTRAINED
#define AV_PROFILE_H264_CONSTRAINED
Definition: defs.h:107
dec_descs
static const FFVulkanDecodeDescriptor * dec_descs[]
Definition: vulkan_decode.c:50
FFVulkanDecodeContext::hevc_headers
struct HEVCHeaderSet * hevc_headers
Definition: vulkan_decode.h:68
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:274
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:724
ff_vk_dec_hevc_desc
const FFVulkanDecodeDescriptor ff_vk_dec_hevc_desc
Definition: vulkan_hevc.c:26
ff_vk_dec_prores_raw_desc
const FFVulkanDecodeDescriptor ff_vk_dec_prores_raw_desc
Definition: vulkan_prores_raw.c:31
get_codecdesc
static const FFVulkanDecodeDescriptor * get_codecdesc(enum AVCodecID codec_id)
Definition: vulkan_decode.c:84
AVCodecContext
main external API structure.
Definition: avcodec.h:431
FFVulkanDecodeContext::dedicated_dpb
int dedicated_dpb
Definition: vulkan_decode.h:60
av_find_best_pix_fmt_of_2
enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
Compute what kind of losses will occur when converting from one specific pixel format to another.
Definition: pixdesc.c:3720
ff_vk_dec_ffv1_desc
const FFVulkanDecodeDescriptor ff_vk_dec_ffv1_desc
Definition: vulkan_ffv1.c:39
av_refstruct_replace
void av_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:160
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1618
FFVulkanDecodeDescriptor
Definition: vulkan_decode.h:29
AV_CODEC_ID_H265
#define AV_CODEC_ID_H265
Definition: codec_id.h:229
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVCodecContext::export_side_data
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition: avcodec.h:1774
ff_vk_params_invalidate
int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
Removes current session parameters to recreate them.
Definition: vulkan_decode.c:138
FFVulkanDecodePicture::dpb_frame
AVFrame * dpb_frame
Definition: vulkan_decode.h:76
AV_PROFILE_H264_CONSTRAINED_BASELINE
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition: defs.h:111
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:120
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:217
vulkan_video.h
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:607
desc
const char * desc
Definition: libsvtav1.c:79
AVVulkanDeviceContext::enabled_dev_extensions
const char *const * enabled_dev_extensions
Enabled device extensions.
Definition: hwcontext_vulkan.h:112
AVVulkanFramesContext::nb_layers
int nb_layers
Number of layers each image will have.
Definition: hwcontext_vulkan.h:273
FFVulkanDecodePicture::slices_buf
AVBufferRef * slices_buf
Definition: vulkan_decode.h:101
mem.h
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:327
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FFVulkanDecodeDescriptor::queue_flags
VkQueueFlagBits queue_flags
Definition: vulkan_decode.h:32
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:84
vulkan_decode.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
decode_end
static av_cold int decode_end(AVCodecContext *avctx)
Definition: 4xm.c:980
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
vulkan_setup_profile
static VkResult vulkan_setup_profile(AVCodecContext *avctx, FFVulkanDecodeProfileData *prof, AVVulkanDeviceContext *hwctx, FFVulkanFunctions *vk, const FFVulkanDecodeDescriptor *vk_desc, VkVideoDecodeH264CapabilitiesKHR *h264_caps, VkVideoDecodeH265CapabilitiesKHR *h265_caps, VkVideoDecodeAV1CapabilitiesKHR *av1_caps, VkVideoCapabilitiesKHR *caps, VkVideoDecodeCapabilitiesKHR *dec_caps, int cur_profile)
Definition: vulkan_decode.c:705
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFVkBuffer
Definition: vulkan.h:87
vk_get_dpb_pool
static AVFrame * vk_get_dpb_pool(FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:145
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:904
FFVulkanDecodePicture::destroy_image_view
PFN_vkDestroyImageView destroy_image_view
Definition: vulkan_decode.h:106
ff_vk_extensions_to_mask
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
Definition: vulkan_loader.h:36
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
vulkan_decode_bootstrap
static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
Definition: vulkan_decode.c:664
ff_vk_pix_fmt_from_vkfmt
enum AVPixelFormat ff_vk_pix_fmt_from_vkfmt(VkFormat vkf)
Get pixfmt from a Vulkan format.
Definition: vulkan_video.c:99
ff_vk_decode_init
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
Definition: vulkan_decode.c:1243
FFVulkanDecodePicture::decode_info
VkVideoDecodeInfoKHR decode_info
Definition: vulkan_decode.h:98
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:638
av_hwframe_get_buffer
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:506
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
FFVulkanFunctions
Definition: vulkan_functions.h:276
FFVulkanDecodeContext::quirk_av1_offset
int quirk_av1_offset
Definition: vulkan_decode.h:65
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:1254
src
#define src
Definition: vp8dsp.c:248
free_profile_data
static void free_profile_data(AVHWFramesContext *hwfc)
Definition: vulkan_decode.c:1070
AV_CODEC_EXPORT_DATA_FILM_GRAIN
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition: avcodec.h:400
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:3361