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/attributes.h"
20 #include "libavutil/refstruct.h"
21 #include "vulkan_video.h"
22 #include "vulkan_decode.h"
23 #include "config_components.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/mem.h"
27 
28 #define DECODER_IS_SDR(codec_id) \
29  (((codec_id) == AV_CODEC_ID_FFV1) || \
30  ((codec_id) == AV_CODEC_ID_DPX) || \
31  ((codec_id) == AV_CODEC_ID_APV) || \
32  ((codec_id) == AV_CODEC_ID_PRORES_RAW) || \
33  ((codec_id) == AV_CODEC_ID_PRORES))
34 
35 #if CONFIG_H264_VULKAN_HWACCEL
37 #endif
38 #if CONFIG_HEVC_VULKAN_HWACCEL
40 #endif
41 #if CONFIG_VP9_VULKAN_HWACCEL
43 #endif
44 #if CONFIG_AV1_VULKAN_HWACCEL
46 #endif
47 #if CONFIG_FFV1_VULKAN_HWACCEL
49 #endif
50 #if CONFIG_PRORES_RAW_VULKAN_HWACCEL
52 #endif
53 #if CONFIG_PRORES_VULKAN_HWACCEL
55 #endif
56 #if CONFIG_DPX_VULKAN_HWACCEL
58 #endif
59 #if CONFIG_APV_VULKAN_HWACCEL
61 #endif
62 
64 #if CONFIG_H264_VULKAN_HWACCEL
66 #endif
67 #if CONFIG_HEVC_VULKAN_HWACCEL
69 #endif
70 #if CONFIG_VP9_VULKAN_HWACCEL
72 #endif
73 #if CONFIG_AV1_VULKAN_HWACCEL
75 #endif
76 #if CONFIG_FFV1_VULKAN_HWACCEL
78 #endif
79 #if CONFIG_PRORES_RAW_VULKAN_HWACCEL
81 #endif
82 #if CONFIG_PRORES_VULKAN_HWACCEL
84 #endif
85 #if CONFIG_DPX_VULKAN_HWACCEL
87 #endif
88 #if CONFIG_APV_VULKAN_HWACCEL
90 #endif
91 };
92 
93 typedef struct FFVulkanDecodeProfileData {
94  VkVideoDecodeH264ProfileInfoKHR h264_profile;
95  VkVideoDecodeH265ProfileInfoKHR h265_profile;
96 #if CONFIG_VP9_VULKAN_HWACCEL
97  VkVideoDecodeVP9ProfileInfoKHR vp9_profile;
98 #endif
99  VkVideoDecodeAV1ProfileInfoKHR av1_profile;
100 
101  VkVideoDecodeUsageInfoKHR usage;
102  VkVideoProfileInfoKHR profile;
103  VkVideoProfileListInfoKHR profile_list;
105 
107 {
108  for (size_t i = 0; i < FF_ARRAY_ELEMS(dec_descs); i++)
109  if (dec_descs[i]->codec_id == codec_id)
110  return dec_descs[i];
111  av_assert1(!"no codec descriptor");
112  return NULL;
113 }
114 
115 static const VkVideoProfileInfoKHR *get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
116 {
117  const VkVideoProfileListInfoKHR *profile_list;
118 
119  VkStructureType profile_struct_type =
120  codec_id == AV_CODEC_ID_H264 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR :
121  codec_id == AV_CODEC_ID_HEVC ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR :
122 #if CONFIG_VP9_VULKAN_HWACCEL
123  codec_id == AV_CODEC_ID_VP9 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR :
124 #endif
125  codec_id == AV_CODEC_ID_AV1 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR :
126  VK_STRUCTURE_TYPE_MAX_ENUM;
127  if (profile_struct_type == VK_STRUCTURE_TYPE_MAX_ENUM)
128  return NULL;
129 
130  profile_list = ff_vk_find_struct(ctx->s.hwfc->create_pnext,
131  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
132  if (!profile_list)
133  return NULL;
134 
135  for (int i = 0; i < profile_list->profileCount; i++)
136  if (ff_vk_find_struct(profile_list->pProfiles[i].pNext, profile_struct_type))
137  return &profile_list->pProfiles[i];
138 
139  return NULL;
140 }
141 
143 {
144  FFVulkanDecodeContext *src_ctx = src->internal->hwaccel_priv_data;
145  FFVulkanDecodeContext *dst_ctx = dst->internal->hwaccel_priv_data;
146 
147  av_refstruct_replace(&dst_ctx->shared_ctx, src_ctx->shared_ctx);
148 
150 
151  dst_ctx->dedicated_dpb = src_ctx->dedicated_dpb;
152  dst_ctx->external_fg = src_ctx->external_fg;
153 
154  return 0;
155 }
156 
157 int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
158 {
161  return 0;
162 }
163 
165 {
166  int err;
167  AVFrame *avf = av_frame_alloc();
168  if (!avf)
169  return NULL;
170 
171  err = av_hwframe_get_buffer(ctx->common.dpb_hwfc_ref, avf, 0x0);
172  if (err < 0)
173  av_frame_free(&avf);
174 
175  return avf;
176 }
177 
179 {
181  FFVulkanFunctions *vk = &ctx->s.vkfn;
182 
183  vkpic->dpb_frame = NULL;
184  vkpic->out_views = NULL;
185  vkpic->view.ref = VK_NULL_HANDLE;
186  vkpic->view.out = VK_NULL_HANDLE;
187 
188  vkpic->invalidate_memory_ranges = vk->InvalidateMappedMemoryRanges;
189 }
190 
192  FFVulkanDecodePicture *vkpic, int is_current,
193  int alloc_dpb)
194 {
195  int err;
197 
198  vkpic->slices_size = 0;
199 
200  /* If the decoder made a blank frame to make up for a missing ref, or the
201  * frame is the current frame so it's missing one, create a re-representation */
202  if (vkpic->view.ref)
203  return 0;
204 
205  init_frame(dec, vkpic);
206 
207  /* Slot 0 holds the output view, slot 1 the DISTINCT-mode reference
208  * view; refcounted, so executions keep them alive past the picture */
209  vkpic->out_views = ff_vk_imageviews_alloc(&ctx->s, 2);
210  if (!vkpic->out_views)
211  return AVERROR(ENOMEM);
212 
213  if (ctx->common.layered_dpb && alloc_dpb) {
214  vkpic->view.ref = ctx->common.layered_view;
215  vkpic->view.aspect_ref = ctx->common.layered_aspect;
216  } else if (alloc_dpb) {
217  AVHWFramesContext *dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
218  AVVulkanFramesContext *dpb_hwfc = dpb_frames->hwctx;
219 
220  vkpic->dpb_frame = vk_get_dpb_pool(ctx);
221  if (!vkpic->dpb_frame)
222  return AVERROR(ENOMEM);
223 
224  err = ff_vk_create_view(&ctx->s, &ctx->common,
225  &vkpic->out_views->views[1], &vkpic->view.aspect_ref,
226  (AVVkFrame *)vkpic->dpb_frame->data[0],
227  dpb_hwfc->format[0], VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR);
228  if (err < 0)
229  return err;
230 
231  vkpic->view.ref = vkpic->out_views->views[1];
232  }
233 
234  if (!alloc_dpb || is_current) {
236  AVVulkanFramesContext *hwfc = frames->hwctx;
237 
238  err = ff_vk_create_view(&ctx->s, &ctx->common,
239  &vkpic->out_views->views[0], &vkpic->view.aspect,
240  (AVVkFrame *)pic->data[0],
241  hwfc->format[0],
242  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
243  (hwfc->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR));
244  // the above fixes VUID-VkVideoBeginCodingInfoKHR-slotIndex-07245
245  if (err < 0)
246  return err;
247  vkpic->view.out = vkpic->out_views->views[0];
248 
249  if (!alloc_dpb) {
250  vkpic->view.ref = vkpic->view.out;
251  vkpic->view.aspect_ref = vkpic->view.aspect;
252  }
253  }
254 
255  return 0;
256 }
257 
259  const uint8_t *data, size_t size, int add_startcode,
260  uint32_t *nb_slices, const uint32_t **offsets)
261 {
264 
265  static const uint8_t startcode_prefix[3] = { 0x0, 0x0, 0x1 };
266  const size_t startcode_len = add_startcode ? sizeof(startcode_prefix) : 0;
267  const int nb = nb_slices ? *nb_slices : 0;
268  uint8_t *slices;
269  uint32_t *slice_off;
270  FFVkBuffer *vkbuf;
271 
272  size_t new_size = vp->slices_size + startcode_len + size +
273  ctx->caps.minBitstreamBufferSizeAlignment;
274  new_size = FFALIGN(new_size, ctx->caps.minBitstreamBufferSizeAlignment);
275 
276  if (offsets) {
277  slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
278  (nb + 1)*sizeof(slice_off));
279  if (!slice_off)
280  return AVERROR(ENOMEM);
281 
282  *offsets = dec->slice_off = slice_off;
283 
284  slice_off[nb] = vp->slices_size;
285  }
286 
287  vkbuf = vp->slices_buf;
288  if (!vkbuf || vkbuf->size < new_size) {
289  int err;
290  FFVkBuffer *new_buf;
291 
292  /* No point in requesting anything smaller. */
293  size_t buf_size = FFMAX(new_size, 1024*1024);
294 
295  /* Align buffer to nearest power of two. Makes fragmentation management
296  * easier, and gives us ample headroom. */
297  buf_size = 2 << av_log2(buf_size);
298 
299  /* When the frames context uses DRM modifier tiling,
300  * hwctx->create_pnext contains VkImageDrmFormatModifierListCreateInfoEXT,
301  * which per spec does not extend VkBufferCreateInfo, so we need to find
302  * the VkVideoProfileListInfoKHR structure within it. */
303  void *buf_pnext = ctx->s.hwfc->create_pnext;
304  if (ctx->s.hwfc->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
305  buf_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
306  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
307 
308  VkBufferUsageFlags buf_usage = DECODER_IS_SDR(avctx->codec_id) ?
309  (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
310  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) :
311  VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR;
312 
313  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_buf,
314  buf_usage, buf_pnext, buf_size,
315  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
316  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
317  if (err < 0)
318  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_buf,
319  buf_usage, buf_pnext, buf_size,
320  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
321  if (err < 0)
322  return err;
323 
324  /* Copy data from the old buffer */
325  if (vkbuf) {
326  memcpy(new_buf->mapped_mem, vkbuf->mapped_mem, vp->slices_size);
328  }
329 
330  vp->slices_buf = new_buf;
331  vkbuf = new_buf;
332  }
333  slices = vkbuf->mapped_mem;
334 
335  /* Startcode */
336  memcpy(slices + vp->slices_size, startcode_prefix, startcode_len);
337 
338  /* Slice data */
339  memcpy(slices + vp->slices_size + startcode_len, data, size);
340 
341  if (nb_slices)
342  *nb_slices = nb + 1;
343 
344  vp->slices_size += startcode_len + size;
345 
346  return 0;
347 }
348 
351  VkVideoSessionParametersKHR *empty_session_params)
352 {
353  if (avctx->codec_id == AV_CODEC_ID_VP9)
354  return 0;
355 
356  VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
357  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
358  };
359  VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
360  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
361  };
362  StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
363  VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
364  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
365  .pStdSequenceHeader = &av1_empty_seq,
366  };
367  VkVideoSessionParametersCreateInfoKHR session_params_create = {
368  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
369  .pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
370  avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
371  avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
372  NULL,
373  .videoSession = ctx->common.session,
374  };
375 
376  VkResult ret;
377  FFVulkanContext *s = &ctx->s;
378  FFVulkanFunctions *vk = &s->vkfn;
379  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
380  s->hwctx->alloc, empty_session_params);
381  if (ret != VK_SUCCESS) {
382  av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
383  ff_vk_ret2str(ret));
384  return AVERROR_EXTERNAL;
385  }
386 
387  return 0;
388 }
389 
391 {
392  int err;
393  FFVulkanContext *s = &ctx->s;
394  FFVulkanFunctions *vk = &s->vkfn;
395 
396  VkVideoBeginCodingInfoKHR decode_start = {
397  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
398  .videoSession = ctx->common.session,
399  };
400 
401  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
403  &decode_start.videoSessionParameters);
404  if (err < 0)
405  return err;
406  }
407 
408  VkVideoCodingControlInfoKHR decode_ctrl = {
409  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
410  .flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
411  };
412  VkVideoEndCodingInfoKHR decode_end = {
413  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
414  };
415 
416  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
417  ff_vk_exec_start(&ctx->s, exec);
418 
419  vk->CmdBeginVideoCodingKHR(exec->buf, &decode_start);
420  vk->CmdControlVideoCodingKHR(exec->buf, &decode_ctrl);
421  vk->CmdEndVideoCodingKHR(exec->buf, &decode_end);
422 
423  err = ff_vk_exec_submit(&ctx->s, exec);
424 
425  if (decode_start.videoSessionParameters) {
426  /* Wait to complete to delete the temporary session parameters */
427  if (err >= 0)
428  ff_vk_exec_wait(&ctx->s, exec);
429 
430  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
431  decode_start.videoSessionParameters,
432  s->hwctx->alloc);
433  }
434 
435  if (err < 0)
436  av_log(avctx, AV_LOG_ERROR, "Unable to reset decoder: %s",
437  ff_vk_ret2str(err));
438 
439  return err;
440 }
441 
443  AVFrame *pic, FFVulkanDecodePicture *vp,
444  AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
445 {
446  int err;
447  VkResult ret;
448  VkCommandBuffer cmd_buf;
449  FFVkBuffer *sd_buf;
450 
453  FFVulkanFunctions *vk = &ctx->s.vkfn;
454 
455  /* Output */
456  AVVkFrame *vkf = (AVVkFrame *)pic->buf[0]->data;
457 
458  /* Quirks */
459  const int layered_dpb = ctx->common.layered_dpb;
460 
461  VkVideoBeginCodingInfoKHR decode_start = {
462  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
463  .videoSession = ctx->common.session,
464  .videoSessionParameters = dec->session_params ?
465  *dec->session_params : VK_NULL_HANDLE,
466  .referenceSlotCount = vp->decode_info.referenceSlotCount,
467  .pReferenceSlots = vp->decode_info.pReferenceSlots,
468  };
469  VkVideoEndCodingInfoKHR decode_end = {
470  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
471  };
472 
473  VkImageMemoryBarrier2 img_bar[37];
474  int nb_img_bar = 0;
475  size_t data_size = FFALIGN(vp->slices_size,
476  ctx->caps.minBitstreamBufferSizeAlignment);
477 
478  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
479 
480  /* The current decoding reference has to be bound as an inactive reference */
481  VkVideoReferenceSlotInfoKHR *cur_vk_ref;
482  cur_vk_ref = (void *)&decode_start.pReferenceSlots[decode_start.referenceSlotCount];
483  cur_vk_ref[0] = vp->ref_slot;
484  cur_vk_ref[0].slotIndex = -1;
485  decode_start.referenceSlotCount++;
486 
487  sd_buf = vp->slices_buf;
488 
489  /* Flush if needed */
490  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
491  VkMappedMemoryRange flush_buf = {
492  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
493  .memory = sd_buf->mem,
494  .offset = 0,
495  .size = FFALIGN(vp->slices_size,
496  ctx->s.props.properties.limits.nonCoherentAtomSize),
497  };
498 
499  ret = vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &flush_buf);
500  if (ret != VK_SUCCESS) {
501  av_log(avctx, AV_LOG_ERROR, "Failed to flush memory: %s\n",
502  ff_vk_ret2str(ret));
503  return AVERROR_EXTERNAL;
504  }
505  }
506 
507  vp->decode_info.srcBuffer = sd_buf->buf;
508  vp->decode_info.srcBufferOffset = 0;
509  vp->decode_info.srcBufferRange = data_size;
510 
511  /* Start command buffer recording */
512  err = ff_vk_exec_start(&ctx->s, exec);
513  if (err < 0)
514  return err;
515  cmd_buf = exec->buf;
516 
517  /* Slices; owned by the execution from now on */
518  ff_vk_exec_move_dep_refstruct(&ctx->s, exec, &vp->slices_buf);
519 
520  /* Parameters; unset when inline session parameters are used */
521  if (dec->session_params)
522  ff_vk_exec_add_dep_refstruct(&ctx->s, exec, dec->session_params);
523 
524  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, pic,
525  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
526  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
527  if (err < 0)
528  return err;
529 
530  /* The output view is kept alive by the execution context; freeing the
531  * picture then needs no host wait. */
532  ff_vk_exec_add_dep_refstruct(&ctx->s, exec, vp->out_views);
533 
534  /* Output image - change layout, as it comes from a pool */
535  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
536  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
537  .pNext = NULL,
538  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
539  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
540  .srcAccessMask = VK_ACCESS_2_NONE,
541  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
542  .oldLayout = vkf->layout[0],
543  .newLayout = (layered_dpb || vp->dpb_frame) ?
544  VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
545  VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, /* Spec, 07252 utter madness */
546  .srcQueueFamilyIndex = vkf->queue_family[0],
547  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
548  .image = vkf->img[0],
549  .subresourceRange = (VkImageSubresourceRange) {
550  .aspectMask = vp->view.aspect,
551  .layerCount = 1,
552  .levelCount = 1,
553  },
554  };
555  ff_vk_exec_update_frame(&ctx->s, exec, pic,
556  &img_bar[nb_img_bar], &nb_img_bar);
557 
558  /* Reference for the current image, if existing and not layered */
559  if (vp->dpb_frame) {
560  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
561  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
562  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
563  if (err < 0)
564  return err;
565  }
566 
567  if (!layered_dpb) {
568  /* All references (apart from the current) for non-layered refs */
569 
570  for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
571  AVFrame *ref_frame = rpic[i];
572  FFVulkanDecodePicture *rvp = rvkp[i];
573  AVFrame *ref = rvp->dpb_frame ? rvp->dpb_frame : ref_frame;
574 
575  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref,
576  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
577  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
578  if (err < 0)
579  return err;
580 
581  /* The reference's image views are kept alive by the execution,
582  * so freeing the picture needs no host wait. */
583  if (err == 0 && rvp->out_views)
584  ff_vk_exec_add_dep_refstruct(&ctx->s, exec, rvp->out_views);
585 
586  if (!rvp->dpb_frame) {
587  AVVkFrame *rvkf = (AVVkFrame *)ref->data[0];
588 
589  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
590  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
591  .pNext = NULL,
592  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
593  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
594  .srcAccessMask = VK_ACCESS_2_NONE,
595  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR |
596  VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
597  .oldLayout = rvkf->layout[0],
598  .newLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
599  .srcQueueFamilyIndex = rvkf->queue_family[0],
600  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
601  .image = rvkf->img[0],
602  .subresourceRange = (VkImageSubresourceRange) {
603  .aspectMask = rvp->view.aspect_ref,
604  .layerCount = 1,
605  .levelCount = 1,
606  },
607  };
608  ff_vk_exec_update_frame(&ctx->s, exec, ref,
609  &img_bar[nb_img_bar], &nb_img_bar);
610  }
611  }
612  } else if (vp->decode_info.referenceSlotCount ||
613  vp->view.out != vp->view.ref) {
614  /* Single barrier for a single layered ref */
615  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
616  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
617  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
618  if (err < 0)
619  return err;
620  }
621 
622  /* Change image layout */
623  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
624  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
625  .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
626  .pImageMemoryBarriers = img_bar,
627  .imageMemoryBarrierCount = nb_img_bar,
628  });
629 
630  /* Start, use parameters, decode and end decoding */
631  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
632  vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
633  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
634 
635  /* End recording and submit for execution */
636  return ff_vk_exec_submit(&ctx->s, exec);
637 }
638 
640 {
641  /* Free slices data */
643 
644  /* The views are kept alive by every execution referencing them, so no
645  * host wait is needed. */
647 
648  av_frame_free(&vp->dpb_frame);
649 }
650 
651 static void free_common(AVRefStructOpaque unused, void *obj)
652 {
653  FFVulkanDecodeShared *ctx = obj;
654  FFVulkanContext *s = &ctx->s;
655 
656  /* Wait on and free execution pool */
657  ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
658 
659  /* This also frees all references from this pool */
660  av_frame_free(&ctx->common.layered_frame);
661 
662  av_refstruct_pool_uninit(&ctx->buf_pool);
663 
664  ff_vk_video_common_uninit(s, &ctx->common);
665 
666  if (ctx->sd_ctx_free)
667  ctx->sd_ctx_free(ctx);
668 
669  ff_vk_uninit(s);
670 }
671 
672 static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
673 {
674  int err;
676  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
678  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
679  AVVulkanDeviceContext *hwctx = device->hwctx;
681 
682  if (dec->shared_ctx)
683  return 0;
684 
685  dec->shared_ctx = av_refstruct_alloc_ext(sizeof(*ctx), 0, NULL,
686  free_common);
687  if (!dec->shared_ctx)
688  return AVERROR(ENOMEM);
689 
690  ctx = dec->shared_ctx;
691 
692  ctx->s.extensions = ff_vk_extensions_to_mask(hwctx->enabled_dev_extensions,
694 
695  if (vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
696  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_DECODE_QUEUE)) {
697  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
698  VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
700  return AVERROR(ENOSYS);
701  }
702  }
703 
704  err = ff_vk_load_functions(device, &ctx->s.vkfn, ctx->s.extensions, 1, 1);
705  if (err < 0) {
707  return err;
708  }
709 
710  return 0;
711 }
712 
713 static VkResult vulkan_setup_profile(AVCodecContext *avctx,
715  AVVulkanDeviceContext *hwctx,
716  FFVulkanFunctions *vk,
717  const FFVulkanDecodeDescriptor *vk_desc,
718  VkVideoDecodeH264CapabilitiesKHR *h264_caps,
719  VkVideoDecodeH265CapabilitiesKHR *h265_caps,
720 #if CONFIG_VP9_VULKAN_HWACCEL
721  VkVideoDecodeVP9CapabilitiesKHR *vp9_caps,
722 #endif
723  VkVideoDecodeAV1CapabilitiesKHR *av1_caps,
724  VkVideoCapabilitiesKHR *caps,
725  VkVideoDecodeCapabilitiesKHR *dec_caps,
726  int cur_profile)
727 {
728  VkVideoDecodeUsageInfoKHR *usage = &prof->usage;
729  VkVideoProfileInfoKHR *profile = &prof->profile;
730  VkVideoProfileListInfoKHR *profile_list = &prof->profile_list;
731 
732  VkVideoDecodeH264ProfileInfoKHR *h264_profile = &prof->h264_profile;
733  VkVideoDecodeH265ProfileInfoKHR *h265_profile = &prof->h265_profile;
734 #if CONFIG_VP9_VULKAN_HWACCEL
735  VkVideoDecodeVP9ProfileInfoKHR *vp9_profile = &prof->vp9_profile;
736 #endif
737  VkVideoDecodeAV1ProfileInfoKHR *av1_profile = &prof->av1_profile;
738 
740  if (!desc)
741  return AVERROR(EINVAL);
742 
743  if (avctx->codec_id == AV_CODEC_ID_H264) {
744  dec_caps->pNext = h264_caps;
745  usage->pNext = h264_profile;
746  h264_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
747 
748  /* Vulkan transmits all the constrant_set flags, rather than wanting them
749  * merged in the profile IDC */
750  h264_profile->stdProfileIdc = cur_profile & ~(AV_PROFILE_H264_CONSTRAINED |
752 
753  h264_profile->pictureLayout = avctx->field_order == AV_FIELD_UNKNOWN ||
755  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
756  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
757  } else if (avctx->codec_id == AV_CODEC_ID_H265) {
758  dec_caps->pNext = h265_caps;
759  usage->pNext = h265_profile;
760  h265_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
761  h265_profile->stdProfileIdc = cur_profile;
762 #if CONFIG_VP9_VULKAN_HWACCEL
763  } else if (avctx->codec_id == AV_CODEC_ID_VP9) {
764  dec_caps->pNext = vp9_caps;
765  usage->pNext = vp9_profile;
766  vp9_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR;
767  vp9_profile->stdProfile = cur_profile;
768 #endif
769  } else if (avctx->codec_id == AV_CODEC_ID_AV1) {
770  dec_caps->pNext = av1_caps;
771  usage->pNext = av1_profile;
772  av1_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
773  av1_profile->stdProfile = cur_profile;
774  av1_profile->filmGrainSupport = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
775  }
776 
777  usage->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR;
778  usage->videoUsageHints = VK_VIDEO_DECODE_USAGE_DEFAULT_KHR;
779 
780  profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
781  profile->pNext = usage;
782  profile->videoCodecOperation = vk_desc->decode_op;
783  profile->chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
784  profile->lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
785  profile->chromaBitDepth = profile->lumaBitDepth;
786 
787  profile_list->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
788  profile_list->profileCount = 1;
789  profile_list->pProfiles = profile;
790 
791  /* Get the capabilities of the decoder for the given profile */
792  caps->sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
793  caps->pNext = dec_caps;
794  dec_caps->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR;
795  /* dec_caps->pNext already filled in */
796 
797  return vk->GetPhysicalDeviceVideoCapabilitiesKHR(hwctx->phys_dev, profile,
798  caps);
799 }
800 
801 static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref,
802  enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt,
804  int *dpb_dedicate)
805 {
806  VkResult ret;
807  int max_level, base_profile, cur_profile;
808  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
810  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
811  AVVulkanDeviceContext *hwctx = device->hwctx;
812  enum AVPixelFormat source_format;
813  enum AVPixelFormat best_format;
814  VkFormat best_vkfmt;
815 
818  FFVulkanFunctions *vk = &ctx->s.vkfn;
819 
820  VkVideoCapabilitiesKHR *caps = &ctx->caps;
821  VkVideoDecodeCapabilitiesKHR *dec_caps = &ctx->dec_caps;
822 
823  VkVideoDecodeH264CapabilitiesKHR h264_caps = {
824  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR,
825  };
826  VkVideoDecodeH265CapabilitiesKHR h265_caps = {
827  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR,
828  };
829 #if CONFIG_VP9_VULKAN_HWACCEL
830  VkVideoDecodeVP9CapabilitiesKHR vp9_caps = {
831  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_CAPABILITIES_KHR,
832  };
833 #endif
834  VkVideoDecodeAV1CapabilitiesKHR av1_caps = {
835  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR,
836  };
837 
838  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
839  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
840  .pNext = &prof->profile_list,
841  };
842  VkVideoFormatPropertiesKHR *ret_info;
843  uint32_t nb_out_fmts = 0;
844 
845  if (!(vk_desc->decode_extension & ctx->s.extensions)) {
846  av_log(avctx, AV_LOG_ERROR, "Device does not support decoding %s!\n",
847  avcodec_get_name(avctx->codec_id));
848  return AVERROR(ENOSYS);
849  }
850 
851  cur_profile = avctx->profile;
854 #if CONFIG_VP9_VULKAN_HWACCEL
855  avctx->codec_id == AV_CODEC_ID_VP9 ? STD_VIDEO_VP9_PROFILE_0 :
856 #endif
857  avctx->codec_id == AV_CODEC_ID_AV1 ? STD_VIDEO_AV1_PROFILE_MAIN :
858  0;
859 
860  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
861  &h264_caps,
862  &h265_caps,
863 #if CONFIG_VP9_VULKAN_HWACCEL
864  &vp9_caps,
865 #endif
866  &av1_caps,
867  caps,
868  dec_caps,
869  cur_profile);
870  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR &&
872  avctx->profile != base_profile) {
873  av_log(avctx, AV_LOG_VERBOSE, "%s profile %s not supported, attempting "
874  "again with profile %s\n",
875  avcodec_get_name(avctx->codec_id),
876  avcodec_profile_name(avctx->codec_id, cur_profile),
877  avcodec_profile_name(avctx->codec_id, base_profile));
878  cur_profile = base_profile;
879  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
880  &h264_caps,
881  &h265_caps,
882 #if CONFIG_VP9_VULKAN_HWACCEL
883  &vp9_caps,
884 #endif
885  &av1_caps,
886  caps,
887  dec_caps,
888  cur_profile);
889  }
890 
891  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
892  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
893  "%s profile \"%s\" not supported!\n",
894  avcodec_get_name(avctx->codec_id),
895  avcodec_profile_name(avctx->codec_id, cur_profile));
896  return AVERROR(EINVAL);
897  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
898  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
899  "format (%s) not supported!\n",
901  return AVERROR(EINVAL);
902  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
903  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
904  return AVERROR(EINVAL);
905  } else if (ret != VK_SUCCESS) {
906  return AVERROR_EXTERNAL;
907  }
908 
909  max_level = avctx->codec_id == AV_CODEC_ID_H264 ? ff_vk_h264_level_to_av(h264_caps.maxLevelIdc) :
910  avctx->codec_id == AV_CODEC_ID_H265 ? ff_vk_h265_level_to_av(h265_caps.maxLevelIdc) :
911 #if CONFIG_VP9_VULKAN_HWACCEL
912  avctx->codec_id == AV_CODEC_ID_VP9 ? vp9_caps.maxLevel :
913 #endif
914  avctx->codec_id == AV_CODEC_ID_AV1 ? av1_caps.maxLevel :
915  0;
916 
917  av_log(avctx, AV_LOG_VERBOSE, "Decoder capabilities for %s profile \"%s\":\n",
918  avcodec_get_name(avctx->codec_id),
919  avcodec_profile_name(avctx->codec_id, cur_profile));
920  av_log(avctx, AV_LOG_VERBOSE, " Maximum level: %i (stream %i)\n",
921  max_level, avctx->level);
922  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
923  caps->minCodedExtent.width, caps->maxCodedExtent.width);
924  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
925  caps->minCodedExtent.height, caps->maxCodedExtent.height);
926  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
927  caps->pictureAccessGranularity.width);
928  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
929  caps->pictureAccessGranularity.height);
930  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
931  caps->minBitstreamBufferOffsetAlignment);
932  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
933  caps->minBitstreamBufferSizeAlignment);
934  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
935  caps->maxDpbSlots);
936  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
937  caps->maxActiveReferencePictures);
938  av_log(avctx, AV_LOG_VERBOSE, " Codec header name: '%s' (driver), '%s' (compiled)\n",
939  caps->stdHeaderVersion.extensionName,
940  vk_desc->ext_props.extensionName);
941  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
942  CODEC_VER(caps->stdHeaderVersion.specVersion),
943  CODEC_VER(vk_desc->ext_props.specVersion));
944  av_log(avctx, AV_LOG_VERBOSE, " Decode modes:%s%s%s\n",
945  dec_caps->flags ? "" :
946  " invalid",
947  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR ?
948  " reuse_dst_dpb" : "",
949  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR ?
950  " dedicated_dpb" : "");
951  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
952  caps->flags ? "" :
953  " none",
954  caps->flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
955  " protected" : "",
956  caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
957  " separate_references" : "");
958 
959  /* Check if decoding is possible with the given parameters */
960  if (avctx->coded_width < caps->minCodedExtent.width ||
961  avctx->coded_height < caps->minCodedExtent.height ||
962  avctx->coded_width > caps->maxCodedExtent.width ||
963  avctx->coded_height > caps->maxCodedExtent.height)
964  return AVERROR(EINVAL);
965 
967  avctx->level > max_level)
968  return AVERROR(EINVAL);
969 
970  /* Some basic sanity checking */
971  if (!(dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
972  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR))) {
973  av_log(avctx, AV_LOG_ERROR, "Buggy driver signals invalid decoding mode: neither "
974  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR nor "
975  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR are set!\n");
976  return AVERROR_EXTERNAL;
977  } else if ((dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
978  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ==
979  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) &&
980  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR)) {
981  av_log(avctx, AV_LOG_ERROR, "Cannot initialize Vulkan decoding session, buggy driver: "
982  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set "
983  "but VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!\n");
984  return AVERROR_EXTERNAL;
985  }
986 
987  dec->dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
988  ctx->common.layered_dpb = !dec->dedicated_dpb ? 0 :
989  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
990 
991  if (dec->dedicated_dpb) {
992  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
993  } else {
994  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
995  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
996  VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
997  VK_IMAGE_USAGE_SAMPLED_BIT;
998 
999  if ((ctx->s.extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE) &&
1000  (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1))
1001  fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1002  }
1003 
1004  /* Get the format of the images necessary */
1005  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1006  &fmt_info,
1007  &nb_out_fmts, NULL);
1008  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1009  (!nb_out_fmts && ret == VK_SUCCESS)) {
1010  return AVERROR(EINVAL);
1011  } else if (ret != VK_SUCCESS) {
1012  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1013  ff_vk_ret2str(ret));
1014  return AVERROR_EXTERNAL;
1015  }
1016 
1017  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
1018  if (!ret_info)
1019  return AVERROR(ENOMEM);
1020 
1021  for (int i = 0; i < nb_out_fmts; i++)
1022  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1023 
1024  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1025  &fmt_info,
1026  &nb_out_fmts, ret_info);
1027  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1028  (!nb_out_fmts && ret == VK_SUCCESS)) {
1029  av_free(ret_info);
1030  return AVERROR(EINVAL);
1031  } else if (ret != VK_SUCCESS) {
1032  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1033  ff_vk_ret2str(ret));
1034  av_free(ret_info);
1035  return AVERROR_EXTERNAL;
1036  }
1037 
1038  /* Find a format to use */
1039  *pix_fmt = best_format = AV_PIX_FMT_NONE;
1040  *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
1041  source_format = avctx->sw_pix_fmt;
1042 
1043  av_log(avctx, AV_LOG_DEBUG, "Choosing best pixel format for decoding from %i:\n", nb_out_fmts);
1044  for (int i = 0; i < nb_out_fmts; i++) {
1046  if (tmp == AV_PIX_FMT_NONE) {
1047  av_log(avctx, AV_LOG_WARNING, "Invalid/unknown Vulkan format %i!\n", ret_info[i].format);
1048  continue;
1049  }
1050 
1051  best_format = av_find_best_pix_fmt_of_2(tmp, best_format, source_format, 0, NULL);
1052  if (tmp == best_format)
1053  best_vkfmt = ret_info[i].format;
1054 
1055  av_log(avctx, AV_LOG_DEBUG, " %s%s (Vulkan ID: %i)\n",
1056  av_get_pix_fmt_name(tmp), tmp == best_format ? "*" : "",
1057  ret_info[i].format);
1058  }
1059 
1060  av_free(ret_info);
1061 
1062  if (best_format == AV_PIX_FMT_NONE) {
1063  av_log(avctx, AV_LOG_ERROR, "No valid/compatible pixel format found for decoding!\n");
1064  return AVERROR(EINVAL);
1065  } else {
1066  av_log(avctx, AV_LOG_VERBOSE, "Chosen frame pixfmt: %s (Vulkan ID: %i)\n",
1067  av_get_pix_fmt_name(best_format), best_vkfmt);
1068  }
1069 
1070  *pix_fmt = best_format;
1071  *vk_fmt = best_vkfmt;
1072 
1073  *dpb_dedicate = dec->dedicated_dpb;
1074 
1075  return 0;
1076 }
1077 
1079 {
1080  av_free(hwfc->user_opaque);
1081 }
1082 
1083 int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
1084 {
1085  int err, dedicated_dpb;
1086  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
1087  AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
1090 
1091  err = vulkan_decode_bootstrap(avctx, hw_frames_ctx);
1092  if (err < 0)
1093  return err;
1094 
1095  frames_ctx->format = AV_PIX_FMT_VULKAN;
1096  frames_ctx->sw_format = avctx->sw_pix_fmt;
1097  frames_ctx->width = avctx->coded_width;
1098  frames_ctx->height = avctx->coded_height;
1099 
1100  if (!DECODER_IS_SDR(avctx->codec_id)) {
1101  prof = av_mallocz(sizeof(FFVulkanDecodeProfileData));
1102  if (!prof)
1103  return AVERROR(ENOMEM);
1104 
1105  err = vulkan_decode_get_profile(avctx, hw_frames_ctx,
1106  &frames_ctx->sw_format,
1107  &hwfc->format[0],
1108  prof, &dedicated_dpb);
1109  if (err < 0) {
1110  av_free(prof);
1111  return err;
1112  }
1113 
1114  const AVPixFmtDescriptor *pdesc = av_pix_fmt_desc_get(frames_ctx->sw_format);
1115  frames_ctx->width = FFALIGN(frames_ctx->width, 1 << pdesc->log2_chroma_w);
1116  frames_ctx->height = FFALIGN(frames_ctx->height, 1 << pdesc->log2_chroma_h);
1117  frames_ctx->user_opaque = prof;
1118  frames_ctx->free = free_profile_data;
1119 
1120  hwfc->create_pnext = &prof->profile_list;
1121  } else {
1122  hwfc->format[0] = VK_FORMAT_UNDEFINED;
1123  switch (frames_ctx->sw_format) {
1124  case AV_PIX_FMT_GBRAP16:
1125  /* This should be more efficient for downloading and using */
1126  frames_ctx->sw_format = AV_PIX_FMT_RGBA64;
1127  break;
1128  case AV_PIX_FMT_GBRP10:
1129  /* This saves memory bandwidth when downloading */
1130  frames_ctx->sw_format = AV_PIX_FMT_X2BGR10;
1131  break;
1132  case AV_PIX_FMT_RGB24:
1133  case AV_PIX_FMT_BGR0:
1134  /* mpv has issues with bgr0 mapping, so just remap it */
1135  frames_ctx->sw_format = AV_PIX_FMT_RGB0;
1136  break;
1137  /* DPX endian mismatch remappings */
1138  case AV_PIX_FMT_RGB48LE:
1139  case AV_PIX_FMT_RGB48BE: frames_ctx->sw_format = AV_PIX_FMT_GBRP16; break;
1140  case AV_PIX_FMT_RGBA64BE: frames_ctx->sw_format = AV_PIX_FMT_RGBA64; break;
1141  case AV_PIX_FMT_GRAY16BE: frames_ctx->sw_format = AV_PIX_FMT_GRAY16; break;
1142  /* ProRes needs to clear the input image, which is not possible on YUV formats */
1143  case AV_PIX_FMT_YUVA422P10:
1144  case AV_PIX_FMT_YUVA444P10:
1145  case AV_PIX_FMT_YUVA422P12:
1146  case AV_PIX_FMT_YUVA444P12:
1147  hwfc->format[3] = VK_FORMAT_R16_UNORM;
1149  case AV_PIX_FMT_YUV422P10:
1150  case AV_PIX_FMT_YUV444P10:
1151  case AV_PIX_FMT_YUV422P12:
1152  case AV_PIX_FMT_YUV444P12:
1153  hwfc->format[0] = VK_FORMAT_R16_UNORM;
1154  hwfc->format[1] = VK_FORMAT_R16_UNORM;
1155  hwfc->format[2] = VK_FORMAT_R16_UNORM;
1156  break;
1157  default:
1158  break;
1159  }
1160  }
1161 
1162  if (hwfc->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1163  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1164 
1165  hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1166  VK_IMAGE_USAGE_STORAGE_BIT |
1167  VK_IMAGE_USAGE_SAMPLED_BIT;
1168 
1169  if (prof) {
1171 
1172  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1173  if (!dec->dedicated_dpb)
1174  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1175 
1176  ctx = dec->shared_ctx;
1177  if ((ctx->s.extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE) &&
1178  (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1))
1179  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1180  }
1181 
1182  return err;
1183 }
1184 
1185 static void vk_decode_free_params(AVRefStructOpaque opaque, void *obj)
1186 {
1187  FFVulkanDecodeShared *ctx = opaque.nc;
1188  FFVulkanFunctions *vk = &ctx->s.vkfn;
1189  VkVideoSessionParametersKHR *par = obj;
1190  vk->DestroyVideoSessionParametersKHR(ctx->s.hwctx->act_dev, *par,
1191  ctx->s.hwctx->alloc);
1192 }
1193 
1194 int ff_vk_decode_create_params(VkVideoSessionParametersKHR **par_ref, void *logctx, FFVulkanDecodeShared *ctx,
1195  const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1196 {
1197  VkVideoSessionParametersKHR *par;
1198  const FFVulkanFunctions *vk = &ctx->s.vkfn;
1199  VkResult ret;
1200 
1201  par = av_refstruct_alloc_ext(sizeof(*par), 0, ctx, vk_decode_free_params);
1202  if (!par)
1203  return AVERROR(ENOMEM);
1204 
1205  /* Create session parameters */
1206  ret = vk->CreateVideoSessionParametersKHR(ctx->s.hwctx->act_dev, session_params_create,
1207  ctx->s.hwctx->alloc, par);
1208  if (ret != VK_SUCCESS) {
1209  av_log(logctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1210  ff_vk_ret2str(ret));
1211  *par = VK_NULL_HANDLE;
1212  av_refstruct_unref(&par);
1213  return AVERROR_EXTERNAL;
1214  }
1215  *par_ref = par;
1216 
1217  return 0;
1218 }
1219 
1221 {
1223 
1224  av_freep(&dec->hevc_headers);
1227  av_freep(&dec->slice_off);
1228  return 0;
1229 }
1230 
1232 {
1233  int err;
1236  FFVulkanContext *s;
1237  int async_depth;
1238  const VkVideoProfileInfoKHR *profile;
1239  const FFVulkanDecodeDescriptor *vk_desc;
1240 
1241  VkVideoSessionCreateInfoKHR session_create = {
1242  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1243  };
1244 
1246  if (err < 0)
1247  return err;
1248 
1249  /* Initialize contexts */
1250  ctx = dec->shared_ctx;
1251  s = &ctx->s;
1252 
1253  err = ff_vk_init(s, avctx, NULL, avctx->hw_frames_ctx);
1254  if (err < 0)
1255  return err;
1256 
1257  vk_desc = get_codecdesc(avctx->codec_id);
1258 
1260  if ((vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) && !profile) {
1261  av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
1262  return AVERROR(EINVAL);
1263  }
1264 
1265  /* Create queue context */
1266  vk_desc = get_codecdesc(avctx->codec_id);
1267  ctx->qf = ff_vk_qf_find(s, vk_desc->queue_flags, vk_desc->decode_op);
1268  if (!ctx->qf) {
1269  av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
1270  avcodec_get_name(avctx->codec_id));
1271  return err;
1272  }
1273 
1274  session_create.queueFamilyIndex = ctx->qf->idx;
1275  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1276  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1277  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1278  session_create.pictureFormat = s->hwfc->format[0];
1279  session_create.referencePictureFormat = session_create.pictureFormat;
1280  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1281  session_create.pVideoProfile = profile;
1282 #ifdef VK_KHR_video_maintenance2
1283  if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)
1284  session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1285 #endif
1286 
1287  /* Create the decode exec context.
1288  * A small fixed depth is enough to keep the GPU fed, as submissions are
1289  * serialized for hardware decoding; thread-safe hwaccels submit from
1290  * every frame thread concurrently, and need a context per thread. */
1291  async_depth = FF_VK_DEFAULT_EXEC_CONTEXTS;
1293  async_depth = FFMAX(async_depth, avctx->thread_count);
1294 
1295  err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
1296  async_depth, 0, 0, 0, profile);
1297  if (err < 0)
1298  goto fail;
1299 
1300  if (!DECODER_IS_SDR(avctx->codec_id)) {
1301  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1302  if (err < 0)
1303  goto fail;
1304  }
1305 
1306  /* If doing an out-of-place decoding, create a DPB pool */
1307  if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) {
1309  AVVulkanFramesContext *dpb_hwfc;
1310 
1311  ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref);
1312  if (!ctx->common.dpb_hwfc_ref) {
1313  err = AVERROR(ENOMEM);
1314  goto fail;
1315  }
1316 
1317  dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
1318  dpb_frames->format = s->frames->format;
1319  dpb_frames->sw_format = s->frames->sw_format;
1320  dpb_frames->width = s->frames->width;
1321  dpb_frames->height = s->frames->height;
1322 
1323  dpb_hwfc = dpb_frames->hwctx;
1324  void *profile_list = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1325  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1326  /* Reference (DPB) images use the same tiling and pNext chain as output.
1327  * If VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR is 0, the
1328  * driver does not support separate output and DPB with different layouts/tiling. */
1329  void *drm_create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1330  VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
1331  if (drm_create_pnext) {
1332  dpb_hwfc->create_pnext = drm_create_pnext;
1333  dpb_hwfc->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
1334  av_assert2(ff_vk_find_struct(drm_create_pnext, VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
1335  } else {
1336  dpb_hwfc->create_pnext = profile_list;
1337  dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1338  }
1339  dpb_hwfc->format[0] = s->hwfc->format[0];
1340  dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1341 
1342  if (ctx->common.layered_dpb)
1343  dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
1344 
1345  err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref);
1346  if (err < 0)
1347  goto fail;
1348 
1349  if (ctx->common.layered_dpb) {
1350  ctx->common.layered_frame = vk_get_dpb_pool(ctx);
1351  if (!ctx->common.layered_frame) {
1352  err = AVERROR(ENOMEM);
1353  goto fail;
1354  }
1355 
1356  err = ff_vk_create_view(&ctx->s, &ctx->common,
1357  &ctx->common.layered_view,
1358  &ctx->common.layered_aspect,
1359  (AVVkFrame *)ctx->common.layered_frame->data[0],
1360  s->hwfc->format[0], VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR);
1361  if (err < 0)
1362  goto fail;
1363  }
1364  }
1365 
1366  if (!DECODER_IS_SDR(avctx->codec_id)) {
1367  err = decode_reset(avctx, ctx);
1368  if (err < 0)
1369  return err;
1370  } else {
1371  /* For SDR decoders, this alignment value will be 0. Since this will make
1372  * add_slice() malfunction, set it to a sane default value. */
1373  ctx->caps.minBitstreamBufferSizeAlignment = AV_INPUT_BUFFER_PADDING_SIZE;
1374  }
1375 
1376  const VkPhysicalDeviceDriverProperties *driver_props;
1377  driver_props = &dec->shared_ctx->s.driver_props;
1378  if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1379  driver_props->conformanceVersion.major == 1 &&
1380  driver_props->conformanceVersion.minor == 3 &&
1381  driver_props->conformanceVersion.subminor == 8 &&
1382  driver_props->conformanceVersion.patch < 3)
1383  dec->quirk_av1_offset = 1;
1384 
1385  av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization successful\n");
1386 
1387  return 0;
1388 
1389 fail:
1390  ff_vk_decode_uninit(avctx);
1391 
1392  return err;
1393 }
vulkan_loader.h
ff_vk_dec_apv_desc
const FFVulkanDecodeDescriptor ff_vk_dec_apv_desc
Definition: vulkan_apv.c:33
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1423
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:571
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:102
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:95
ff_vk_exec_add_dep_refstruct
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition: vulkan.c:687
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3460
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FFVulkanDecodeContext::shared_ctx
FFVulkanDecodeShared * shared_ctx
Definition: vulkan_decode.h:55
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:357
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:62
AVRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
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:105
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:837
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
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:472
AV_PIX_FMT_RGBA64BE
@ AV_PIX_FMT_RGBA64BE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:202
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:694
AVVulkanFramesContext::create_pnext
void * create_pnext
Extension data for image creation.
Definition: hwcontext_vulkan.h:202
ff_vk_find_struct
static const void * ff_vk_find_struct(const void *chain, VkStructureType stype)
Definition: vulkan.h:355
b
#define b
Definition: input.c:43
data
const char data[16]
Definition: mxf.c:149
create_empty_session_parameters
static int create_empty_session_parameters(AVCodecContext *avctx, FFVulkanDecodeShared *ctx, VkVideoSessionParametersKHR *empty_session_params)
Definition: vulkan_decode.c:349
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:2651
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:571
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2638
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:446
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:99
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:649
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:597
FFVulkanDecodeContext
Definition: vulkan_decode.h:54
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
FFVulkanDecodeContext::session_params
VkVideoSessionParametersKHR * session_params
Definition: vulkan_decode.h:56
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:777
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:191
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:1998
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:493
AV_HWDEVICE_TYPE_VULKAN
@ AV_HWDEVICE_TYPE_VULKAN
Definition: hwcontext.h:39
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_GRAY16BE
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
Definition: pixfmt.h:104
AVVkFrame::img
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Definition: hwcontext_vulkan.h:266
FFVulkanDecodeDescriptor::decode_op
VkVideoCodecOperationFlagBitsKHR decode_op
Definition: vulkan_decode.h:33
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1579
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:564
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:171
HWACCEL_CAP_THREAD_SAFE
#define HWACCEL_CAP_THREAD_SAFE
Definition: hwaccel_internal.h:32
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
ff_vk_ret2str
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
Definition: vulkan.c:41
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:528
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:442
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:801
init_frame
static void init_frame(FFVulkanDecodeContext *dec, FFVulkanDecodePicture *vkpic)
Definition: vulkan_decode.c:178
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:52
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:548
FFVulkanDecodeContext::slice_off
uint32_t * slice_off
Definition: vulkan_decode.h:69
avassert.h
FFVulkanDecodePicture::slices_buf
FFVkBuffer * slices_buf
Definition: vulkan_decode.h:101
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:94
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:103
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:495
FFVulkanDecodePicture
Definition: vulkan_decode.h:73
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
offsets
static const int offsets[]
Definition: hevc_pel.c:34
FFVulkanContext::driver_props
VkPhysicalDeviceDriverProperties driver_props
Definition: vulkan.h:298
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:134
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:217
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:590
FFVkImageViews::views
VkImageView views[AV_NUM_DATA_POINTERS]
Definition: vulkan.h:546
ff_vk_dec_dpx_desc
const FFVulkanDecodeDescriptor ff_vk_dec_dpx_desc
Definition: vulkan_dpx.c:34
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_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:600
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
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:310
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
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:1069
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:453
ff_vk_exec_move_dep_refstruct
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition: vulkan.c:694
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:115
ff_vk_get_pooled_buffer
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition: vulkan.c:1256
fail
#define fail
Definition: test.h:479
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:59
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:567
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:535
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_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:275
AVVulkanDeviceContext::nb_enabled_dev_extensions
int nb_enabled_dev_extensions
Definition: hwcontext_vulkan.h:117
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:639
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:337
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:70
AV_PIX_FMT_RGB48LE
@ AV_PIX_FMT_RGB48LE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:110
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:478
FFVulkanDecodeProfileData::usage
VkVideoDecodeUsageInfoKHR usage
Definition: vulkan_decode.c:101
FFVulkanDecodeDescriptor::decode_extension
FFVulkanExtensions decode_extension
Definition: vulkan_decode.h:31
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
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:2018
FFVulkanDecodePicture::out_views
FFVkImageViews * out_views
Definition: vulkan_decode.h:98
ff_vk_decode_uninit
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
Definition: vulkan_decode.c:1220
AVVulkanFramesContext::format
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
Definition: hwcontext_vulkan.h:232
FFVkBuffer::size
size_t size
Definition: vulkan.h:98
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:191
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
attributes.h
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:546
FFVulkanDecodePicture::out
VkImageView out
Definition: vulkan_decode.h:78
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:103
FFVulkanContext
Definition: vulkan.h:290
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:1083
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1646
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
usage
const char * usage
Definition: floatimg_cmp.c:62
AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_X2BGR10
Definition: pixfmt.h:620
free_common
static void free_common(AVRefStructOpaque unused, void *obj)
Definition: vulkan_decode.c:651
FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
Definition: vulkan_functions.h:61
ff_vk_h265_level_to_av
int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
Definition: vulkan_video.c:191
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
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:261
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
FFVulkanDecodePicture::aspect
VkImageAspectFlags aspect
Definition: vulkan_decode.h:79
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:550
size
int size
Definition: twinvq_data.h:10344
ref_frame
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
Definition: dec.c:616
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:552
FFVulkanDecodePicture::aspect_ref
VkImageAspectFlags aspect_ref
Definition: vulkan_decode.h:80
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:70
AVVkFrame::queue_family
uint32_t queue_family[AV_NUM_DATA_POINTERS]
Queue family of the images.
Definition: hwcontext_vulkan.h:320
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:598
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
FFVkExecContext
Definition: vulkan.h:128
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
ff_vk_imageviews_alloc
FFVkImageViews * ff_vk_imageviews_alloc(FFVulkanContext *s, int nb_views)
Allocate a reference-counted set of image views, zero-initialized for the caller to create.
Definition: vulkan.c:1789
FFVulkanDecodeProfileData
Definition: vulkan_decode.c:93
FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
Definition: vulkan_functions.h:64
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:421
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
FF_VK_DEFAULT_EXEC_CONTEXTS
#define FF_VK_DEFAULT_EXEC_CONTEXTS
Definition: vulkan.h:121
AV_PIX_FMT_RGB48BE
@ AV_PIX_FMT_RGB48BE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:109
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:599
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:1502
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
s
uint8_t s
Definition: llvidencdsp.c:39
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
DECODER_IS_SDR
#define DECODER_IS_SDR(codec_id)
Definition: vulkan_decode.c:28
FFVulkanDecodeContext::external_fg
int external_fg
Definition: vulkan_decode.h:59
profile
int profile
Definition: mxfenc.c:2299
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:1471
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
FFVulkanDecodePicture::ref
VkImageView ref
Definition: vulkan_decode.h:77
ret
ret
Definition: filter_design.txt:187
ff_vk_dec_prores_desc
const FFVulkanDecodeDescriptor ff_vk_dec_prores_desc
Definition: vulkan_prores.c:31
ff_vk_create_view
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common, VkImageView *view, VkImageAspectFlags *aspect, AVVkFrame *src, VkFormat vkf, VkImageUsageFlags usage)
Creates image views for video frames.
Definition: vulkan_video.c:291
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:258
AV_PROFILE_H264_CONSTRAINED
#define AV_PROFILE_H264_CONSTRAINED
Definition: defs.h:107
dec_descs
static const FFVulkanDecodeDescriptor * dec_descs[]
Definition: vulkan_decode.c:63
FFVulkanDecodeContext::hevc_headers
struct HEVCHeaderSet * hevc_headers
Definition: vulkan_decode.h:66
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:297
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:139
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
ff_vk_dec_prores_raw_desc
const FFVulkanDecodeDescriptor ff_vk_dec_prores_raw_desc
Definition: vulkan_prores_raw.c:33
get_codecdesc
static const FFVulkanDecodeDescriptor * get_codecdesc(enum AVCodecID codec_id)
Definition: vulkan_decode.c:106
AVCodecContext
main external API structure.
Definition: avcodec.h:443
FFVulkanDecodeContext::dedicated_dpb
int dedicated_dpb
Definition: vulkan_decode.h:58
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:3739
ff_vk_dec_ffv1_desc
const FFVulkanDecodeDescriptor ff_vk_dec_ffv1_desc
Definition: vulkan_ffv1.c:63
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
AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:599
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1636
ffhwaccel
static const FFHWAccel * ffhwaccel(const AVHWAccel *codec)
Definition: hwaccel_internal.h:168
FFVulkanDecodeDescriptor
Definition: vulkan_decode.h:29
AV_CODEC_ID_H265
#define AV_CODEC_ID_H265
Definition: codec_id.h:224
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:1779
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:157
ff_vk_decode_create_params
int ff_vk_decode_create_params(VkVideoSessionParametersKHR **par_ref, void *logctx, FFVulkanDecodeShared *ctx, const VkVideoSessionParametersCreateInfoKHR *session_params_create)
Create VkVideoSessionParametersKHR wrapped in an AVBufferRef.
Definition: vulkan_decode.c:1194
FFVulkanDecodePicture::dpb_frame
AVFrame * dpb_frame
Definition: vulkan_decode.h:74
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:142
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:180
vulkan_video.h
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
desc
const char * desc
Definition: libsvtav1.c:83
AVVulkanDeviceContext::enabled_dev_extensions
const char *const * enabled_dev_extensions
Enabled device extensions.
Definition: hwcontext_vulkan.h:116
AVVulkanFramesContext::nb_layers
int nb_layers
Number of layers each image will have.
Definition: hwcontext_vulkan.h:237
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:291
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
vulkan_decode.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_refstruct_pool_uninit
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
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:713
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFVkBuffer
Definition: vulkan.h:94
vk_get_dpb_pool
static AVFrame * vk_get_dpb_pool(FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:164
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:881
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:672
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:1231
FFVulkanDecodePicture::decode_info
VkVideoDecodeInfoKHR decode_info
Definition: vulkan_decode.h:95
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
vk_decode_free_params
static void vk_decode_free_params(AVRefStructOpaque opaque, void *obj)
Definition: vulkan_decode.c:1185
decode_reset
static int decode_reset(AVCodecContext *avctx, FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:390
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
FFHWAccel::caps_internal
int caps_internal
Internal hwaccel capabilities.
Definition: hwaccel_internal.h:119
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:63
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
src
#define src
Definition: vp8dsp.c:248
free_profile_data
static void free_profile_data(AVHWFramesContext *hwfc)
Definition: vulkan_decode.c:1078
AV_CODEC_EXPORT_DATA_FILM_GRAIN
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition: avcodec.h:404
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@354 view
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:3380