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  int err;
145  FFVulkanDecodeContext *src_ctx = src->internal->hwaccel_priv_data;
146  FFVulkanDecodeContext *dst_ctx = dst->internal->hwaccel_priv_data;
147 
148  av_refstruct_replace(&dst_ctx->shared_ctx, src_ctx->shared_ctx);
149 
150  err = av_buffer_replace(&dst_ctx->session_params, src_ctx->session_params);
151  if (err < 0)
152  return err;
153 
154  dst_ctx->dedicated_dpb = src_ctx->dedicated_dpb;
155  dst_ctx->external_fg = src_ctx->external_fg;
156 
157  return 0;
158 }
159 
160 int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
161 {
164  return 0;
165 }
166 
168 {
169  int err;
170  AVFrame *avf = av_frame_alloc();
171  if (!avf)
172  return NULL;
173 
174  err = av_hwframe_get_buffer(ctx->common.dpb_hwfc_ref, avf, 0x0);
175  if (err < 0)
176  av_frame_free(&avf);
177 
178  return avf;
179 }
180 
182 {
184  FFVulkanFunctions *vk = &ctx->s.vkfn;
185 
186  vkpic->dpb_frame = NULL;
187  for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) {
188  vkpic->view.ref[i] = VK_NULL_HANDLE;
189  vkpic->view.out[i] = VK_NULL_HANDLE;
190  vkpic->view.dst[i] = VK_NULL_HANDLE;
191  }
192 
193  vkpic->destroy_image_view = vk->DestroyImageView;
194  vkpic->wait_semaphores = vk->WaitSemaphores;
195  vkpic->invalidate_memory_ranges = vk->InvalidateMappedMemoryRanges;
196 }
197 
199  FFVulkanDecodePicture *vkpic, int is_current,
200  int alloc_dpb)
201 {
202  int err;
204 
205  vkpic->slices_size = 0;
206 
207  /* If the decoder made a blank frame to make up for a missing ref, or the
208  * frame is the current frame so it's missing one, create a re-representation */
209  if (vkpic->view.ref[0])
210  return 0;
211 
212  init_frame(dec, vkpic);
213 
214  if (ctx->common.layered_dpb && alloc_dpb) {
215  vkpic->view.ref[0] = ctx->common.layered_view;
216  vkpic->view.aspect_ref[0] = ctx->common.layered_aspect;
217  } else if (alloc_dpb) {
218  AVHWFramesContext *dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
219  AVVulkanFramesContext *dpb_hwfc = dpb_frames->hwctx;
220 
221  vkpic->dpb_frame = vk_get_dpb_pool(ctx);
222  if (!vkpic->dpb_frame)
223  return AVERROR(ENOMEM);
224 
225  err = ff_vk_create_view(&ctx->s, &ctx->common,
226  &vkpic->view.ref[0], &vkpic->view.aspect_ref[0],
227  (AVVkFrame *)vkpic->dpb_frame->data[0],
228  dpb_hwfc->format[0], VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR);
229  if (err < 0)
230  return err;
231 
232  vkpic->view.dst[0] = vkpic->view.ref[0];
233  }
234 
235  if (!alloc_dpb || is_current) {
237  AVVulkanFramesContext *hwfc = frames->hwctx;
238 
239  err = ff_vk_create_view(&ctx->s, &ctx->common,
240  &vkpic->view.out[0], &vkpic->view.aspect[0],
241  (AVVkFrame *)pic->data[0],
242  hwfc->format[0],
243  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
244  (hwfc->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR));
245  // the above fixes VUID-VkVideoBeginCodingInfoKHR-slotIndex-07245
246  if (err < 0)
247  return err;
248 
249  if (!alloc_dpb) {
250  vkpic->view.ref[0] = vkpic->view.out[0];
251  vkpic->view.aspect_ref[0] = vkpic->view.aspect[0];
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 ? (FFVkBuffer *)vp->slices_buf->data : NULL;
288  if (!vkbuf || vkbuf->size < new_size) {
289  int err;
290  AVBufferRef *new_ref;
291  FFVkBuffer *new_buf;
292 
293  /* No point in requesting anything smaller. */
294  size_t buf_size = FFMAX(new_size, 1024*1024);
295 
296  /* Align buffer to nearest power of two. Makes fragmentation management
297  * easier, and gives us ample headroom. */
298  buf_size = 2 << av_log2(buf_size);
299 
300  /* When the frames context uses DRM modifier tiling,
301  * hwctx->create_pnext contains VkImageDrmFormatModifierListCreateInfoEXT,
302  * which per spec does not extend VkBufferCreateInfo, so we need to find
303  * the VkVideoProfileListInfoKHR structure within it. */
304  void *buf_pnext = ctx->s.hwfc->create_pnext;
305  if (ctx->s.hwfc->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
306  buf_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
307  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
308 
309  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_ref,
310  DECODER_IS_SDR(avctx->codec_id) ?
311  (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
312  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) :
313  VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR,
314  buf_pnext, buf_size,
315  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
316  (DECODER_IS_SDR(avctx->codec_id) ?
317  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0));
318  if (err < 0)
319  return err;
320 
321  new_buf = (FFVkBuffer *)new_ref->data;
322 
323  /* Copy data from the old buffer */
324  if (vkbuf) {
325  memcpy(new_buf->mapped_mem, vkbuf->mapped_mem, vp->slices_size);
327  }
328 
329  vp->slices_buf = new_ref;
330  vkbuf = new_buf;
331  }
332  slices = vkbuf->mapped_mem;
333 
334  /* Startcode */
335  memcpy(slices + vp->slices_size, startcode_prefix, startcode_len);
336 
337  /* Slice data */
338  memcpy(slices + vp->slices_size + startcode_len, data, size);
339 
340  if (nb_slices)
341  *nb_slices = nb + 1;
342 
343  vp->slices_size += startcode_len + size;
344 
345  return 0;
346 }
347 
350  VkVideoSessionParametersKHR *empty_session_params)
351 {
352  if (avctx->codec_id == AV_CODEC_ID_VP9)
353  return 0;
354 
355  VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
356  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
357  };
358  VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
359  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
360  };
361  StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
362  VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
363  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
364  .pStdSequenceHeader = &av1_empty_seq,
365  };
366  VkVideoSessionParametersCreateInfoKHR session_params_create = {
367  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
368  .pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
369  avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
370  avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
371  NULL,
372  .videoSession = ctx->common.session,
373  };
374 
375  VkResult ret;
376  FFVulkanContext *s = &ctx->s;
377  FFVulkanFunctions *vk = &s->vkfn;
378  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
379  s->hwctx->alloc, empty_session_params);
380  if (ret != VK_SUCCESS) {
381  av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
382  ff_vk_ret2str(ret));
383  return AVERROR_EXTERNAL;
384  }
385 
386  return 0;
387 }
388 
390 {
391  int err;
392  FFVulkanContext *s = &ctx->s;
393  FFVulkanFunctions *vk = &s->vkfn;
394 
395  VkVideoBeginCodingInfoKHR decode_start = {
396  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
397  .videoSession = ctx->common.session,
398  };
399 
400  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
402  &decode_start.videoSessionParameters);
403  if (err < 0)
404  return err;
405  }
406 
407  VkVideoCodingControlInfoKHR decode_ctrl = {
408  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
409  .flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
410  };
411  VkVideoEndCodingInfoKHR decode_end = {
412  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
413  };
414 
415  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
416  ff_vk_exec_start(&ctx->s, exec);
417 
418  vk->CmdBeginVideoCodingKHR(exec->buf, &decode_start);
419  vk->CmdControlVideoCodingKHR(exec->buf, &decode_ctrl);
420  vk->CmdEndVideoCodingKHR(exec->buf, &decode_end);
421 
422  err = ff_vk_exec_submit(&ctx->s, exec);
423 
424  if (decode_start.videoSessionParameters) {
425  /* Wait to complete to delete the temporary session parameters */
426  if (err >= 0)
427  ff_vk_exec_wait(&ctx->s, exec);
428 
429  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
430  decode_start.videoSessionParameters,
431  s->hwctx->alloc);
432  }
433 
434  if (err < 0)
435  av_log(avctx, AV_LOG_ERROR, "Unable to reset decoder: %s",
436  ff_vk_ret2str(err));
437 
438  return err;
439 }
440 
442  AVFrame *pic, FFVulkanDecodePicture *vp,
443  AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
444 {
445  int err;
446  VkResult ret;
447  VkCommandBuffer cmd_buf;
448  FFVkBuffer *sd_buf;
449 
452  FFVulkanFunctions *vk = &ctx->s.vkfn;
453 
454  /* Output */
455  AVVkFrame *vkf = (AVVkFrame *)pic->buf[0]->data;
456 
457  /* Quirks */
458  const int layered_dpb = ctx->common.layered_dpb;
459 
460  VkVideoBeginCodingInfoKHR decode_start = {
461  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
462  .videoSession = ctx->common.session,
463  .videoSessionParameters = dec->session_params ?
464  *((VkVideoSessionParametersKHR *)dec->session_params->data) :
465  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 = (FFVkBuffer *)vp->slices_buf->data;
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 */
518  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0);
519  if (err < 0)
520  return err;
521  vp->slices_buf = NULL; /* Owned by the exec buffer from now on */
522 
523  /* Parameters */
524  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &dec->session_params, 1, 1);
525  if (err < 0)
526  return err;
527 
528  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, pic,
529  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
530  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
531  if (err < 0)
532  return err;
533 
534  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
535  pic);
536  if (err < 0)
537  return err;
538 
539  /* Output image - change layout, as it comes from a pool */
540  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
541  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
542  .pNext = NULL,
543  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
544  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
545  .srcAccessMask = VK_ACCESS_2_NONE,
546  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
547  .oldLayout = vkf->layout[0],
548  .newLayout = (layered_dpb || vp->dpb_frame) ?
549  VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
550  VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, /* Spec, 07252 utter madness */
551  .srcQueueFamilyIndex = vkf->queue_family[0],
552  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
553  .image = vkf->img[0],
554  .subresourceRange = (VkImageSubresourceRange) {
555  .aspectMask = vp->view.aspect[0],
556  .layerCount = 1,
557  .levelCount = 1,
558  },
559  };
560  ff_vk_exec_update_frame(&ctx->s, exec, pic,
561  &img_bar[nb_img_bar], &nb_img_bar);
562 
563  /* Reference for the current image, if existing and not layered */
564  if (vp->dpb_frame) {
565  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
566  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
567  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
568  if (err < 0)
569  return err;
570  }
571 
572  if (!layered_dpb) {
573  /* All references (apart from the current) for non-layered refs */
574 
575  for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
576  AVFrame *ref_frame = rpic[i];
577  FFVulkanDecodePicture *rvp = rvkp[i];
578  AVFrame *ref = rvp->dpb_frame ? rvp->dpb_frame : ref_frame;
579 
580  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref,
581  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
582  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
583  if (err < 0)
584  return err;
585 
586  if (err == 0) {
587  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec,
588  &rvp->sem, &rvp->sem_value,
589  ref);
590  if (err < 0)
591  return err;
592  }
593 
594  if (!rvp->dpb_frame) {
595  AVVkFrame *rvkf = (AVVkFrame *)ref->data[0];
596 
597  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
598  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
599  .pNext = NULL,
600  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
601  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
602  .srcAccessMask = VK_ACCESS_2_NONE,
603  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR |
604  VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
605  .oldLayout = rvkf->layout[0],
606  .newLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
607  .srcQueueFamilyIndex = rvkf->queue_family[0],
608  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
609  .image = rvkf->img[0],
610  .subresourceRange = (VkImageSubresourceRange) {
611  .aspectMask = rvp->view.aspect_ref[0],
612  .layerCount = 1,
613  .levelCount = 1,
614  },
615  };
616  ff_vk_exec_update_frame(&ctx->s, exec, ref,
617  &img_bar[nb_img_bar], &nb_img_bar);
618  }
619  }
620  } else if (vp->decode_info.referenceSlotCount ||
621  vp->view.out[0] != vp->view.ref[0]) {
622  /* Single barrier for a single layered ref */
623  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
624  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
625  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
626  if (err < 0)
627  return err;
628  }
629 
630  /* Change image layout */
631  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
632  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
633  .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
634  .pImageMemoryBarriers = img_bar,
635  .imageMemoryBarrierCount = nb_img_bar,
636  });
637 
638  /* Start, use parameters, decode and end decoding */
639  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
640  vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
641  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
642 
643  /* End recording and submit for execution */
644  return ff_vk_exec_submit(&ctx->s, exec);
645 }
646 
648 {
649  AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
650 
651  VkSemaphoreWaitInfo sem_wait = (VkSemaphoreWaitInfo) {
652  .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
653  .pSemaphores = &vp->sem,
654  .pValues = &vp->sem_value,
655  .semaphoreCount = 1,
656  };
657 
658  /* We do not have to lock the frame here because we're not interested
659  * in the actual current semaphore value, but only that it's later than
660  * the time we submitted the image for decoding. */
661  if (vp->sem)
662  vp->wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
663 
664  /* Free slices data */
666 
667  /* Destroy image view (out) */
668  for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) {
669  if (vp->view.out[i] && vp->view.out[i] != vp->view.dst[i])
670  vp->destroy_image_view(hwctx->act_dev, vp->view.out[i], hwctx->alloc);
671 
672  /* Destroy image view (ref, unlayered) */
673  if (vp->view.dst[i])
674  vp->destroy_image_view(hwctx->act_dev, vp->view.dst[i], hwctx->alloc);
675  }
676 
677  av_frame_free(&vp->dpb_frame);
678 }
679 
680 static void free_common(AVRefStructOpaque unused, void *obj)
681 {
682  FFVulkanDecodeShared *ctx = obj;
683  FFVulkanContext *s = &ctx->s;
684 
685  /* Wait on and free execution pool */
686  ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
687 
688  /* This also frees all references from this pool */
689  av_frame_free(&ctx->common.layered_frame);
690 
691  av_buffer_pool_uninit(&ctx->buf_pool);
692 
693  ff_vk_video_common_uninit(s, &ctx->common);
694 
695  if (ctx->sd_ctx_free)
696  ctx->sd_ctx_free(ctx);
697 
698  ff_vk_uninit(s);
699 }
700 
701 static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
702 {
703  int err;
705  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
707  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
708  AVVulkanDeviceContext *hwctx = device->hwctx;
710 
711  if (dec->shared_ctx)
712  return 0;
713 
714  dec->shared_ctx = av_refstruct_alloc_ext(sizeof(*ctx), 0, NULL,
715  free_common);
716  if (!dec->shared_ctx)
717  return AVERROR(ENOMEM);
718 
719  ctx = dec->shared_ctx;
720 
721  ctx->s.extensions = ff_vk_extensions_to_mask(hwctx->enabled_dev_extensions,
723 
724  if (vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
725  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_DECODE_QUEUE)) {
726  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
727  VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
729  return AVERROR(ENOSYS);
730  }
731  }
732 
733  err = ff_vk_load_functions(device, &ctx->s.vkfn, ctx->s.extensions, 1, 1);
734  if (err < 0) {
736  return err;
737  }
738 
739  return 0;
740 }
741 
742 static VkResult vulkan_setup_profile(AVCodecContext *avctx,
744  AVVulkanDeviceContext *hwctx,
745  FFVulkanFunctions *vk,
746  const FFVulkanDecodeDescriptor *vk_desc,
747  VkVideoDecodeH264CapabilitiesKHR *h264_caps,
748  VkVideoDecodeH265CapabilitiesKHR *h265_caps,
749 #if CONFIG_VP9_VULKAN_HWACCEL
750  VkVideoDecodeVP9CapabilitiesKHR *vp9_caps,
751 #endif
752  VkVideoDecodeAV1CapabilitiesKHR *av1_caps,
753  VkVideoCapabilitiesKHR *caps,
754  VkVideoDecodeCapabilitiesKHR *dec_caps,
755  int cur_profile)
756 {
757  VkVideoDecodeUsageInfoKHR *usage = &prof->usage;
758  VkVideoProfileInfoKHR *profile = &prof->profile;
759  VkVideoProfileListInfoKHR *profile_list = &prof->profile_list;
760 
761  VkVideoDecodeH264ProfileInfoKHR *h264_profile = &prof->h264_profile;
762  VkVideoDecodeH265ProfileInfoKHR *h265_profile = &prof->h265_profile;
763 #if CONFIG_VP9_VULKAN_HWACCEL
764  VkVideoDecodeVP9ProfileInfoKHR *vp9_profile = &prof->vp9_profile;
765 #endif
766  VkVideoDecodeAV1ProfileInfoKHR *av1_profile = &prof->av1_profile;
767 
769  if (!desc)
770  return AVERROR(EINVAL);
771 
772  if (avctx->codec_id == AV_CODEC_ID_H264) {
773  dec_caps->pNext = h264_caps;
774  usage->pNext = h264_profile;
775  h264_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
776 
777  /* Vulkan transmits all the constrant_set flags, rather than wanting them
778  * merged in the profile IDC */
779  h264_profile->stdProfileIdc = cur_profile & ~(AV_PROFILE_H264_CONSTRAINED |
781 
782  h264_profile->pictureLayout = avctx->field_order == AV_FIELD_UNKNOWN ||
784  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
785  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
786  } else if (avctx->codec_id == AV_CODEC_ID_H265) {
787  dec_caps->pNext = h265_caps;
788  usage->pNext = h265_profile;
789  h265_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
790  h265_profile->stdProfileIdc = cur_profile;
791 #if CONFIG_VP9_VULKAN_HWACCEL
792  } else if (avctx->codec_id == AV_CODEC_ID_VP9) {
793  dec_caps->pNext = vp9_caps;
794  usage->pNext = vp9_profile;
795  vp9_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR;
796  vp9_profile->stdProfile = cur_profile;
797 #endif
798  } else if (avctx->codec_id == AV_CODEC_ID_AV1) {
799  dec_caps->pNext = av1_caps;
800  usage->pNext = av1_profile;
801  av1_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
802  av1_profile->stdProfile = cur_profile;
803  av1_profile->filmGrainSupport = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
804  }
805 
806  usage->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR;
807  usage->videoUsageHints = VK_VIDEO_DECODE_USAGE_DEFAULT_KHR;
808 
809  profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
810  profile->pNext = usage;
811  profile->videoCodecOperation = vk_desc->decode_op;
812  profile->chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
813  profile->lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
814  profile->chromaBitDepth = profile->lumaBitDepth;
815 
816  profile_list->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
817  profile_list->profileCount = 1;
818  profile_list->pProfiles = profile;
819 
820  /* Get the capabilities of the decoder for the given profile */
821  caps->sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
822  caps->pNext = dec_caps;
823  dec_caps->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR;
824  /* dec_caps->pNext already filled in */
825 
826  return vk->GetPhysicalDeviceVideoCapabilitiesKHR(hwctx->phys_dev, profile,
827  caps);
828 }
829 
830 static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref,
831  enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt,
833  int *dpb_dedicate)
834 {
835  VkResult ret;
836  int max_level, base_profile, cur_profile;
837  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
839  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
840  AVVulkanDeviceContext *hwctx = device->hwctx;
841  enum AVPixelFormat source_format;
842  enum AVPixelFormat best_format;
843  VkFormat best_vkfmt;
844 
847  FFVulkanFunctions *vk = &ctx->s.vkfn;
848 
849  VkVideoCapabilitiesKHR *caps = &ctx->caps;
850  VkVideoDecodeCapabilitiesKHR *dec_caps = &ctx->dec_caps;
851 
852  VkVideoDecodeH264CapabilitiesKHR h264_caps = {
853  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR,
854  };
855  VkVideoDecodeH265CapabilitiesKHR h265_caps = {
856  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR,
857  };
858 #if CONFIG_VP9_VULKAN_HWACCEL
859  VkVideoDecodeVP9CapabilitiesKHR vp9_caps = {
860  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_CAPABILITIES_KHR,
861  };
862 #endif
863  VkVideoDecodeAV1CapabilitiesKHR av1_caps = {
864  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR,
865  };
866 
867  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
868  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
869  .pNext = &prof->profile_list,
870  };
871  VkVideoFormatPropertiesKHR *ret_info;
872  uint32_t nb_out_fmts = 0;
873 
874  if (!(vk_desc->decode_extension & ctx->s.extensions)) {
875  av_log(avctx, AV_LOG_ERROR, "Device does not support decoding %s!\n",
876  avcodec_get_name(avctx->codec_id));
877  return AVERROR(ENOSYS);
878  }
879 
880  cur_profile = avctx->profile;
883 #if CONFIG_VP9_VULKAN_HWACCEL
884  avctx->codec_id == AV_CODEC_ID_VP9 ? STD_VIDEO_VP9_PROFILE_0 :
885 #endif
886  avctx->codec_id == AV_CODEC_ID_AV1 ? STD_VIDEO_AV1_PROFILE_MAIN :
887  0;
888 
889  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
890  &h264_caps,
891  &h265_caps,
892 #if CONFIG_VP9_VULKAN_HWACCEL
893  &vp9_caps,
894 #endif
895  &av1_caps,
896  caps,
897  dec_caps,
898  cur_profile);
899  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR &&
901  avctx->profile != base_profile) {
902  av_log(avctx, AV_LOG_VERBOSE, "%s profile %s not supported, attempting "
903  "again with profile %s\n",
904  avcodec_get_name(avctx->codec_id),
905  avcodec_profile_name(avctx->codec_id, cur_profile),
906  avcodec_profile_name(avctx->codec_id, base_profile));
907  cur_profile = base_profile;
908  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
909  &h264_caps,
910  &h265_caps,
911 #if CONFIG_VP9_VULKAN_HWACCEL
912  &vp9_caps,
913 #endif
914  &av1_caps,
915  caps,
916  dec_caps,
917  cur_profile);
918  }
919 
920  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
921  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
922  "%s profile \"%s\" not supported!\n",
923  avcodec_get_name(avctx->codec_id),
924  avcodec_profile_name(avctx->codec_id, cur_profile));
925  return AVERROR(EINVAL);
926  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
927  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
928  "format (%s) not supported!\n",
930  return AVERROR(EINVAL);
931  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
932  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
933  return AVERROR(EINVAL);
934  } else if (ret != VK_SUCCESS) {
935  return AVERROR_EXTERNAL;
936  }
937 
938  max_level = avctx->codec_id == AV_CODEC_ID_H264 ? ff_vk_h264_level_to_av(h264_caps.maxLevelIdc) :
939  avctx->codec_id == AV_CODEC_ID_H265 ? ff_vk_h265_level_to_av(h265_caps.maxLevelIdc) :
940 #if CONFIG_VP9_VULKAN_HWACCEL
941  avctx->codec_id == AV_CODEC_ID_VP9 ? vp9_caps.maxLevel :
942 #endif
943  avctx->codec_id == AV_CODEC_ID_AV1 ? av1_caps.maxLevel :
944  0;
945 
946  av_log(avctx, AV_LOG_VERBOSE, "Decoder capabilities for %s profile \"%s\":\n",
947  avcodec_get_name(avctx->codec_id),
948  avcodec_profile_name(avctx->codec_id, cur_profile));
949  av_log(avctx, AV_LOG_VERBOSE, " Maximum level: %i (stream %i)\n",
950  max_level, avctx->level);
951  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
952  caps->minCodedExtent.width, caps->maxCodedExtent.width);
953  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
954  caps->minCodedExtent.height, caps->maxCodedExtent.height);
955  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
956  caps->pictureAccessGranularity.width);
957  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
958  caps->pictureAccessGranularity.height);
959  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
960  caps->minBitstreamBufferOffsetAlignment);
961  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
962  caps->minBitstreamBufferSizeAlignment);
963  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
964  caps->maxDpbSlots);
965  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
966  caps->maxActiveReferencePictures);
967  av_log(avctx, AV_LOG_VERBOSE, " Codec header name: '%s' (driver), '%s' (compiled)\n",
968  caps->stdHeaderVersion.extensionName,
969  vk_desc->ext_props.extensionName);
970  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
971  CODEC_VER(caps->stdHeaderVersion.specVersion),
972  CODEC_VER(vk_desc->ext_props.specVersion));
973  av_log(avctx, AV_LOG_VERBOSE, " Decode modes:%s%s%s\n",
974  dec_caps->flags ? "" :
975  " invalid",
976  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR ?
977  " reuse_dst_dpb" : "",
978  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR ?
979  " dedicated_dpb" : "");
980  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
981  caps->flags ? "" :
982  " none",
983  caps->flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
984  " protected" : "",
985  caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
986  " separate_references" : "");
987 
988  /* Check if decoding is possible with the given parameters */
989  if (avctx->coded_width < caps->minCodedExtent.width ||
990  avctx->coded_height < caps->minCodedExtent.height ||
991  avctx->coded_width > caps->maxCodedExtent.width ||
992  avctx->coded_height > caps->maxCodedExtent.height)
993  return AVERROR(EINVAL);
994 
996  avctx->level > max_level)
997  return AVERROR(EINVAL);
998 
999  /* Some basic sanity checking */
1000  if (!(dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
1001  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR))) {
1002  av_log(avctx, AV_LOG_ERROR, "Buggy driver signals invalid decoding mode: neither "
1003  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR nor "
1004  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR are set!\n");
1005  return AVERROR_EXTERNAL;
1006  } else if ((dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
1007  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ==
1008  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) &&
1009  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR)) {
1010  av_log(avctx, AV_LOG_ERROR, "Cannot initialize Vulkan decoding session, buggy driver: "
1011  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set "
1012  "but VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!\n");
1013  return AVERROR_EXTERNAL;
1014  }
1015 
1016  dec->dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
1017  ctx->common.layered_dpb = !dec->dedicated_dpb ? 0 :
1018  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
1019 
1020  if (dec->dedicated_dpb) {
1021  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1022  } else {
1023  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1024  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
1025  VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1026  VK_IMAGE_USAGE_SAMPLED_BIT;
1027 
1028  if ((ctx->s.extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE) &&
1029  (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1))
1030  fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1031  }
1032 
1033  /* Get the format of the images necessary */
1034  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1035  &fmt_info,
1036  &nb_out_fmts, NULL);
1037  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1038  (!nb_out_fmts && ret == VK_SUCCESS)) {
1039  return AVERROR(EINVAL);
1040  } else if (ret != VK_SUCCESS) {
1041  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1042  ff_vk_ret2str(ret));
1043  return AVERROR_EXTERNAL;
1044  }
1045 
1046  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
1047  if (!ret_info)
1048  return AVERROR(ENOMEM);
1049 
1050  for (int i = 0; i < nb_out_fmts; i++)
1051  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1052 
1053  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1054  &fmt_info,
1055  &nb_out_fmts, ret_info);
1056  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1057  (!nb_out_fmts && ret == VK_SUCCESS)) {
1058  av_free(ret_info);
1059  return AVERROR(EINVAL);
1060  } else if (ret != VK_SUCCESS) {
1061  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1062  ff_vk_ret2str(ret));
1063  av_free(ret_info);
1064  return AVERROR_EXTERNAL;
1065  }
1066 
1067  /* Find a format to use */
1068  *pix_fmt = best_format = AV_PIX_FMT_NONE;
1069  *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
1070  source_format = avctx->sw_pix_fmt;
1071 
1072  av_log(avctx, AV_LOG_DEBUG, "Choosing best pixel format for decoding from %i:\n", nb_out_fmts);
1073  for (int i = 0; i < nb_out_fmts; i++) {
1075  if (tmp == AV_PIX_FMT_NONE) {
1076  av_log(avctx, AV_LOG_WARNING, "Invalid/unknown Vulkan format %i!\n", ret_info[i].format);
1077  continue;
1078  }
1079 
1080  best_format = av_find_best_pix_fmt_of_2(tmp, best_format, source_format, 0, NULL);
1081  if (tmp == best_format)
1082  best_vkfmt = ret_info[i].format;
1083 
1084  av_log(avctx, AV_LOG_DEBUG, " %s%s (Vulkan ID: %i)\n",
1085  av_get_pix_fmt_name(tmp), tmp == best_format ? "*" : "",
1086  ret_info[i].format);
1087  }
1088 
1089  av_free(ret_info);
1090 
1091  if (best_format == AV_PIX_FMT_NONE) {
1092  av_log(avctx, AV_LOG_ERROR, "No valid/compatible pixel format found for decoding!\n");
1093  return AVERROR(EINVAL);
1094  } else {
1095  av_log(avctx, AV_LOG_VERBOSE, "Chosen frame pixfmt: %s (Vulkan ID: %i)\n",
1096  av_get_pix_fmt_name(best_format), best_vkfmt);
1097  }
1098 
1099  *pix_fmt = best_format;
1100  *vk_fmt = best_vkfmt;
1101 
1102  *dpb_dedicate = dec->dedicated_dpb;
1103 
1104  return 0;
1105 }
1106 
1108 {
1109  av_free(hwfc->user_opaque);
1110 }
1111 
1112 int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
1113 {
1114  int err, dedicated_dpb;
1115  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
1116  AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
1119 
1120  err = vulkan_decode_bootstrap(avctx, hw_frames_ctx);
1121  if (err < 0)
1122  return err;
1123 
1124  frames_ctx->format = AV_PIX_FMT_VULKAN;
1125  frames_ctx->sw_format = avctx->sw_pix_fmt;
1126  frames_ctx->width = avctx->coded_width;
1127  frames_ctx->height = avctx->coded_height;
1128 
1129  if (!DECODER_IS_SDR(avctx->codec_id)) {
1130  prof = av_mallocz(sizeof(FFVulkanDecodeProfileData));
1131  if (!prof)
1132  return AVERROR(ENOMEM);
1133 
1134  err = vulkan_decode_get_profile(avctx, hw_frames_ctx,
1135  &frames_ctx->sw_format,
1136  &hwfc->format[0],
1137  prof, &dedicated_dpb);
1138  if (err < 0) {
1139  av_free(prof);
1140  return err;
1141  }
1142 
1143  const AVPixFmtDescriptor *pdesc = av_pix_fmt_desc_get(frames_ctx->sw_format);
1144  frames_ctx->width = FFALIGN(frames_ctx->width, 1 << pdesc->log2_chroma_w);
1145  frames_ctx->height = FFALIGN(frames_ctx->height, 1 << pdesc->log2_chroma_h);
1146  frames_ctx->user_opaque = prof;
1147  frames_ctx->free = free_profile_data;
1148 
1149  hwfc->create_pnext = &prof->profile_list;
1150  } else {
1151  hwfc->format[0] = VK_FORMAT_UNDEFINED;
1152  switch (frames_ctx->sw_format) {
1153  case AV_PIX_FMT_GBRAP16:
1154  /* This should be more efficient for downloading and using */
1155  frames_ctx->sw_format = AV_PIX_FMT_RGBA64;
1156  break;
1157  case AV_PIX_FMT_GBRP10:
1158  /* This saves memory bandwidth when downloading */
1159  frames_ctx->sw_format = AV_PIX_FMT_X2BGR10;
1160  break;
1161  case AV_PIX_FMT_RGB24:
1162  case AV_PIX_FMT_BGR0:
1163  /* mpv has issues with bgr0 mapping, so just remap it */
1164  frames_ctx->sw_format = AV_PIX_FMT_RGB0;
1165  break;
1166  /* DPX endian mismatch remappings */
1167  case AV_PIX_FMT_RGB48LE:
1168  case AV_PIX_FMT_RGB48BE: frames_ctx->sw_format = AV_PIX_FMT_GBRP16; break;
1169  case AV_PIX_FMT_RGBA64BE: frames_ctx->sw_format = AV_PIX_FMT_RGBA64; break;
1170  case AV_PIX_FMT_GRAY16BE: frames_ctx->sw_format = AV_PIX_FMT_GRAY16; break;
1171  /* ProRes needs to clear the input image, which is not possible on YUV formats */
1172  case AV_PIX_FMT_YUVA422P10:
1173  case AV_PIX_FMT_YUVA444P10:
1174  case AV_PIX_FMT_YUVA422P12:
1175  case AV_PIX_FMT_YUVA444P12:
1176  hwfc->format[3] = VK_FORMAT_R16_UNORM;
1178  case AV_PIX_FMT_YUV422P10:
1179  case AV_PIX_FMT_YUV444P10:
1180  case AV_PIX_FMT_YUV422P12:
1181  case AV_PIX_FMT_YUV444P12:
1182  hwfc->format[0] = VK_FORMAT_R16_UNORM;
1183  hwfc->format[1] = VK_FORMAT_R16_UNORM;
1184  hwfc->format[2] = VK_FORMAT_R16_UNORM;
1185  break;
1186  default:
1187  break;
1188  }
1189  }
1190 
1191  if (hwfc->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1192  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1193 
1194  hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1195  VK_IMAGE_USAGE_STORAGE_BIT |
1196  VK_IMAGE_USAGE_SAMPLED_BIT;
1197 
1198  if (prof) {
1200 
1201  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1202  if (!dec->dedicated_dpb)
1203  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1204 
1205  ctx = dec->shared_ctx;
1206  if ((ctx->s.extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE) &&
1207  (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1))
1208  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1209  }
1210 
1211  return err;
1212 }
1213 
1214 static void vk_decode_free_params(void *opaque, uint8_t *data)
1215 {
1216  FFVulkanDecodeShared *ctx = opaque;
1217  FFVulkanFunctions *vk = &ctx->s.vkfn;
1218  VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)data;
1219  vk->DestroyVideoSessionParametersKHR(ctx->s.hwctx->act_dev, *par,
1220  ctx->s.hwctx->alloc);
1221  av_free(par);
1222 }
1223 
1225  const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1226 {
1227  VkVideoSessionParametersKHR *par = av_malloc(sizeof(*par));
1228  const FFVulkanFunctions *vk = &ctx->s.vkfn;
1229  VkResult ret;
1230 
1231  if (!par)
1232  return AVERROR(ENOMEM);
1233 
1234  /* Create session parameters */
1235  ret = vk->CreateVideoSessionParametersKHR(ctx->s.hwctx->act_dev, session_params_create,
1236  ctx->s.hwctx->alloc, par);
1237  if (ret != VK_SUCCESS) {
1238  av_log(logctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1239  ff_vk_ret2str(ret));
1240  av_free(par);
1241  return AVERROR_EXTERNAL;
1242  }
1243  *par_ref = av_buffer_create((uint8_t *)par, sizeof(*par),
1245  if (!*par_ref) {
1246  vk_decode_free_params(ctx, (uint8_t *)par);
1247  return AVERROR(ENOMEM);
1248  }
1249 
1250  return 0;
1251 }
1252 
1254 {
1256 
1257  av_freep(&dec->hevc_headers);
1260  av_freep(&dec->slice_off);
1261  return 0;
1262 }
1263 
1265 {
1266  int err;
1269  FFVulkanContext *s;
1270  int async_depth;
1271  const VkVideoProfileInfoKHR *profile;
1272  const FFVulkanDecodeDescriptor *vk_desc;
1273 
1274  VkVideoSessionCreateInfoKHR session_create = {
1275  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1276  };
1277 
1279  if (err < 0)
1280  return err;
1281 
1282  /* Initialize contexts */
1283  ctx = dec->shared_ctx;
1284  s = &ctx->s;
1285 
1286  err = ff_vk_init(s, avctx, NULL, avctx->hw_frames_ctx);
1287  if (err < 0)
1288  return err;
1289 
1290  vk_desc = get_codecdesc(avctx->codec_id);
1291 
1293  if ((vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) && !profile) {
1294  av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
1295  return AVERROR(EINVAL);
1296  }
1297 
1298  /* Create queue context */
1299  vk_desc = get_codecdesc(avctx->codec_id);
1300  ctx->qf = ff_vk_qf_find(s, vk_desc->queue_flags, vk_desc->decode_op);
1301  if (!ctx->qf) {
1302  av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
1303  avcodec_get_name(avctx->codec_id));
1304  return err;
1305  }
1306 
1307  session_create.queueFamilyIndex = ctx->qf->idx;
1308  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1309  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1310  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1311  session_create.pictureFormat = s->hwfc->format[0];
1312  session_create.referencePictureFormat = session_create.pictureFormat;
1313  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1314  session_create.pVideoProfile = profile;
1315 #ifdef VK_KHR_video_maintenance2
1316  if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)
1317  session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1318 #endif
1319 
1320  /* Create decode exec context for this specific main thread.
1321  * 2 async contexts per thread was experimentally determined to be optimal
1322  * for a majority of streams. */
1323  async_depth = 2*ctx->qf->num;
1324  /* We don't need more than 2 per thread context */
1325  async_depth = FFMIN(async_depth, 2*avctx->thread_count);
1326  /* Make sure there are enough async contexts for each thread */
1327  async_depth = FFMAX(async_depth, avctx->thread_count);
1328 
1329  err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
1330  async_depth, 0, 0, 0, profile);
1331  if (err < 0)
1332  goto fail;
1333 
1334  if (!DECODER_IS_SDR(avctx->codec_id)) {
1335  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1336  if (err < 0)
1337  goto fail;
1338  }
1339 
1340  /* If doing an out-of-place decoding, create a DPB pool */
1341  if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) {
1343  AVVulkanFramesContext *dpb_hwfc;
1344 
1345  ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref);
1346  if (!ctx->common.dpb_hwfc_ref) {
1347  err = AVERROR(ENOMEM);
1348  goto fail;
1349  }
1350 
1351  dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
1352  dpb_frames->format = s->frames->format;
1353  dpb_frames->sw_format = s->frames->sw_format;
1354  dpb_frames->width = s->frames->width;
1355  dpb_frames->height = s->frames->height;
1356 
1357  dpb_hwfc = dpb_frames->hwctx;
1358  void *profile_list = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1359  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1360  /* Reference (DPB) images use the same tiling and pNext chain as output.
1361  * If VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR is 0, the
1362  * driver does not support separate output and DPB with different layouts/tiling. */
1363  void *drm_create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1364  VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
1365  if (drm_create_pnext) {
1366  dpb_hwfc->create_pnext = drm_create_pnext;
1367  dpb_hwfc->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
1368  av_assert2(ff_vk_find_struct(drm_create_pnext, VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
1369  } else {
1370  dpb_hwfc->create_pnext = profile_list;
1371  dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1372  }
1373  dpb_hwfc->format[0] = s->hwfc->format[0];
1374  dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1375 
1376  if (ctx->common.layered_dpb)
1377  dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
1378 
1379  err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref);
1380  if (err < 0)
1381  goto fail;
1382 
1383  if (ctx->common.layered_dpb) {
1384  ctx->common.layered_frame = vk_get_dpb_pool(ctx);
1385  if (!ctx->common.layered_frame) {
1386  err = AVERROR(ENOMEM);
1387  goto fail;
1388  }
1389 
1390  err = ff_vk_create_view(&ctx->s, &ctx->common,
1391  &ctx->common.layered_view,
1392  &ctx->common.layered_aspect,
1393  (AVVkFrame *)ctx->common.layered_frame->data[0],
1394  s->hwfc->format[0], VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR);
1395  if (err < 0)
1396  goto fail;
1397  }
1398  }
1399 
1400  if (!DECODER_IS_SDR(avctx->codec_id)) {
1401  err = decode_reset(avctx, ctx);
1402  if (err < 0)
1403  return err;
1404  } else {
1405  /* For SDR decoders, this alignment value will be 0. Since this will make
1406  * add_slice() malfunction, set it to a sane default value. */
1407  ctx->caps.minBitstreamBufferSizeAlignment = AV_INPUT_BUFFER_PADDING_SIZE;
1408  }
1409 
1410  const VkPhysicalDeviceDriverProperties *driver_props;
1411  driver_props = &dec->shared_ctx->s.driver_props;
1412  if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1413  driver_props->conformanceVersion.major == 1 &&
1414  driver_props->conformanceVersion.minor == 3 &&
1415  driver_props->conformanceVersion.subminor == 8 &&
1416  driver_props->conformanceVersion.patch < 3)
1417  dec->quirk_av1_offset = 1;
1418 
1419  av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization successful\n");
1420 
1421  return 0;
1422 
1423 fail:
1424  ff_vk_decode_uninit(avctx);
1425 
1426  return err;
1427 }
vulkan_loader.h
ff_vk_dec_apv_desc
const FFVulkanDecodeDescriptor ff_vk_dec_apv_desc
Definition: vulkan_apv.c:33
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
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@352 view
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
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:61
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:880
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:466
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:375
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:348
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:2891
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:568
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2879
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
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:99
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:643
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:800
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:198
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:487
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
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:266
FFVulkanDecodeDescriptor::decode_op
VkVideoCodecOperationFlagBitsKHR decode_op
Definition: vulkan_decode.h:33
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:1579
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:171
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:40
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
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:441
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:830
init_frame
static void init_frame(FFVulkanDecodeContext *dec, FFVulkanDecodePicture *vkpic)
Definition: vulkan_decode.c:181
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: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::wait_semaphores
PFN_vkWaitSemaphores wait_semaphores
Definition: vulkan_decode.h:103
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:1224
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:899
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:131
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:573
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: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:640
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: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:1063
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:453
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
fail
#define fail
Definition: test.h:478
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: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:647
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:69
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
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:1253
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:129
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
FFVulkanDecodePicture::aspect
VkImageAspectFlags aspect[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:80
attributes.h
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:1112
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1646
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:47
usage
const char * usage
Definition: floatimg_cmp.c:62
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:680
FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
Definition: vulkan_functions.h:60
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:261
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:467
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:320
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:1214
FFVulkanDecodeProfileData
Definition: vulkan_decode.c:93
FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
Definition: vulkan_functions.h:63
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
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:580
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: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
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: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
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: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:763
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:3735
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:593
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1636
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:160
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
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:291
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:742
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:167
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:925
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:701
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:1264
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:650
decode_reset
static int decode_reset(AVCodecContext *avctx, FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:389
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:275
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:1306
src
#define src
Definition: vp8dsp.c:248
free_profile_data
static void free_profile_data(AVHWFramesContext *hwfc)
Definition: vulkan_decode.c:1107
AV_CODEC_EXPORT_DATA_FILM_GRAIN
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition: avcodec.h:404
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