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 #if CONFIG_H264_VULKAN_HWACCEL
29 #endif
30 #if CONFIG_HEVC_VULKAN_HWACCEL
32 #endif
33 #if CONFIG_AV1_VULKAN_HWACCEL
35 #endif
36 
38 #if CONFIG_H264_VULKAN_HWACCEL
40 #endif
41 #if CONFIG_HEVC_VULKAN_HWACCEL
43 #endif
44 #if CONFIG_AV1_VULKAN_HWACCEL
46 #endif
47 };
48 
50 {
51  for (size_t i = 0; i < FF_ARRAY_ELEMS(dec_descs); i++)
52  if (dec_descs[i]->codec_id == codec_id)
53  return dec_descs[i];
54  av_assert1(!"no codec descriptor");
55  return NULL;
56 }
57 
58 static const VkVideoProfileInfoKHR *get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
59 {
60  const VkVideoProfileListInfoKHR *profile_list;
61 
62  VkStructureType profile_struct_type =
63  codec_id == AV_CODEC_ID_H264 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR :
64  codec_id == AV_CODEC_ID_HEVC ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR :
65  codec_id == AV_CODEC_ID_AV1 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR :
66  0;
67 
68  profile_list = ff_vk_find_struct(ctx->s.hwfc->create_pnext,
69  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
70  if (!profile_list)
71  return NULL;
72 
73  for (int i = 0; i < profile_list->profileCount; i++)
74  if (ff_vk_find_struct(profile_list->pProfiles[i].pNext, profile_struct_type))
75  return &profile_list->pProfiles[i];
76 
77  return NULL;
78 }
79 
81 {
82  int err;
83  FFVulkanDecodeContext *src_ctx = src->internal->hwaccel_priv_data;
84  FFVulkanDecodeContext *dst_ctx = dst->internal->hwaccel_priv_data;
85 
86  av_refstruct_replace(&dst_ctx->shared_ctx, src_ctx->shared_ctx);
87 
88  if (src_ctx->session_params) {
89  err = av_buffer_replace(&dst_ctx->session_params, src_ctx->session_params);
90  if (err < 0)
91  return err;
92  }
93 
94  dst_ctx->dedicated_dpb = src_ctx->dedicated_dpb;
95  dst_ctx->external_fg = src_ctx->external_fg;
96  dst_ctx->frame_id_alloc_mask = src_ctx->frame_id_alloc_mask;
97 
98  return 0;
99 }
100 
101 int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
102 {
105  return 0;
106 }
107 
109 {
110  int err;
111  AVFrame *avf = av_frame_alloc();
112  if (!avf)
113  return NULL;
114 
115  err = av_hwframe_get_buffer(ctx->common.dpb_hwfc_ref, avf, 0x0);
116  if (err < 0)
117  av_frame_free(&avf);
118 
119  return avf;
120 }
121 
123  FFVulkanDecodePicture *vkpic, int is_current,
124  int alloc_dpb)
125 {
126  int err;
128  FFVulkanFunctions *vk = &ctx->s.vkfn;
129 
130  vkpic->slices_size = 0;
131 
132  /* If the decoder made a blank frame to make up for a missing ref, or the
133  * frame is the current frame so it's missing one, create a re-representation */
134  if (vkpic->img_view_ref)
135  return 0;
136 
137  vkpic->dpb_frame = NULL;
138  vkpic->img_view_ref = VK_NULL_HANDLE;
139  vkpic->img_view_out = VK_NULL_HANDLE;
140  vkpic->img_view_dest = VK_NULL_HANDLE;
141 
142  vkpic->destroy_image_view = vk->DestroyImageView;
143  vkpic->wait_semaphores = vk->WaitSemaphores;
144 
145  if (ctx->common.layered_dpb && alloc_dpb) {
146  vkpic->img_view_ref = ctx->common.layered_view;
147  vkpic->img_aspect_ref = ctx->common.layered_aspect;
148  } else if (alloc_dpb) {
149  AVHWFramesContext *dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
150  AVVulkanFramesContext *dpb_hwfc = dpb_frames->hwctx;
151 
152  vkpic->dpb_frame = vk_get_dpb_pool(ctx);
153  if (!vkpic->dpb_frame)
154  return AVERROR(ENOMEM);
155 
156  err = ff_vk_create_view(&ctx->s, &ctx->common,
157  &vkpic->img_view_ref, &vkpic->img_aspect_ref,
158  (AVVkFrame *)vkpic->dpb_frame->data[0],
159  dpb_hwfc->format[0], !is_current);
160  if (err < 0)
161  return err;
162 
163  vkpic->img_view_dest = vkpic->img_view_ref;
164  }
165 
166  if (!alloc_dpb || is_current) {
168  AVVulkanFramesContext *hwfc = frames->hwctx;
169 
170  err = ff_vk_create_view(&ctx->s, &ctx->common,
171  &vkpic->img_view_out, &vkpic->img_aspect,
172  (AVVkFrame *)pic->data[0],
173  hwfc->format[0], !is_current);
174  if (err < 0)
175  return err;
176 
177  if (!alloc_dpb) {
178  vkpic->img_view_ref = vkpic->img_view_out;
179  vkpic->img_aspect_ref = vkpic->img_aspect;
180  }
181  }
182 
183  return 0;
184 }
185 
187  const uint8_t *data, size_t size, int add_startcode,
188  uint32_t *nb_slices, const uint32_t **offsets)
189 {
192 
193  static const uint8_t startcode_prefix[3] = { 0x0, 0x0, 0x1 };
194  const size_t startcode_len = add_startcode ? sizeof(startcode_prefix) : 0;
195  const int nb = *nb_slices;
196  uint8_t *slices;
197  uint32_t *slice_off;
198  FFVkBuffer *vkbuf;
199 
200  size_t new_size = vp->slices_size + startcode_len + size +
201  ctx->caps.minBitstreamBufferSizeAlignment;
202  new_size = FFALIGN(new_size, ctx->caps.minBitstreamBufferSizeAlignment);
203 
204  slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
205  (nb + 1)*sizeof(slice_off));
206  if (!slice_off)
207  return AVERROR(ENOMEM);
208 
209  *offsets = dec->slice_off = slice_off;
210  slice_off[nb] = vp->slices_size;
211 
212  vkbuf = vp->slices_buf ? (FFVkBuffer *)vp->slices_buf->data : NULL;
213  if (!vkbuf || vkbuf->size < new_size) {
214  int err;
215  AVBufferRef *new_ref;
216  FFVkBuffer *new_buf;
217 
218  /* No point in requesting anything smaller. */
219  size_t buf_size = FFMAX(new_size, 1024*1024);
220 
221  /* Align buffer to nearest power of two. Makes fragmentation management
222  * easier, and gives us ample headroom. */
223  buf_size = 2 << av_log2(buf_size);
224 
225  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_ref,
226  VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR,
227  ctx->s.hwfc->create_pnext, buf_size,
228  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
229  if (err < 0)
230  return err;
231 
232  new_buf = (FFVkBuffer *)new_ref->data;
233 
234  /* Copy data from the old buffer */
235  if (vkbuf) {
236  memcpy(new_buf->mapped_mem, vkbuf->mapped_mem, vp->slices_size);
238  }
239 
240  vp->slices_buf = new_ref;
241  vkbuf = new_buf;
242  }
243  slices = vkbuf->mapped_mem;
244 
245  /* Startcode */
246  memcpy(slices + vp->slices_size, startcode_prefix, startcode_len);
247 
248  /* Slice data */
249  memcpy(slices + vp->slices_size + startcode_len, data, size);
250 
251  *nb_slices = nb + 1;
252  vp->slices_size += startcode_len + size;
253 
254  return 0;
255 }
256 
258 {
261 
262  FFVulkanFunctions *vk = &ctx->s.vkfn;
263  VkVideoBeginCodingInfoKHR decode_start = {
264  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
265  .videoSession = ctx->common.session,
266  .videoSessionParameters = ctx->empty_session_params,
267  };
268  VkVideoCodingControlInfoKHR decode_ctrl = {
269  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
270  .flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
271  };
272  VkVideoEndCodingInfoKHR decode_end = {
273  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
274  };
275 
276  VkCommandBuffer cmd_buf;
277  FFVkExecContext *exec;
278 
279  exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
280  ff_vk_exec_start(&ctx->s, exec);
281  cmd_buf = exec->buf;
282 
283  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
284  vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
285  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
286  ff_vk_exec_submit(&ctx->s, exec);
287 }
288 
290  AVFrame *pic, FFVulkanDecodePicture *vp,
291  AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
292 {
293  int err;
294  VkResult ret;
295  VkCommandBuffer cmd_buf;
296  FFVkBuffer *sd_buf;
297 
300  FFVulkanFunctions *vk = &ctx->s.vkfn;
301 
302  /* Output */
303  AVVkFrame *vkf = (AVVkFrame *)pic->buf[0]->data;
304 
305  /* Quirks */
306  const int layered_dpb = ctx->common.layered_dpb;
307 
308  VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)dec->session_params->data;
309  VkVideoBeginCodingInfoKHR decode_start = {
310  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
311  .videoSession = ctx->common.session,
312  .videoSessionParameters = *par,
313  .referenceSlotCount = vp->decode_info.referenceSlotCount,
314  .pReferenceSlots = vp->decode_info.pReferenceSlots,
315  };
316  VkVideoEndCodingInfoKHR decode_end = {
317  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
318  };
319 
320  VkImageMemoryBarrier2 img_bar[37];
321  int nb_img_bar = 0;
322  size_t data_size = FFALIGN(vp->slices_size,
323  ctx->caps.minBitstreamBufferSizeAlignment);
324 
325  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
326 
327  /* The current decoding reference has to be bound as an inactive reference */
328  VkVideoReferenceSlotInfoKHR *cur_vk_ref;
329  cur_vk_ref = (void *)&decode_start.pReferenceSlots[decode_start.referenceSlotCount];
330  cur_vk_ref[0] = vp->ref_slot;
331  cur_vk_ref[0].slotIndex = -1;
332  decode_start.referenceSlotCount++;
333 
334  sd_buf = (FFVkBuffer *)vp->slices_buf->data;
335 
336  /* Flush if needed */
337  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
338  VkMappedMemoryRange flush_buf = {
339  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
340  .memory = sd_buf->mem,
341  .offset = 0,
342  .size = FFALIGN(vp->slices_size,
343  ctx->s.props.properties.limits.nonCoherentAtomSize),
344  };
345 
346  ret = vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &flush_buf);
347  if (ret != VK_SUCCESS) {
348  av_log(avctx, AV_LOG_ERROR, "Failed to flush memory: %s\n",
349  ff_vk_ret2str(ret));
350  return AVERROR_EXTERNAL;
351  }
352  }
353 
354  vp->decode_info.srcBuffer = sd_buf->buf;
355  vp->decode_info.srcBufferOffset = 0;
356  vp->decode_info.srcBufferRange = data_size;
357 
358  /* Start command buffer recording */
359  err = ff_vk_exec_start(&ctx->s, exec);
360  if (err < 0)
361  return err;
362  cmd_buf = exec->buf;
363 
364  /* Slices */
365  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0);
366  if (err < 0)
367  return err;
368  vp->slices_buf = NULL; /* Owned by the exec buffer from now on */
369 
370  /* Parameters */
371  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &dec->session_params, 1, 1);
372  if (err < 0)
373  return err;
374 
375  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, pic,
376  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
377  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
378  if (err < 0)
379  return err;
380 
381  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
382  pic);
383  if (err < 0)
384  return err;
385 
386  /* Output image - change layout, as it comes from a pool */
387  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
388  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
389  .pNext = NULL,
390  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
391  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
392  .srcAccessMask = VK_ACCESS_2_NONE,
393  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
394  .oldLayout = vkf->layout[0],
395  .newLayout = (layered_dpb || vp->dpb_frame) ?
396  VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
397  VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, /* Spec, 07252 utter madness */
398  .srcQueueFamilyIndex = vkf->queue_family[0],
399  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
400  .image = vkf->img[0],
401  .subresourceRange = (VkImageSubresourceRange) {
402  .aspectMask = vp->img_aspect,
403  .layerCount = 1,
404  .levelCount = 1,
405  },
406  };
407  ff_vk_exec_update_frame(&ctx->s, exec, pic,
408  &img_bar[nb_img_bar], &nb_img_bar);
409 
410  /* Reference for the current image, if existing and not layered */
411  if (vp->dpb_frame) {
412  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
413  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
414  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
415  if (err < 0)
416  return err;
417  }
418 
419  if (!layered_dpb) {
420  /* All references (apart from the current) for non-layered refs */
421 
422  for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
423  AVFrame *ref_frame = rpic[i];
424  FFVulkanDecodePicture *rvp = rvkp[i];
425  AVFrame *ref = rvp->dpb_frame ? rvp->dpb_frame : ref_frame;
426 
427  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref,
428  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
429  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
430  if (err < 0)
431  return err;
432 
433  if (err == 0) {
434  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec,
435  &rvp->sem, &rvp->sem_value,
436  ref);
437  if (err < 0)
438  return err;
439  }
440 
441  if (!rvp->dpb_frame) {
442  AVVkFrame *rvkf = (AVVkFrame *)ref->data[0];
443 
444  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
445  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
446  .pNext = NULL,
447  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
448  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
449  .srcAccessMask = VK_ACCESS_2_NONE,
450  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR |
451  VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
452  .oldLayout = rvkf->layout[0],
453  .newLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
454  .srcQueueFamilyIndex = rvkf->queue_family[0],
455  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
456  .image = rvkf->img[0],
457  .subresourceRange = (VkImageSubresourceRange) {
458  .aspectMask = rvp->img_aspect_ref,
459  .layerCount = 1,
460  .levelCount = 1,
461  },
462  };
463  ff_vk_exec_update_frame(&ctx->s, exec, ref,
464  &img_bar[nb_img_bar], &nb_img_bar);
465  }
466  }
467  } else if (vp->decode_info.referenceSlotCount ||
468  vp->img_view_out != vp->img_view_ref) {
469  /* Single barrier for a single layered ref */
470  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
471  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
472  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
473  if (err < 0)
474  return err;
475  }
476 
477  /* Change image layout */
478  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
479  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
480  .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
481  .pImageMemoryBarriers = img_bar,
482  .imageMemoryBarrierCount = nb_img_bar,
483  });
484 
485  /* Start, use parameters, decode and end decoding */
486  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
487  vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
488  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
489 
490  /* End recording and submit for execution */
491  return ff_vk_exec_submit(&ctx->s, exec);
492 }
493 
495 {
496  AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
497 
498  VkSemaphoreWaitInfo sem_wait = (VkSemaphoreWaitInfo) {
499  .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
500  .pSemaphores = &vp->sem,
501  .pValues = &vp->sem_value,
502  .semaphoreCount = 1,
503  };
504 
505  /* We do not have to lock the frame here because we're not interested
506  * in the actual current semaphore value, but only that it's later than
507  * the time we submitted the image for decoding. */
508  if (vp->sem)
509  vp->wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
510 
511  /* Free slices data */
513 
514  /* Destroy image view (out) */
515  if (vp->img_view_out && vp->img_view_out != vp->img_view_dest)
516  vp->destroy_image_view(hwctx->act_dev, vp->img_view_out, hwctx->alloc);
517 
518  /* Destroy image view (ref, unlayered) */
519  if (vp->img_view_dest)
520  vp->destroy_image_view(hwctx->act_dev, vp->img_view_dest, hwctx->alloc);
521 
522  av_frame_free(&vp->dpb_frame);
523 }
524 
525 static void free_common(AVRefStructOpaque unused, void *obj)
526 {
527  FFVulkanDecodeShared *ctx = obj;
528  FFVulkanContext *s = &ctx->s;
529  FFVulkanFunctions *vk = &ctx->s.vkfn;
530 
531  /* Wait on and free execution pool */
532  ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
533 
534  /* This also frees all references from this pool */
535  av_frame_free(&ctx->common.layered_frame);
536 
537  /* Destroy parameters */
538  if (ctx->empty_session_params)
539  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
540  ctx->empty_session_params,
541  s->hwctx->alloc);
542 
543  av_buffer_pool_uninit(&ctx->buf_pool);
544 
545  ff_vk_video_common_uninit(s, &ctx->common);
546 
547  ff_vk_uninit(s);
548 }
549 
550 static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
551 {
552  int err;
555  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
556  AVVulkanDeviceContext *hwctx = device->hwctx;
558 
559  if (dec->shared_ctx)
560  return 0;
561 
562  dec->shared_ctx = av_refstruct_alloc_ext(sizeof(*ctx), 0, NULL,
563  free_common);
564  if (!dec->shared_ctx)
565  return AVERROR(ENOMEM);
566 
567  ctx = dec->shared_ctx;
568 
569  ctx->s.extensions = ff_vk_extensions_to_mask(hwctx->enabled_dev_extensions,
571 
572  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_DECODE_QUEUE)) {
573  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
574  VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
576  return AVERROR(ENOSYS);
577  }
578 
579  err = ff_vk_load_functions(device, &ctx->s.vkfn, ctx->s.extensions, 1, 1);
580  if (err < 0) {
582  return err;
583  }
584 
585  return 0;
586 }
587 
588 static VkResult vulkan_setup_profile(AVCodecContext *avctx,
590  AVVulkanDeviceContext *hwctx,
591  FFVulkanFunctions *vk,
592  const FFVulkanDecodeDescriptor *vk_desc,
593  VkVideoDecodeH264CapabilitiesKHR *h264_caps,
594  VkVideoDecodeH265CapabilitiesKHR *h265_caps,
595  VkVideoDecodeAV1CapabilitiesKHR *av1_caps,
596  VkVideoCapabilitiesKHR *caps,
597  VkVideoDecodeCapabilitiesKHR *dec_caps,
598  int cur_profile)
599 {
600  VkVideoDecodeUsageInfoKHR *usage = &prof->usage;
601  VkVideoProfileInfoKHR *profile = &prof->profile;
602  VkVideoProfileListInfoKHR *profile_list = &prof->profile_list;
603 
604  VkVideoDecodeH264ProfileInfoKHR *h264_profile = &prof->h264_profile;
605  VkVideoDecodeH265ProfileInfoKHR *h265_profile = &prof->h265_profile;
606  VkVideoDecodeAV1ProfileInfoKHR *av1_profile = &prof->av1_profile;
607 
609  if (!desc)
610  return AVERROR(EINVAL);
611 
612  if (avctx->codec_id == AV_CODEC_ID_H264) {
613  dec_caps->pNext = h264_caps;
614  usage->pNext = h264_profile;
615  h264_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
616 
617  /* Vulkan transmits all the constrant_set flags, rather than wanting them
618  * merged in the profile IDC */
619  h264_profile->stdProfileIdc = cur_profile & ~(AV_PROFILE_H264_CONSTRAINED |
621 
622  h264_profile->pictureLayout = avctx->field_order == AV_FIELD_UNKNOWN ||
624  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
625  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
626  } else if (avctx->codec_id == AV_CODEC_ID_H265) {
627  dec_caps->pNext = h265_caps;
628  usage->pNext = h265_profile;
629  h265_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
630  h265_profile->stdProfileIdc = cur_profile;
631  } else if (avctx->codec_id == AV_CODEC_ID_AV1) {
632  dec_caps->pNext = av1_caps;
633  usage->pNext = av1_profile;
634  av1_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
635  av1_profile->stdProfile = cur_profile;
636  av1_profile->filmGrainSupport = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
637  }
638 
639  usage->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR;
640  usage->videoUsageHints = VK_VIDEO_DECODE_USAGE_DEFAULT_KHR;
641 
642  profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
643  profile->pNext = usage;
644  profile->videoCodecOperation = vk_desc->decode_op;
645  profile->chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
646  profile->lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
647  profile->chromaBitDepth = profile->lumaBitDepth;
648 
649  profile_list->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
650  profile_list->profileCount = 1;
651  profile_list->pProfiles = profile;
652 
653  /* Get the capabilities of the decoder for the given profile */
654  caps->sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
655  caps->pNext = dec_caps;
656  dec_caps->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR;
657  /* dec_caps->pNext already filled in */
658 
659  return vk->GetPhysicalDeviceVideoCapabilitiesKHR(hwctx->phys_dev, profile,
660  caps);
661 }
662 
663 static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref,
664  enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt,
666  int *dpb_dedicate)
667 {
668  VkResult ret;
669  int max_level, base_profile, cur_profile;
670  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
672  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
673  AVVulkanDeviceContext *hwctx = device->hwctx;
674  enum AVPixelFormat source_format;
675  enum AVPixelFormat best_format;
676  VkFormat best_vkfmt;
677 
680  FFVulkanFunctions *vk = &ctx->s.vkfn;
681 
682  VkVideoCapabilitiesKHR *caps = &ctx->caps;
683  VkVideoDecodeCapabilitiesKHR *dec_caps = &ctx->dec_caps;
684 
685  VkVideoDecodeH264CapabilitiesKHR h264_caps = {
686  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR,
687  };
688  VkVideoDecodeH265CapabilitiesKHR h265_caps = {
689  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR,
690  };
691  VkVideoDecodeAV1CapabilitiesKHR av1_caps = {
692  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR,
693  };
694 
695  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
696  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
697  .pNext = &prof->profile_list,
698  };
699  VkVideoFormatPropertiesKHR *ret_info;
700  uint32_t nb_out_fmts = 0;
701 
702  if (!(vk_desc->decode_extension & ctx->s.extensions)) {
703  av_log(avctx, AV_LOG_ERROR, "Device does not support decoding %s!\n",
704  avcodec_get_name(avctx->codec_id));
705  return AVERROR(ENOSYS);
706  }
707 
708  cur_profile = avctx->profile;
711  avctx->codec_id == AV_CODEC_ID_AV1 ? STD_VIDEO_AV1_PROFILE_MAIN :
712  0;
713 
714  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
715  &h264_caps,
716  &h265_caps,
717  &av1_caps,
718  caps,
719  dec_caps,
720  cur_profile);
721  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR &&
723  avctx->profile != base_profile) {
724  av_log(avctx, AV_LOG_VERBOSE, "%s profile %s not supported, attempting "
725  "again with profile %s\n",
726  avcodec_get_name(avctx->codec_id),
727  avcodec_profile_name(avctx->codec_id, cur_profile),
728  avcodec_profile_name(avctx->codec_id, base_profile));
729  cur_profile = base_profile;
730  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
731  &h264_caps,
732  &h265_caps,
733  &av1_caps,
734  caps,
735  dec_caps,
736  cur_profile);
737  }
738 
739  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
740  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
741  "%s profile \"%s\" not supported!\n",
742  avcodec_get_name(avctx->codec_id),
743  avcodec_profile_name(avctx->codec_id, cur_profile));
744  return AVERROR(EINVAL);
745  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
746  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
747  "format (%s) not supported!\n",
749  return AVERROR(EINVAL);
750  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
751  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
752  return AVERROR(EINVAL);
753  } else if (ret != VK_SUCCESS) {
754  return AVERROR_EXTERNAL;
755  }
756 
757  max_level = avctx->codec_id == AV_CODEC_ID_H264 ? ff_vk_h264_level_to_av(h264_caps.maxLevelIdc) :
758  avctx->codec_id == AV_CODEC_ID_H265 ? ff_vk_h265_level_to_av(h265_caps.maxLevelIdc) :
759  avctx->codec_id == AV_CODEC_ID_AV1 ? av1_caps.maxLevel :
760  0;
761 
762  av_log(avctx, AV_LOG_VERBOSE, "Decoder capabilities for %s profile \"%s\":\n",
763  avcodec_get_name(avctx->codec_id),
764  avcodec_profile_name(avctx->codec_id, cur_profile));
765  av_log(avctx, AV_LOG_VERBOSE, " Maximum level: %i (stream %i)\n",
766  max_level, avctx->level);
767  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
768  caps->minCodedExtent.width, caps->maxCodedExtent.width);
769  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
770  caps->minCodedExtent.height, caps->maxCodedExtent.height);
771  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
772  caps->pictureAccessGranularity.width);
773  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
774  caps->pictureAccessGranularity.height);
775  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
776  caps->minBitstreamBufferOffsetAlignment);
777  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
778  caps->minBitstreamBufferSizeAlignment);
779  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
780  caps->maxDpbSlots);
781  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
782  caps->maxActiveReferencePictures);
783  av_log(avctx, AV_LOG_VERBOSE, " Codec header name: '%s' (driver), '%s' (compiled)\n",
784  caps->stdHeaderVersion.extensionName,
785  vk_desc->ext_props.extensionName);
786  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
787  CODEC_VER(caps->stdHeaderVersion.specVersion),
788  CODEC_VER(vk_desc->ext_props.specVersion));
789  av_log(avctx, AV_LOG_VERBOSE, " Decode modes:%s%s%s\n",
790  dec_caps->flags ? "" :
791  " invalid",
792  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR ?
793  " reuse_dst_dpb" : "",
794  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR ?
795  " dedicated_dpb" : "");
796  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
797  caps->flags ? "" :
798  " none",
799  caps->flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
800  " protected" : "",
801  caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
802  " separate_references" : "");
803 
804  /* Check if decoding is possible with the given parameters */
805  if (avctx->coded_width < caps->minCodedExtent.width ||
806  avctx->coded_height < caps->minCodedExtent.height ||
807  avctx->coded_width > caps->maxCodedExtent.width ||
808  avctx->coded_height > caps->maxCodedExtent.height)
809  return AVERROR(EINVAL);
810 
812  avctx->level > max_level)
813  return AVERROR(EINVAL);
814 
815  /* Some basic sanity checking */
816  if (!(dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
817  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR))) {
818  av_log(avctx, AV_LOG_ERROR, "Buggy driver signals invalid decoding mode: neither "
819  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR nor "
820  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR are set!\n");
821  return AVERROR_EXTERNAL;
822  } else if ((dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
823  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ==
824  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) &&
825  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR)) {
826  av_log(avctx, AV_LOG_ERROR, "Cannot initialize Vulkan decoding session, buggy driver: "
827  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set "
828  "but VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!\n");
829  return AVERROR_EXTERNAL;
830  }
831 
832  dec->dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
833  ctx->common.layered_dpb = !dec->dedicated_dpb ? 0 :
834  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
835 
836  if (dec->dedicated_dpb) {
837  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
838  } else {
839  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
840  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
841  VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
842  VK_IMAGE_USAGE_SAMPLED_BIT;
843 
844  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
846  fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
847  }
848 
849  /* Get the format of the images necessary */
850  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
851  &fmt_info,
852  &nb_out_fmts, NULL);
853  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
854  (!nb_out_fmts && ret == VK_SUCCESS)) {
855  return AVERROR(EINVAL);
856  } else if (ret != VK_SUCCESS) {
857  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
858  ff_vk_ret2str(ret));
859  return AVERROR_EXTERNAL;
860  }
861 
862  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
863  if (!ret_info)
864  return AVERROR(ENOMEM);
865 
866  for (int i = 0; i < nb_out_fmts; i++)
867  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
868 
869  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
870  &fmt_info,
871  &nb_out_fmts, ret_info);
872  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
873  (!nb_out_fmts && ret == VK_SUCCESS)) {
874  av_free(ret_info);
875  return AVERROR(EINVAL);
876  } else if (ret != VK_SUCCESS) {
877  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
878  ff_vk_ret2str(ret));
879  av_free(ret_info);
880  return AVERROR_EXTERNAL;
881  }
882 
883  /* Find a format to use */
884  *pix_fmt = best_format = AV_PIX_FMT_NONE;
885  *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
886  source_format = avctx->sw_pix_fmt;
887 
888  av_log(avctx, AV_LOG_DEBUG, "Choosing best pixel format for decoding from %i:\n", nb_out_fmts);
889  for (int i = 0; i < nb_out_fmts; i++) {
891  if (tmp == AV_PIX_FMT_NONE) {
892  av_log(avctx, AV_LOG_WARNING, "Invalid/unknown Vulkan format %i!\n", ret_info[i].format);
893  continue;
894  }
895 
896  best_format = av_find_best_pix_fmt_of_2(tmp, best_format, source_format, 0, NULL);
897  if (tmp == best_format)
898  best_vkfmt = ret_info[i].format;
899 
900  av_log(avctx, AV_LOG_DEBUG, " %s%s (Vulkan ID: %i)\n",
901  av_get_pix_fmt_name(tmp), tmp == best_format ? "*" : "",
902  ret_info[i].format);
903  }
904 
905  av_free(ret_info);
906 
907  if (best_format == AV_PIX_FMT_NONE) {
908  av_log(avctx, AV_LOG_ERROR, "No valid/compatible pixel format found for decoding!\n");
909  return AVERROR(EINVAL);
910  } else {
911  av_log(avctx, AV_LOG_VERBOSE, "Chosen frame pixfmt: %s (Vulkan ID: %i)\n",
912  av_get_pix_fmt_name(best_format), best_vkfmt);
913  }
914 
915  *pix_fmt = best_format;
916  *vk_fmt = best_vkfmt;
917 
918  *dpb_dedicate = dec->dedicated_dpb;
919 
920  return 0;
921 }
922 
924 {
925  av_free(hwfc->user_opaque);
926 }
927 
928 int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
929 {
930  VkFormat vkfmt;
931  int err, dedicated_dpb;
932  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
933  AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
937 
938  frames_ctx->sw_format = AV_PIX_FMT_NONE;
939 
940  err = vulkan_decode_bootstrap(avctx, hw_frames_ctx);
941  if (err < 0)
942  return err;
943 
944  prof = av_mallocz(sizeof(FFVulkanDecodeProfileData));
945  if (!prof)
946  return AVERROR(ENOMEM);
947 
948  err = vulkan_decode_get_profile(avctx, hw_frames_ctx,
949  &frames_ctx->sw_format, &vkfmt,
950  prof, &dedicated_dpb);
951  if (err < 0) {
952  av_free(prof);
953  return err;
954  }
955 
956  frames_ctx->user_opaque = prof;
957  frames_ctx->free = free_profile_data;
958 
959  frames_ctx->width = avctx->coded_width;
960  frames_ctx->height = avctx->coded_height;
961  frames_ctx->format = AV_PIX_FMT_VULKAN;
962 
963  hwfc->format[0] = vkfmt;
964  hwfc->create_pnext = &prof->profile_list;
965  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
966  hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
967  VK_IMAGE_USAGE_SAMPLED_BIT |
968  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
969 
970  if (!dec->dedicated_dpb)
971  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
972 
973  ctx = dec->shared_ctx;
974  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
976  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
977 
978  return err;
979 }
980 
981 static void vk_decode_free_params(void *opaque, uint8_t *data)
982 {
983  FFVulkanDecodeShared *ctx = opaque;
984  FFVulkanFunctions *vk = &ctx->s.vkfn;
985  VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)data;
986  vk->DestroyVideoSessionParametersKHR(ctx->s.hwctx->act_dev, *par,
987  ctx->s.hwctx->alloc);
988  av_free(par);
989 }
990 
992  const VkVideoSessionParametersCreateInfoKHR *session_params_create)
993 {
994  VkVideoSessionParametersKHR *par = av_malloc(sizeof(*par));
995  const FFVulkanFunctions *vk = &ctx->s.vkfn;
996  VkResult ret;
997 
998  if (!par)
999  return AVERROR(ENOMEM);
1000 
1001  /* Create session parameters */
1002  ret = vk->CreateVideoSessionParametersKHR(ctx->s.hwctx->act_dev, session_params_create,
1003  ctx->s.hwctx->alloc, par);
1004  if (ret != VK_SUCCESS) {
1005  av_log(logctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1006  ff_vk_ret2str(ret));
1007  av_free(par);
1008  return AVERROR_EXTERNAL;
1009  }
1010  *par_ref = av_buffer_create((uint8_t *)par, sizeof(*par),
1012  if (!*par_ref) {
1013  vk_decode_free_params(ctx, (uint8_t *)par);
1014  return AVERROR(ENOMEM);
1015  }
1016 
1017  return 0;
1018 }
1019 
1021 {
1023 
1024  av_freep(&dec->hevc_headers);
1027  av_freep(&dec->slice_off);
1028  return 0;
1029 }
1030 
1032 {
1033  int err;
1034  VkResult ret;
1037  FFVulkanContext *s;
1038  FFVulkanFunctions *vk;
1039  const VkVideoProfileInfoKHR *profile;
1040  const FFVulkanDecodeDescriptor *vk_desc;
1041  const VkPhysicalDeviceDriverProperties *driver_props;
1042 
1043  VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
1044  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
1045  };
1046  VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
1047  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1048  };
1049  StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
1050  VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
1051  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
1052  .pStdSequenceHeader = &av1_empty_seq,
1053  };
1054  VkVideoSessionParametersCreateInfoKHR session_params_create = {
1055  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1056  .pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
1057  avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
1058  avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
1059  NULL,
1060  };
1061  VkVideoSessionCreateInfoKHR session_create = {
1062  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1063  };
1064 
1066  if (err < 0)
1067  return err;
1068 
1069  /* Initialize contexts */
1070  ctx = dec->shared_ctx;
1071  s = &ctx->s;
1072  vk = &ctx->s.vkfn;
1073 
1074  err = ff_vk_init(s, avctx, NULL, avctx->hw_frames_ctx);
1075  if (err < 0)
1076  return err;
1077 
1079  if (!profile) {
1080  av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
1081  return AVERROR(EINVAL);
1082  }
1083 
1084  /* Create queue context */
1085  vk_desc = get_codecdesc(avctx->codec_id);
1086  ctx->qf = ff_vk_qf_find(s, vk_desc->queue_flags, vk_desc->decode_op);
1087  if (!ctx->qf) {
1088  av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
1089  avcodec_get_name(avctx->codec_id));
1090  return err;
1091  }
1092 
1093  session_create.flags = 0x0;
1094  session_create.queueFamilyIndex = ctx->qf->idx;
1095  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1096  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1097  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1098  session_create.pictureFormat = s->hwfc->format[0];
1099  session_create.referencePictureFormat = session_create.pictureFormat;
1100  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1101  session_create.pVideoProfile = profile;
1102 
1103  /* Create decode exec context for this specific main thread.
1104  * 2 async contexts per thread was experimentally determined to be optimal
1105  * for a majority of streams. */
1106  err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
1107  FFMAX(2*ctx->qf->num, avctx->thread_count),
1108  0, 0, 0, profile);
1109  if (err < 0)
1110  goto fail;
1111 
1112  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1113  if (err < 0)
1114  goto fail;
1115 
1116  /* If doing an out-of-place decoding, create a DPB pool */
1117  if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) {
1119  AVVulkanFramesContext *dpb_hwfc;
1120 
1121  ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref);
1122  if (!ctx->common.dpb_hwfc_ref) {
1123  err = AVERROR(ENOMEM);
1124  goto fail;
1125  }
1126 
1127  dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
1128  dpb_frames->format = s->frames->format;
1129  dpb_frames->sw_format = s->frames->sw_format;
1130  dpb_frames->width = avctx->coded_width;
1131  dpb_frames->height = avctx->coded_height;
1132 
1133  dpb_hwfc = dpb_frames->hwctx;
1134  dpb_hwfc->create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1135  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1136  dpb_hwfc->format[0] = s->hwfc->format[0];
1137  dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1138  dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1139  VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */
1140 
1141  if (ctx->common.layered_dpb)
1142  dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
1143 
1144  err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref);
1145  if (err < 0)
1146  goto fail;
1147 
1148  if (ctx->common.layered_dpb) {
1149  ctx->common.layered_frame = vk_get_dpb_pool(ctx);
1150  if (!ctx->common.layered_frame) {
1151  err = AVERROR(ENOMEM);
1152  goto fail;
1153  }
1154 
1155  err = ff_vk_create_view(&ctx->s, &ctx->common,
1156  &ctx->common.layered_view,
1157  &ctx->common.layered_aspect,
1158  (AVVkFrame *)ctx->common.layered_frame->data[0],
1159  s->hwfc->format[0], 1);
1160  if (err < 0)
1161  goto fail;
1162  }
1163  }
1164 
1165  session_params_create.videoSession = ctx->common.session;
1166  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1167  s->hwctx->alloc, &ctx->empty_session_params);
1168  if (ret != VK_SUCCESS) {
1169  av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
1170  ff_vk_ret2str(ret));
1171  return AVERROR_EXTERNAL;
1172  }
1173 
1174  driver_props = &dec->shared_ctx->s.driver_props;
1175  if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1176  driver_props->conformanceVersion.major == 1 &&
1177  driver_props->conformanceVersion.minor == 3 &&
1178  driver_props->conformanceVersion.subminor == 8 &&
1179  driver_props->conformanceVersion.patch < 3)
1180  dec->quirk_av1_offset = 1;
1181 
1182  ff_vk_decode_flush(avctx);
1183 
1184  av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization sucessful\n");
1185 
1186  return 0;
1187 
1188 fail:
1189  ff_vk_decode_uninit(avctx);
1190 
1191  return err;
1192 }
vulkan_loader.h
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AVVulkanDeviceContext::phys_dev
VkPhysicalDevice phys_dev
Physical device.
Definition: hwcontext_vulkan.h:79
FFVulkanDecodePicture::slices_size
size_t slices_size
Definition: vulkan_decode.h:106
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
FFVulkanDecodeShared::s
FFVulkanContext s
Definition: vulkan_decode.h:48
FFVulkanDecodeProfileData::profile
VkVideoProfileInfoKHR profile
Definition: vulkan_decode.h:43
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.h:40
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3244
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FFVulkanDecodeContext::shared_ctx
FFVulkanDecodeShared * shared_ctx
Definition: vulkan_decode.h:62
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:202
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:296
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:197
dpb_frames
int dpb_frames
Definition: h264_levels.c:163
AV_PROFILE_HEVC_MAIN
#define AV_PROFILE_HEVC_MAIN
Definition: defs.h:159
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:766
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:163
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:322
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:410
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
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:248
AVHWFramesContext::free
void(* free)(struct AVHWFramesContext *ctx)
This field may be set by the caller before calling av_hwframe_ctx_init().
Definition: hwcontext.h:158
AVCodecContext::field_order
enum AVFieldOrder field_order
Field order.
Definition: avcodec.h:722
AVVulkanFramesContext::create_pnext
void * create_pnext
Extension data for image creation.
Definition: hwcontext_vulkan.h:243
ff_vk_find_struct
static const void * ff_vk_find_struct(const void *chain, VkStructureType stype)
Definition: vulkan.h:321
b
#define b
Definition: input.c:41
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:271
FFVulkanDecodeContext::frame_id_alloc_mask
uint32_t frame_id_alloc_mask
Definition: vulkan_decode.h:67
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
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:2622
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:477
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2611
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:442
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:217
FFVulkanDecodeProfileData::av1_profile
VkVideoDecodeAV1ProfileInfoKHR av1_profile
Definition: vulkan_decode.h:41
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:623
FFVulkanDecodeContext
Definition: vulkan_decode.h:61
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:696
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:122
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:2168
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:431
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:88
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_HWDEVICE_TYPE_VULKAN
@ AV_HWDEVICE_TYPE_VULKAN
Definition: hwcontext.h:39
FFVulkanDecodeContext::session_params
AVBufferRef * session_params
Definition: vulkan_decode.h:63
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
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:307
FFVulkanDecodeDescriptor::decode_op
VkVideoCodecOperationFlagBitsKHR decode_op
Definition: vulkan_decode.h:33
fail
#define fail()
Definition: checkasm.h:193
FFVulkanDecodePicture::sem_value
uint64_t sem_value
Definition: vulkan_decode.h:91
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1601
frames
if it could not because there are no more frames
Definition: filter_design.txt:266
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:213
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:508
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:647
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:289
FFVulkanDecodeShared
Definition: vulkan_decode.h:47
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:663
refstruct.h
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:151
FFVulkanDecodeContext::slice_off
uint32_t * slice_off
Definition: vulkan_decode.h:77
avassert.h
FFVulkanDecodePicture::img_view_out
VkImageView img_view_out
Definition: vulkan_decode.h:85
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FFVulkanDecodeProfileData::h264_profile
VkVideoDecodeH264ProfileInfoKHR h264_profile
Definition: vulkan_decode.h:39
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVHWFramesContext::height
int height
Definition: hwcontext.h:217
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:201
FFVulkanDecodeProfileData::profile_list
VkVideoProfileListInfoKHR profile_list
Definition: vulkan_decode.h:44
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:109
s
#define s(width, name)
Definition: cbs_vp9.c:198
FFVulkanDecodePicture
Definition: vulkan_decode.h:81
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:345
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:991
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:785
offsets
static const int offsets[]
Definition: hevc_pel.c:34
FFVulkanContext::driver_props
VkPhysicalDeviceDriverProperties driver_props
Definition: vulkan.h:274
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1451
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
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:105
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
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:230
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:551
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:233
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:1117
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:461
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:58
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:59
FFVulkanDecodePicture::img_view_ref
VkImageView img_view_ref
Definition: vulkan_decode.h:84
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:210
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:494
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:315
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:59
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:486
FFVulkanDecodeProfileData::usage
VkVideoDecodeUsageInfoKHR usage
Definition: vulkan_decode.h:42
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:2188
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:1020
AVVulkanFramesContext::format
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
Definition: hwcontext_vulkan.h:273
FFVkBuffer::size
size_t size
Definition: vulkan.h:91
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:232
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:99
FFVulkanContext
Definition: vulkan.h:266
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:928
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1802
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:60
free_common
static void free_common(AVRefStructOpaque unused, void *obj)
Definition: vulkan_decode.c:525
FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
Definition: vulkan_functions.h:52
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:83
AVVkFrame
Definition: hwcontext_vulkan.h:302
size
int size
Definition: twinvq_data.h:10344
ref_frame
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
Definition: dec.c:593
FFVulkanDecodePicture::img_aspect_ref
VkImageAspectFlags img_aspect_ref
Definition: vulkan_decode.h:88
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:90
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:78
AVVkFrame::queue_family
uint32_t queue_family[AV_NUM_DATA_POINTERS]
Queue family of the images.
Definition: hwcontext_vulkan.h:366
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
FFVkExecContext
Definition: vulkan.h:102
vk_decode_free_params
static void vk_decode_free_params(void *opaque, uint8_t *data)
Definition: vulkan_decode.c:981
FFVulkanDecodeProfileData
Definition: vulkan_decode.h:38
FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
Definition: vulkan_functions.h:54
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:409
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:489
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:1524
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
FFVulkanDecodePicture::ref_slot
VkVideoReferenceSlotInfoKHR ref_slot
Definition: vulkan_decode.h:95
FFVkBuffer::mem
VkDeviceMemory mem
Definition: vulkan.h:89
FFVulkanDecodePicture::sem
VkSemaphore sem
Definition: vulkan_decode.h:90
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:66
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:2233
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:1493
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:115
ff_vk_decode_flush
void ff_vk_decode_flush(AVCodecContext *avctx)
Flush decoder.
Definition: vulkan_decode.c:257
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:150
AVHWFramesContext::user_opaque
void * user_opaque
Arbitrary user data, to be used e.g.
Definition: hwcontext.h:163
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:186
AV_PROFILE_H264_CONSTRAINED
#define AV_PROFILE_H264_CONSTRAINED
Definition: defs.h:107
dec_descs
static const FFVulkanDecodeDescriptor * dec_descs[]
Definition: vulkan_decode.c:37
FFVulkanDecodeContext::hevc_headers
struct HEVCHeaderSet * hevc_headers
Definition: vulkan_decode.h:74
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:220
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:114
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:769
ff_vk_dec_hevc_desc
const FFVulkanDecodeDescriptor ff_vk_dec_hevc_desc
Definition: vulkan_hevc.c:26
get_codecdesc
static const FFVulkanDecodeDescriptor * get_codecdesc(enum AVCodecID codec_id)
Definition: vulkan_decode.c:49
AVCodecContext
main external API structure.
Definition: avcodec.h:451
FFVulkanDecodeContext::dedicated_dpb
int dedicated_dpb
Definition: vulkan_decode.h:65
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:3523
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:1658
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:1956
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:101
FFVulkanDecodePicture::dpb_frame
AVFrame * dpb_frame
Definition: vulkan_decode.h:82
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:80
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:222
vulkan_video.h
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:647
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:278
FFVulkanDecodePicture::slices_buf
AVBufferRef * slices_buf
Definition: vulkan_decode.h:105
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
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
FFVulkanDecodePicture::img_view_dest
VkImageView img_view_dest
Definition: vulkan_decode.h:86
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
decode_end
static av_cold int decode_end(AVCodecContext *avctx)
Definition: 4xm.c:976
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:588
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
FFVkBuffer
Definition: vulkan.h:87
vk_get_dpb_pool
static AVFrame * vk_get_dpb_pool(FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:108
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:811
FFVulkanDecodePicture::destroy_image_view
PFN_vkDestroyImageView destroy_image_view
Definition: vulkan_decode.h:110
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:550
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:1031
FFVulkanDecodePicture::decode_info
VkVideoDecodeInfoKHR decode_info
Definition: vulkan_decode.h:102
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:678
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:491
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
FFVulkanFunctions
Definition: vulkan_functions.h:263
FFVulkanDecodeContext::quirk_av1_offset
int quirk_av1_offset
Definition: vulkan_decode.h:71
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:1178
src
#define src
Definition: vp8dsp.c:248
free_profile_data
static void free_profile_data(AVHWFramesContext *hwfc)
Definition: vulkan_decode.c:923
AV_CODEC_EXPORT_DATA_FILM_GRAIN
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition: avcodec.h:420
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:3164
FFVulkanDecodePicture::img_aspect
VkImageAspectFlags img_aspect
Definition: vulkan_decode.h:87