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