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