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