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