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], !is_current);
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], !is_current);
235  if (err < 0)
236  return err;
237 
238  if (!alloc_dpb) {
239  vkpic->view.ref[0] = vkpic->view.out[0];
240  vkpic->view.aspect_ref[0] = vkpic->view.aspect[0];
241  }
242  }
243 
244  return 0;
245 }
246 
248  FFVulkanDecodePicture *vkpic, int is_current,
249  enum FFVkShaderRepFormat rep_fmt, int alloc_dpb)
250 {
251  int err;
254 
255  vkpic->slices_size = 0;
256 
257  if (vkpic->view.ref[0])
258  return 0;
259 
260  init_frame(dec, vkpic);
261 
262  for (int i = 0; i < av_pix_fmt_count_planes(frames->sw_format); i++) {
263  if (alloc_dpb) {
264  vkpic->dpb_frame = vk_get_dpb_pool(ctx);
265  if (!vkpic->dpb_frame)
266  return AVERROR(ENOMEM);
267 
268  err = ff_vk_create_imageview(&ctx->s,
269  &vkpic->view.ref[i], &vkpic->view.aspect_ref[i],
270  vkpic->dpb_frame, i, rep_fmt);
271  if (err < 0)
272  return err;
273 
274  vkpic->view.dst[i] = vkpic->view.ref[i];
275  }
276 
277  if (!alloc_dpb || is_current) {
278  err = ff_vk_create_imageview(&ctx->s,
279  &vkpic->view.out[i], &vkpic->view.aspect[i],
280  pic, i, rep_fmt);
281  if (err < 0)
282  return err;
283 
284  if (!alloc_dpb) {
285  vkpic->view.ref[i] = vkpic->view.out[i];
286  vkpic->view.aspect_ref[i] = vkpic->view.aspect[i];
287  }
288  }
289  }
290 
291  return 0;
292 }
293 
295  const uint8_t *data, size_t size, int add_startcode,
296  uint32_t *nb_slices, const uint32_t **offsets)
297 {
300 
301  static const uint8_t startcode_prefix[3] = { 0x0, 0x0, 0x1 };
302  const size_t startcode_len = add_startcode ? sizeof(startcode_prefix) : 0;
303  const int nb = nb_slices ? *nb_slices : 0;
304  uint8_t *slices;
305  uint32_t *slice_off;
306  FFVkBuffer *vkbuf;
307 
308  size_t new_size = vp->slices_size + startcode_len + size +
309  ctx->caps.minBitstreamBufferSizeAlignment;
310  new_size = FFALIGN(new_size, ctx->caps.minBitstreamBufferSizeAlignment);
311 
312  if (offsets) {
313  slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
314  (nb + 1)*sizeof(slice_off));
315  if (!slice_off)
316  return AVERROR(ENOMEM);
317 
318  *offsets = dec->slice_off = slice_off;
319 
320  slice_off[nb] = vp->slices_size;
321  }
322 
323  vkbuf = vp->slices_buf ? (FFVkBuffer *)vp->slices_buf->data : NULL;
324  if (!vkbuf || vkbuf->size < new_size) {
325  int err;
326  AVBufferRef *new_ref;
327  FFVkBuffer *new_buf;
328 
329  /* No point in requesting anything smaller. */
330  size_t buf_size = FFMAX(new_size, 1024*1024);
331 
332  /* Align buffer to nearest power of two. Makes fragmentation management
333  * easier, and gives us ample headroom. */
334  buf_size = 2 << av_log2(buf_size);
335 
336  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_ref,
337  DECODER_IS_SDR(avctx->codec_id) ?
338  (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
339  VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) :
340  VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR,
341  ctx->s.hwfc->create_pnext, buf_size,
342  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
343  (DECODER_IS_SDR(avctx->codec_id) ?
344  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0));
345  if (err < 0)
346  return err;
347 
348  new_buf = (FFVkBuffer *)new_ref->data;
349 
350  /* Copy data from the old buffer */
351  if (vkbuf) {
352  memcpy(new_buf->mapped_mem, vkbuf->mapped_mem, vp->slices_size);
354  }
355 
356  vp->slices_buf = new_ref;
357  vkbuf = new_buf;
358  }
359  slices = vkbuf->mapped_mem;
360 
361  /* Startcode */
362  memcpy(slices + vp->slices_size, startcode_prefix, startcode_len);
363 
364  /* Slice data */
365  memcpy(slices + vp->slices_size + startcode_len, data, size);
366 
367  if (nb_slices)
368  *nb_slices = nb + 1;
369 
370  vp->slices_size += startcode_len + size;
371 
372  return 0;
373 }
374 
376 {
379 
380  FFVulkanFunctions *vk = &ctx->s.vkfn;
381  VkVideoBeginCodingInfoKHR decode_start = {
382  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
383  .videoSession = ctx->common.session,
384  .videoSessionParameters = ctx->empty_session_params,
385  };
386  VkVideoCodingControlInfoKHR decode_ctrl = {
387  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
388  .flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
389  };
390  VkVideoEndCodingInfoKHR decode_end = {
391  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
392  };
393 
394  VkCommandBuffer cmd_buf;
395  FFVkExecContext *exec;
396 
397  /* Non-video queues do not need to be reset */
398  if (!(get_codecdesc(avctx->codec_id)->decode_op))
399  return;
400 
401  exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
402  ff_vk_exec_start(&ctx->s, exec);
403  cmd_buf = exec->buf;
404 
405  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
406  vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
407  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
408  ff_vk_exec_submit(&ctx->s, exec);
409 }
410 
412  AVFrame *pic, FFVulkanDecodePicture *vp,
413  AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
414 {
415  int err;
416  VkResult ret;
417  VkCommandBuffer cmd_buf;
418  FFVkBuffer *sd_buf;
419 
422  FFVulkanFunctions *vk = &ctx->s.vkfn;
423 
424  /* Output */
425  AVVkFrame *vkf = (AVVkFrame *)pic->buf[0]->data;
426 
427  /* Quirks */
428  const int layered_dpb = ctx->common.layered_dpb;
429 
430  VkVideoBeginCodingInfoKHR decode_start = {
431  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
432  .videoSession = ctx->common.session,
433  .videoSessionParameters = dec->session_params ?
434  *((VkVideoSessionParametersKHR *)dec->session_params->data) :
435  VK_NULL_HANDLE,
436  .referenceSlotCount = vp->decode_info.referenceSlotCount,
437  .pReferenceSlots = vp->decode_info.pReferenceSlots,
438  };
439  VkVideoEndCodingInfoKHR decode_end = {
440  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
441  };
442 
443  VkImageMemoryBarrier2 img_bar[37];
444  int nb_img_bar = 0;
445  size_t data_size = FFALIGN(vp->slices_size,
446  ctx->caps.minBitstreamBufferSizeAlignment);
447 
448  FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
449 
450  /* The current decoding reference has to be bound as an inactive reference */
451  VkVideoReferenceSlotInfoKHR *cur_vk_ref;
452  cur_vk_ref = (void *)&decode_start.pReferenceSlots[decode_start.referenceSlotCount];
453  cur_vk_ref[0] = vp->ref_slot;
454  cur_vk_ref[0].slotIndex = -1;
455  decode_start.referenceSlotCount++;
456 
457  sd_buf = (FFVkBuffer *)vp->slices_buf->data;
458 
459  /* Flush if needed */
460  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
461  VkMappedMemoryRange flush_buf = {
462  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
463  .memory = sd_buf->mem,
464  .offset = 0,
465  .size = FFALIGN(vp->slices_size,
466  ctx->s.props.properties.limits.nonCoherentAtomSize),
467  };
468 
469  ret = vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &flush_buf);
470  if (ret != VK_SUCCESS) {
471  av_log(avctx, AV_LOG_ERROR, "Failed to flush memory: %s\n",
472  ff_vk_ret2str(ret));
473  return AVERROR_EXTERNAL;
474  }
475  }
476 
477  vp->decode_info.srcBuffer = sd_buf->buf;
478  vp->decode_info.srcBufferOffset = 0;
479  vp->decode_info.srcBufferRange = data_size;
480 
481  /* Start command buffer recording */
482  err = ff_vk_exec_start(&ctx->s, exec);
483  if (err < 0)
484  return err;
485  cmd_buf = exec->buf;
486 
487  /* Slices */
488  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0);
489  if (err < 0)
490  return err;
491  vp->slices_buf = NULL; /* Owned by the exec buffer from now on */
492 
493  /* Parameters */
494  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &dec->session_params, 1, 1);
495  if (err < 0)
496  return err;
497 
498  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, pic,
499  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
500  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
501  if (err < 0)
502  return err;
503 
504  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
505  pic);
506  if (err < 0)
507  return err;
508 
509  /* Output image - change layout, as it comes from a pool */
510  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
511  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
512  .pNext = NULL,
513  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
514  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
515  .srcAccessMask = VK_ACCESS_2_NONE,
516  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
517  .oldLayout = vkf->layout[0],
518  .newLayout = (layered_dpb || vp->dpb_frame) ?
519  VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
520  VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, /* Spec, 07252 utter madness */
521  .srcQueueFamilyIndex = vkf->queue_family[0],
522  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
523  .image = vkf->img[0],
524  .subresourceRange = (VkImageSubresourceRange) {
525  .aspectMask = vp->view.aspect[0],
526  .layerCount = 1,
527  .levelCount = 1,
528  },
529  };
530  ff_vk_exec_update_frame(&ctx->s, exec, pic,
531  &img_bar[nb_img_bar], &nb_img_bar);
532 
533  /* Reference for the current image, if existing and not layered */
534  if (vp->dpb_frame) {
535  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, vp->dpb_frame,
536  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
537  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
538  if (err < 0)
539  return err;
540  }
541 
542  if (!layered_dpb) {
543  /* All references (apart from the current) for non-layered refs */
544 
545  for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
546  AVFrame *ref_frame = rpic[i];
547  FFVulkanDecodePicture *rvp = rvkp[i];
548  AVFrame *ref = rvp->dpb_frame ? rvp->dpb_frame : ref_frame;
549 
550  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref,
551  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
552  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
553  if (err < 0)
554  return err;
555 
556  if (err == 0) {
557  err = ff_vk_exec_mirror_sem_value(&ctx->s, exec,
558  &rvp->sem, &rvp->sem_value,
559  ref);
560  if (err < 0)
561  return err;
562  }
563 
564  if (!rvp->dpb_frame) {
565  AVVkFrame *rvkf = (AVVkFrame *)ref->data[0];
566 
567  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
568  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
569  .pNext = NULL,
570  .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
571  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
572  .srcAccessMask = VK_ACCESS_2_NONE,
573  .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR |
574  VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
575  .oldLayout = rvkf->layout[0],
576  .newLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
577  .srcQueueFamilyIndex = rvkf->queue_family[0],
578  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
579  .image = rvkf->img[0],
580  .subresourceRange = (VkImageSubresourceRange) {
581  .aspectMask = rvp->view.aspect_ref[0],
582  .layerCount = 1,
583  .levelCount = 1,
584  },
585  };
586  ff_vk_exec_update_frame(&ctx->s, exec, ref,
587  &img_bar[nb_img_bar], &nb_img_bar);
588  }
589  }
590  } else if (vp->decode_info.referenceSlotCount ||
591  vp->view.out[0] != vp->view.ref[0]) {
592  /* Single barrier for a single layered ref */
593  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
594  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
595  VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
596  if (err < 0)
597  return err;
598  }
599 
600  /* Change image layout */
601  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
602  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
603  .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
604  .pImageMemoryBarriers = img_bar,
605  .imageMemoryBarrierCount = nb_img_bar,
606  });
607 
608  /* Start, use parameters, decode and end decoding */
609  vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
610  vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
611  vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
612 
613  /* End recording and submit for execution */
614  return ff_vk_exec_submit(&ctx->s, exec);
615 }
616 
618 {
619  AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
620 
621  VkSemaphoreWaitInfo sem_wait = (VkSemaphoreWaitInfo) {
622  .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
623  .pSemaphores = &vp->sem,
624  .pValues = &vp->sem_value,
625  .semaphoreCount = 1,
626  };
627 
628  /* We do not have to lock the frame here because we're not interested
629  * in the actual current semaphore value, but only that it's later than
630  * the time we submitted the image for decoding. */
631  if (vp->sem)
632  vp->wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
633 
634  /* Free slices data */
636 
637  /* Destroy image view (out) */
638  for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) {
639  if (vp->view.out[i] && vp->view.out[i] != vp->view.dst[i])
640  vp->destroy_image_view(hwctx->act_dev, vp->view.out[i], hwctx->alloc);
641 
642  /* Destroy image view (ref, unlayered) */
643  if (vp->view.dst[i])
644  vp->destroy_image_view(hwctx->act_dev, vp->view.dst[i], hwctx->alloc);
645  }
646 
647  av_frame_free(&vp->dpb_frame);
648 }
649 
650 static void free_common(AVRefStructOpaque unused, void *obj)
651 {
652  FFVulkanDecodeShared *ctx = obj;
653  FFVulkanContext *s = &ctx->s;
654  FFVulkanFunctions *vk = &ctx->s.vkfn;
655 
656  /* Wait on and free execution pool */
657  ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
658 
659  /* This also frees all references from this pool */
660  av_frame_free(&ctx->common.layered_frame);
661 
662  /* Destroy parameters */
663  if (ctx->empty_session_params)
664  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
665  ctx->empty_session_params,
666  s->hwctx->alloc);
667 
668  av_buffer_pool_uninit(&ctx->buf_pool);
669 
670  ff_vk_video_common_uninit(s, &ctx->common);
671 
672  if (ctx->sd_ctx_free)
673  ctx->sd_ctx_free(ctx);
674 
675  ff_vk_uninit(s);
676 }
677 
678 static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
679 {
680  int err;
682  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
684  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
685  AVVulkanDeviceContext *hwctx = device->hwctx;
687 
688  if (dec->shared_ctx)
689  return 0;
690 
691  dec->shared_ctx = av_refstruct_alloc_ext(sizeof(*ctx), 0, NULL,
692  free_common);
693  if (!dec->shared_ctx)
694  return AVERROR(ENOMEM);
695 
696  ctx = dec->shared_ctx;
697 
698  ctx->s.extensions = ff_vk_extensions_to_mask(hwctx->enabled_dev_extensions,
700 
701  if (vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
702  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_DECODE_QUEUE)) {
703  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
704  VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
706  return AVERROR(ENOSYS);
707  }
708  }
709 
710  err = ff_vk_load_functions(device, &ctx->s.vkfn, ctx->s.extensions, 1, 1);
711  if (err < 0) {
713  return err;
714  }
715 
716  return 0;
717 }
718 
719 static VkResult vulkan_setup_profile(AVCodecContext *avctx,
721  AVVulkanDeviceContext *hwctx,
722  FFVulkanFunctions *vk,
723  const FFVulkanDecodeDescriptor *vk_desc,
724  VkVideoDecodeH264CapabilitiesKHR *h264_caps,
725  VkVideoDecodeH265CapabilitiesKHR *h265_caps,
726 #if CONFIG_VP9_VULKAN_HWACCEL
727  VkVideoDecodeVP9CapabilitiesKHR *vp9_caps,
728 #endif
729  VkVideoDecodeAV1CapabilitiesKHR *av1_caps,
730  VkVideoCapabilitiesKHR *caps,
731  VkVideoDecodeCapabilitiesKHR *dec_caps,
732  int cur_profile)
733 {
734  VkVideoDecodeUsageInfoKHR *usage = &prof->usage;
735  VkVideoProfileInfoKHR *profile = &prof->profile;
736  VkVideoProfileListInfoKHR *profile_list = &prof->profile_list;
737 
738  VkVideoDecodeH264ProfileInfoKHR *h264_profile = &prof->h264_profile;
739  VkVideoDecodeH265ProfileInfoKHR *h265_profile = &prof->h265_profile;
740 #if CONFIG_VP9_VULKAN_HWACCEL
741  VkVideoDecodeVP9ProfileInfoKHR *vp9_profile = &prof->vp9_profile;
742 #endif
743  VkVideoDecodeAV1ProfileInfoKHR *av1_profile = &prof->av1_profile;
744 
746  if (!desc)
747  return AVERROR(EINVAL);
748 
749  if (avctx->codec_id == AV_CODEC_ID_H264) {
750  dec_caps->pNext = h264_caps;
751  usage->pNext = h264_profile;
752  h264_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
753 
754  /* Vulkan transmits all the constrant_set flags, rather than wanting them
755  * merged in the profile IDC */
756  h264_profile->stdProfileIdc = cur_profile & ~(AV_PROFILE_H264_CONSTRAINED |
758 
759  h264_profile->pictureLayout = avctx->field_order == AV_FIELD_UNKNOWN ||
761  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
762  VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
763  } else if (avctx->codec_id == AV_CODEC_ID_H265) {
764  dec_caps->pNext = h265_caps;
765  usage->pNext = h265_profile;
766  h265_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
767  h265_profile->stdProfileIdc = cur_profile;
768 #if CONFIG_VP9_VULKAN_HWACCEL
769  } else if (avctx->codec_id == AV_CODEC_ID_VP9) {
770  dec_caps->pNext = vp9_caps;
771  usage->pNext = vp9_profile;
772  vp9_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR;
773  vp9_profile->stdProfile = cur_profile;
774 #endif
775  } else if (avctx->codec_id == AV_CODEC_ID_AV1) {
776  dec_caps->pNext = av1_caps;
777  usage->pNext = av1_profile;
778  av1_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
779  av1_profile->stdProfile = cur_profile;
780  av1_profile->filmGrainSupport = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
781  }
782 
783  usage->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR;
784  usage->videoUsageHints = VK_VIDEO_DECODE_USAGE_DEFAULT_KHR;
785 
786  profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
787  profile->pNext = usage;
788  profile->videoCodecOperation = vk_desc->decode_op;
789  profile->chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
790  profile->lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
791  profile->chromaBitDepth = profile->lumaBitDepth;
792 
793  profile_list->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
794  profile_list->profileCount = 1;
795  profile_list->pProfiles = profile;
796 
797  /* Get the capabilities of the decoder for the given profile */
798  caps->sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
799  caps->pNext = dec_caps;
800  dec_caps->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR;
801  /* dec_caps->pNext already filled in */
802 
803  return vk->GetPhysicalDeviceVideoCapabilitiesKHR(hwctx->phys_dev, profile,
804  caps);
805 }
806 
807 static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref,
808  enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt,
810  int *dpb_dedicate)
811 {
812  VkResult ret;
813  int max_level, base_profile, cur_profile;
814  const FFVulkanDecodeDescriptor *vk_desc = get_codecdesc(avctx->codec_id);
816  AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
817  AVVulkanDeviceContext *hwctx = device->hwctx;
818  enum AVPixelFormat source_format;
819  enum AVPixelFormat best_format;
820  VkFormat best_vkfmt;
821 
824  FFVulkanFunctions *vk = &ctx->s.vkfn;
825 
826  VkVideoCapabilitiesKHR *caps = &ctx->caps;
827  VkVideoDecodeCapabilitiesKHR *dec_caps = &ctx->dec_caps;
828 
829  VkVideoDecodeH264CapabilitiesKHR h264_caps = {
830  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR,
831  };
832  VkVideoDecodeH265CapabilitiesKHR h265_caps = {
833  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR,
834  };
835 #if CONFIG_VP9_VULKAN_HWACCEL
836  VkVideoDecodeVP9CapabilitiesKHR vp9_caps = {
837  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_CAPABILITIES_KHR,
838  };
839 #endif
840  VkVideoDecodeAV1CapabilitiesKHR av1_caps = {
841  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR,
842  };
843 
844  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
845  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
846  .pNext = &prof->profile_list,
847  };
848  VkVideoFormatPropertiesKHR *ret_info;
849  uint32_t nb_out_fmts = 0;
850 
851  if (!(vk_desc->decode_extension & ctx->s.extensions)) {
852  av_log(avctx, AV_LOG_ERROR, "Device does not support decoding %s!\n",
853  avcodec_get_name(avctx->codec_id));
854  return AVERROR(ENOSYS);
855  }
856 
857  cur_profile = avctx->profile;
860 #if CONFIG_VP9_VULKAN_HWACCEL
861  avctx->codec_id == AV_CODEC_ID_VP9 ? STD_VIDEO_VP9_PROFILE_0 :
862 #endif
863  avctx->codec_id == AV_CODEC_ID_AV1 ? STD_VIDEO_AV1_PROFILE_MAIN :
864  0;
865 
866  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
867  &h264_caps,
868  &h265_caps,
869 #if CONFIG_VP9_VULKAN_HWACCEL
870  &vp9_caps,
871 #endif
872  &av1_caps,
873  caps,
874  dec_caps,
875  cur_profile);
876  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR &&
878  avctx->profile != base_profile) {
879  av_log(avctx, AV_LOG_VERBOSE, "%s profile %s not supported, attempting "
880  "again with profile %s\n",
881  avcodec_get_name(avctx->codec_id),
882  avcodec_profile_name(avctx->codec_id, cur_profile),
883  avcodec_profile_name(avctx->codec_id, base_profile));
884  cur_profile = base_profile;
885  ret = vulkan_setup_profile(avctx, prof, hwctx, vk, vk_desc,
886  &h264_caps,
887  &h265_caps,
888 #if CONFIG_VP9_VULKAN_HWACCEL
889  &vp9_caps,
890 #endif
891  &av1_caps,
892  caps,
893  dec_caps,
894  cur_profile);
895  }
896 
897  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
898  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
899  "%s profile \"%s\" not supported!\n",
900  avcodec_get_name(avctx->codec_id),
901  avcodec_profile_name(avctx->codec_id, cur_profile));
902  return AVERROR(EINVAL);
903  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
904  av_log(avctx, AV_LOG_VERBOSE, "Unable to initialize video session: "
905  "format (%s) not supported!\n",
907  return AVERROR(EINVAL);
908  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
909  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
910  return AVERROR(EINVAL);
911  } else if (ret != VK_SUCCESS) {
912  return AVERROR_EXTERNAL;
913  }
914 
915  max_level = avctx->codec_id == AV_CODEC_ID_H264 ? ff_vk_h264_level_to_av(h264_caps.maxLevelIdc) :
916  avctx->codec_id == AV_CODEC_ID_H265 ? ff_vk_h265_level_to_av(h265_caps.maxLevelIdc) :
917 #if CONFIG_VP9_VULKAN_HWACCEL
918  avctx->codec_id == AV_CODEC_ID_VP9 ? vp9_caps.maxLevel :
919 #endif
920  avctx->codec_id == AV_CODEC_ID_AV1 ? av1_caps.maxLevel :
921  0;
922 
923  av_log(avctx, AV_LOG_VERBOSE, "Decoder capabilities for %s profile \"%s\":\n",
924  avcodec_get_name(avctx->codec_id),
925  avcodec_profile_name(avctx->codec_id, cur_profile));
926  av_log(avctx, AV_LOG_VERBOSE, " Maximum level: %i (stream %i)\n",
927  max_level, avctx->level);
928  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
929  caps->minCodedExtent.width, caps->maxCodedExtent.width);
930  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
931  caps->minCodedExtent.height, caps->maxCodedExtent.height);
932  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
933  caps->pictureAccessGranularity.width);
934  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
935  caps->pictureAccessGranularity.height);
936  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
937  caps->minBitstreamBufferOffsetAlignment);
938  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
939  caps->minBitstreamBufferSizeAlignment);
940  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
941  caps->maxDpbSlots);
942  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
943  caps->maxActiveReferencePictures);
944  av_log(avctx, AV_LOG_VERBOSE, " Codec header name: '%s' (driver), '%s' (compiled)\n",
945  caps->stdHeaderVersion.extensionName,
946  vk_desc->ext_props.extensionName);
947  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
948  CODEC_VER(caps->stdHeaderVersion.specVersion),
949  CODEC_VER(vk_desc->ext_props.specVersion));
950  av_log(avctx, AV_LOG_VERBOSE, " Decode modes:%s%s%s\n",
951  dec_caps->flags ? "" :
952  " invalid",
953  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR ?
954  " reuse_dst_dpb" : "",
955  dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR ?
956  " dedicated_dpb" : "");
957  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
958  caps->flags ? "" :
959  " none",
960  caps->flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
961  " protected" : "",
962  caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
963  " separate_references" : "");
964 
965  /* Check if decoding is possible with the given parameters */
966  if (avctx->coded_width < caps->minCodedExtent.width ||
967  avctx->coded_height < caps->minCodedExtent.height ||
968  avctx->coded_width > caps->maxCodedExtent.width ||
969  avctx->coded_height > caps->maxCodedExtent.height)
970  return AVERROR(EINVAL);
971 
973  avctx->level > max_level)
974  return AVERROR(EINVAL);
975 
976  /* Some basic sanity checking */
977  if (!(dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
978  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR))) {
979  av_log(avctx, AV_LOG_ERROR, "Buggy driver signals invalid decoding mode: neither "
980  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR nor "
981  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR are set!\n");
982  return AVERROR_EXTERNAL;
983  } else if ((dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
984  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ==
985  VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) &&
986  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR)) {
987  av_log(avctx, AV_LOG_ERROR, "Cannot initialize Vulkan decoding session, buggy driver: "
988  "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set "
989  "but VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!\n");
990  return AVERROR_EXTERNAL;
991  }
992 
993  dec->dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
994  ctx->common.layered_dpb = !dec->dedicated_dpb ? 0 :
995  !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
996 
997  if (dec->dedicated_dpb) {
998  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
999  } else {
1000  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1001  VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
1002  VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1003  VK_IMAGE_USAGE_SAMPLED_BIT;
1004 
1005  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
1007  fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1008  }
1009 
1010  /* Get the format of the images necessary */
1011  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1012  &fmt_info,
1013  &nb_out_fmts, NULL);
1014  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1015  (!nb_out_fmts && ret == VK_SUCCESS)) {
1016  return AVERROR(EINVAL);
1017  } else if (ret != VK_SUCCESS) {
1018  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1019  ff_vk_ret2str(ret));
1020  return AVERROR_EXTERNAL;
1021  }
1022 
1023  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
1024  if (!ret_info)
1025  return AVERROR(ENOMEM);
1026 
1027  for (int i = 0; i < nb_out_fmts; i++)
1028  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1029 
1030  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->phys_dev,
1031  &fmt_info,
1032  &nb_out_fmts, ret_info);
1033  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1034  (!nb_out_fmts && ret == VK_SUCCESS)) {
1035  av_free(ret_info);
1036  return AVERROR(EINVAL);
1037  } else if (ret != VK_SUCCESS) {
1038  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1039  ff_vk_ret2str(ret));
1040  av_free(ret_info);
1041  return AVERROR_EXTERNAL;
1042  }
1043 
1044  /* Find a format to use */
1045  *pix_fmt = best_format = AV_PIX_FMT_NONE;
1046  *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
1047  source_format = avctx->sw_pix_fmt;
1048 
1049  av_log(avctx, AV_LOG_DEBUG, "Choosing best pixel format for decoding from %i:\n", nb_out_fmts);
1050  for (int i = 0; i < nb_out_fmts; i++) {
1052  if (tmp == AV_PIX_FMT_NONE) {
1053  av_log(avctx, AV_LOG_WARNING, "Invalid/unknown Vulkan format %i!\n", ret_info[i].format);
1054  continue;
1055  }
1056 
1057  best_format = av_find_best_pix_fmt_of_2(tmp, best_format, source_format, 0, NULL);
1058  if (tmp == best_format)
1059  best_vkfmt = ret_info[i].format;
1060 
1061  av_log(avctx, AV_LOG_DEBUG, " %s%s (Vulkan ID: %i)\n",
1062  av_get_pix_fmt_name(tmp), tmp == best_format ? "*" : "",
1063  ret_info[i].format);
1064  }
1065 
1066  av_free(ret_info);
1067 
1068  if (best_format == AV_PIX_FMT_NONE) {
1069  av_log(avctx, AV_LOG_ERROR, "No valid/compatible pixel format found for decoding!\n");
1070  return AVERROR(EINVAL);
1071  } else {
1072  av_log(avctx, AV_LOG_VERBOSE, "Chosen frame pixfmt: %s (Vulkan ID: %i)\n",
1073  av_get_pix_fmt_name(best_format), best_vkfmt);
1074  }
1075 
1076  *pix_fmt = best_format;
1077  *vk_fmt = best_vkfmt;
1078 
1079  *dpb_dedicate = dec->dedicated_dpb;
1080 
1081  return 0;
1082 }
1083 
1085 {
1086  av_free(hwfc->user_opaque);
1087 }
1088 
1089 int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
1090 {
1091  VkFormat vkfmt = VK_FORMAT_UNDEFINED;
1092  int err, dedicated_dpb;
1093  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
1094  AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
1097 
1098  err = vulkan_decode_bootstrap(avctx, hw_frames_ctx);
1099  if (err < 0)
1100  return err;
1101 
1102  frames_ctx->sw_format = avctx->sw_pix_fmt;
1103 
1104  if (!DECODER_IS_SDR(avctx->codec_id)) {
1105  prof = av_mallocz(sizeof(FFVulkanDecodeProfileData));
1106  if (!prof)
1107  return AVERROR(ENOMEM);
1108 
1109  err = vulkan_decode_get_profile(avctx, hw_frames_ctx,
1110  &frames_ctx->sw_format, &vkfmt,
1111  prof, &dedicated_dpb);
1112  if (err < 0) {
1113  av_free(prof);
1114  return err;
1115  }
1116 
1117  frames_ctx->user_opaque = prof;
1118  frames_ctx->free = free_profile_data;
1119 
1120  hwfc->create_pnext = &prof->profile_list;
1121  } else {
1122  switch (frames_ctx->sw_format) {
1123  case AV_PIX_FMT_GBRAP16:
1124  /* This should be more efficient for downloading and using */
1125  frames_ctx->sw_format = AV_PIX_FMT_RGBA64;
1126  break;
1127  case AV_PIX_FMT_RGB48LE:
1128  case AV_PIX_FMT_RGB48BE: /* DPX outputs RGB48BE, so we need both */
1129  /* Almost nothing supports native 3-component RGB */
1130  frames_ctx->sw_format = AV_PIX_FMT_GBRP16;
1131  break;
1132  case AV_PIX_FMT_RGBA64BE: /* DPX again, fix for little-endian systems */
1133  frames_ctx->sw_format = AV_PIX_FMT_RGBA64;
1134  break;
1135  case AV_PIX_FMT_GBRP10:
1136  /* This saves memory bandwidth when downloading */
1137  frames_ctx->sw_format = AV_PIX_FMT_X2BGR10;
1138  break;
1139  case AV_PIX_FMT_RGB24:
1140  case AV_PIX_FMT_BGR0:
1141  /* mpv has issues with bgr0 mapping, so just remap it */
1142  frames_ctx->sw_format = AV_PIX_FMT_RGB0;
1143  break;
1144  default:
1145  break;
1146  }
1147  }
1148 
1149  const AVPixFmtDescriptor *pdesc = av_pix_fmt_desc_get(frames_ctx->sw_format);
1150  frames_ctx->width = FFALIGN(avctx->coded_width, 1 << pdesc->log2_chroma_w);
1151  frames_ctx->height = FFALIGN(avctx->coded_height, 1 << pdesc->log2_chroma_h);
1152  frames_ctx->format = AV_PIX_FMT_VULKAN;
1153 
1154  hwfc->format[0] = vkfmt;
1155  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1156  hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1157  VK_IMAGE_USAGE_STORAGE_BIT |
1158  VK_IMAGE_USAGE_SAMPLED_BIT;
1159 
1160  if (prof) {
1162 
1163  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1164  if (!dec->dedicated_dpb)
1165  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1166 
1167  ctx = dec->shared_ctx;
1168  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
1170  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1171  }
1172 
1173  return err;
1174 }
1175 
1176 static void vk_decode_free_params(void *opaque, uint8_t *data)
1177 {
1178  FFVulkanDecodeShared *ctx = opaque;
1179  FFVulkanFunctions *vk = &ctx->s.vkfn;
1180  VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)data;
1181  vk->DestroyVideoSessionParametersKHR(ctx->s.hwctx->act_dev, *par,
1182  ctx->s.hwctx->alloc);
1183  av_free(par);
1184 }
1185 
1187  const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1188 {
1189  VkVideoSessionParametersKHR *par = av_malloc(sizeof(*par));
1190  const FFVulkanFunctions *vk = &ctx->s.vkfn;
1191  VkResult ret;
1192 
1193  if (!par)
1194  return AVERROR(ENOMEM);
1195 
1196  /* Create session parameters */
1197  ret = vk->CreateVideoSessionParametersKHR(ctx->s.hwctx->act_dev, session_params_create,
1198  ctx->s.hwctx->alloc, par);
1199  if (ret != VK_SUCCESS) {
1200  av_log(logctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1201  ff_vk_ret2str(ret));
1202  av_free(par);
1203  return AVERROR_EXTERNAL;
1204  }
1205  *par_ref = av_buffer_create((uint8_t *)par, sizeof(*par),
1207  if (!*par_ref) {
1208  vk_decode_free_params(ctx, (uint8_t *)par);
1209  return AVERROR(ENOMEM);
1210  }
1211 
1212  return 0;
1213 }
1214 
1216 {
1218 
1219  av_freep(&dec->hevc_headers);
1222  av_freep(&dec->slice_off);
1223  return 0;
1224 }
1225 
1228 {
1229  VkResult ret;
1230  FFVulkanContext *s = &ctx->s;
1231  FFVulkanFunctions *vk = &s->vkfn;
1232 
1233  VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
1234  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
1235  };
1236  VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
1237  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1238  };
1239  StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
1240  VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
1241  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
1242  .pStdSequenceHeader = &av1_empty_seq,
1243  };
1244  VkVideoSessionParametersCreateInfoKHR session_params_create = {
1245  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1246  .pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
1247  avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
1248  avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
1249  NULL,
1250  .videoSession = ctx->common.session,
1251  };
1252 
1253  if (avctx->codec_id == AV_CODEC_ID_VP9)
1254  return 0;
1255 
1256  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1257  s->hwctx->alloc, &ctx->empty_session_params);
1258  if (ret != VK_SUCCESS) {
1259  av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
1260  ff_vk_ret2str(ret));
1261  return AVERROR_EXTERNAL;
1262  }
1263 
1264  return 0;
1265 }
1266 
1268 {
1269  int err;
1272  FFVulkanContext *s;
1273  int async_depth;
1274  const VkVideoProfileInfoKHR *profile;
1275  const FFVulkanDecodeDescriptor *vk_desc;
1276  const VkPhysicalDeviceDriverProperties *driver_props;
1277 
1278  VkVideoSessionCreateInfoKHR session_create = {
1279  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1280  };
1281 
1283  if (err < 0)
1284  return err;
1285 
1286  /* Initialize contexts */
1287  ctx = dec->shared_ctx;
1288  s = &ctx->s;
1289 
1290  err = ff_vk_init(s, avctx, NULL, avctx->hw_frames_ctx);
1291  if (err < 0)
1292  return err;
1293 
1294  vk_desc = get_codecdesc(avctx->codec_id);
1295 
1297  if ((vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) && !profile) {
1298  av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
1299  return AVERROR(EINVAL);
1300  }
1301 
1302  /* Create queue context */
1303  vk_desc = get_codecdesc(avctx->codec_id);
1304  ctx->qf = ff_vk_qf_find(s, vk_desc->queue_flags, vk_desc->decode_op);
1305  if (!ctx->qf) {
1306  av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
1307  avcodec_get_name(avctx->codec_id));
1308  return err;
1309  }
1310 
1311  session_create.queueFamilyIndex = ctx->qf->idx;
1312  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1313  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1314  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1315  session_create.pictureFormat = s->hwfc->format[0];
1316  session_create.referencePictureFormat = session_create.pictureFormat;
1317  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1318  session_create.pVideoProfile = profile;
1319 #ifdef VK_KHR_video_maintenance2
1320  if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)
1321  session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1322 #endif
1323 
1324  /* Create decode exec context for this specific main thread.
1325  * 2 async contexts per thread was experimentally determined to be optimal
1326  * for a majority of streams. */
1327  async_depth = 2*ctx->qf->num;
1328  /* We don't need more than 2 per thread context */
1329  async_depth = FFMIN(async_depth, 2*avctx->thread_count);
1330  /* Make sure there are enough async contexts for each thread */
1331  async_depth = FFMAX(async_depth, avctx->thread_count);
1332 
1333  err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
1334  async_depth, 0, 0, 0, profile);
1335  if (err < 0)
1336  goto fail;
1337 
1338  if (!DECODER_IS_SDR(avctx->codec_id)) {
1339  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1340  if (err < 0)
1341  goto fail;
1342  }
1343 
1344  /* If doing an out-of-place decoding, create a DPB pool */
1345  if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) {
1347  AVVulkanFramesContext *dpb_hwfc;
1348 
1349  ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref);
1350  if (!ctx->common.dpb_hwfc_ref) {
1351  err = AVERROR(ENOMEM);
1352  goto fail;
1353  }
1354 
1355  dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
1356  dpb_frames->format = s->frames->format;
1357  dpb_frames->sw_format = s->frames->sw_format;
1358  dpb_frames->width = s->frames->width;
1359  dpb_frames->height = s->frames->height;
1360 
1361  dpb_hwfc = dpb_frames->hwctx;
1362  dpb_hwfc->create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1363  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1364  dpb_hwfc->format[0] = s->hwfc->format[0];
1365  dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1366  dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1367  VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */
1368 
1369  if (ctx->common.layered_dpb)
1370  dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
1371 
1372  err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref);
1373  if (err < 0)
1374  goto fail;
1375 
1376  if (ctx->common.layered_dpb) {
1377  ctx->common.layered_frame = vk_get_dpb_pool(ctx);
1378  if (!ctx->common.layered_frame) {
1379  err = AVERROR(ENOMEM);
1380  goto fail;
1381  }
1382 
1383  err = ff_vk_create_view(&ctx->s, &ctx->common,
1384  &ctx->common.layered_view,
1385  &ctx->common.layered_aspect,
1386  (AVVkFrame *)ctx->common.layered_frame->data[0],
1387  s->hwfc->format[0], 1);
1388  if (err < 0)
1389  goto fail;
1390  }
1391  }
1392 
1393  if (!DECODER_IS_SDR(avctx->codec_id)) {
1394  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
1395  err = create_empty_session_parameters(avctx, ctx);
1396  if (err < 0)
1397  return err;
1398  }
1399  } else {
1400  /* For SDR decoders, this alignment value will be 0. Since this will make
1401  * add_slice() malfunction, set it to a sane default value. */
1402  ctx->caps.minBitstreamBufferSizeAlignment = AV_INPUT_BUFFER_PADDING_SIZE;
1403  }
1404 
1405  driver_props = &dec->shared_ctx->s.driver_props;
1406  if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1407  driver_props->conformanceVersion.major == 1 &&
1408  driver_props->conformanceVersion.minor == 3 &&
1409  driver_props->conformanceVersion.subminor == 8 &&
1410  driver_props->conformanceVersion.patch < 3)
1411  dec->quirk_av1_offset = 1;
1412 
1413  ff_vk_decode_flush(avctx);
1414 
1415  av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization successful\n");
1416 
1417  return 0;
1418 
1419 fail:
1420  ff_vk_decode_uninit(avctx);
1421 
1422  return err;
1423 }
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:102
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:247
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:57
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:356
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:58
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:107
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:859
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:682
AVVulkanFramesContext::create_pnext
void * create_pnext
Extension data for image creation.
Definition: hwcontext_vulkan.h:239
ff_vk_find_struct
static const void * ff_vk_find_struct(const void *chain, VkStructureType stype)
Definition: vulkan.h:332
b
#define b
Definition: input.c:42
create_empty_session_parameters
static int create_empty_session_parameters(AVCodecContext *avctx, FFVulkanDecodeShared *ctx)
Definition: vulkan_decode.c:1226
data
const char data[16]
Definition: mxf.c:149
ff_vk_create_view
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common, VkImageView *view, VkImageAspectFlags *aspect, AVVkFrame *src, VkFormat vkf, int is_dpb)
Creates image views for video frames.
Definition: vulkan_video.c:291
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:3014
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:547
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:3002
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:81
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
FFVulkanDecodeContext
Definition: vulkan_decode.h:56
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:779
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:1993
FFVkShaderRepFormat
FFVkShaderRepFormat
Returns the format to use for images in shaders.
Definition: vulkan.h:404
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AV_HWDEVICE_TYPE_VULKAN
@ AV_HWDEVICE_TYPE_VULKAN
Definition: hwcontext.h:39
FFVulkanDecodeContext::session_params
AVBufferRef * session_params
Definition: vulkan_decode.h:58
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_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:303
FFVulkanDecodeDescriptor::decode_op
VkVideoCodecOperationFlagBitsKHR decode_op
Definition: vulkan_decode.h:33
fail
#define fail()
Definition: checkasm.h:208
FFVulkanDecodePicture::sem_value
uint64_t sem_value
Definition: vulkan_decode.h:87
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1561
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:208
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:488
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:607
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:411
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:807
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
FFVulkanDecodeContext::slice_off
uint32_t * slice_off
Definition: vulkan_decode.h:71
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:105
s
#define s(width, name)
Definition: cbs_vp9.c:198
FFVulkanDecodePicture
Definition: vulkan_decode.h:75
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:1186
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:878
offsets
static const int offsets[]
Definition: hevc_pel.c:34
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@326 view
FFVulkanContext::driver_props
VkPhysicalDeviceDriverProperties driver_props
Definition: vulkan.h:282
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1415
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:122
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_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_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:619
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:287
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:1047
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:441
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:113
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:617
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:335
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:66
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:466
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:2013
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:1215
AVVulkanFramesContext::format
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
Definition: hwcontext_vulkan.h:269
FFVkBuffer::size
size_t size
Definition: vulkan.h:91
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:228
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:82
FFVulkanDecodePicture::aspect_ref
VkImageAspectFlags aspect_ref[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:83
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:100
FFVulkanContext
Definition: vulkan.h:274
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:1089
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1628
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
usage
const char * usage
Definition: floatimg_cmp.c:62
ff_vk_create_imageview
int ff_vk_create_imageview(FFVulkanContext *s, VkImageView *img_view, VkImageAspectFlags *aspect, AVFrame *f, int plane, enum FFVkShaderRepFormat rep_fmt)
Create a single imageview for a given plane.
Definition: vulkan.c:1916
AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_X2BGR10
Definition: pixfmt.h:614
free_common
static void free_common(AVRefStructOpaque unused, void *obj)
Definition: vulkan_decode.c:650
FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
Definition: vulkan_functions.h:57
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:298
FFVulkanDecodePicture::ref
VkImageView ref[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:79
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
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:72
AVVkFrame::queue_family
uint32_t queue_family[AV_NUM_DATA_POINTERS]
Queue family of the images.
Definition: hwcontext_vulkan.h:362
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
FFVkExecContext
Definition: vulkan.h:111
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:1176
FFVulkanDecodeProfileData
Definition: vulkan_decode.c:85
FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
Definition: vulkan_functions.h:60
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::out
VkImageView out[AV_NUM_DATA_POINTERS]
Definition: vulkan_decode.h:80
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:559
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:1484
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:86
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
FFVulkanDecodeContext::external_fg
int external_fg
Definition: vulkan_decode.h:61
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:1453
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
ff_vk_decode_flush
void ff_vk_decode_flush(AVCodecContext *avctx)
Flush decoder.
Definition: vulkan_decode.c:375
ret
ret
Definition: filter_design.txt:187
ff_vk_dec_prores_desc
const FFVulkanDecodeDescriptor ff_vk_dec_prores_desc
Definition: vulkan_prores.c:32
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:294
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:68
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:274
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
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:32
get_codecdesc
static const FFVulkanDecodeDescriptor * get_codecdesc(enum AVCodecID codec_id)
Definition: vulkan_decode.c:98
AVCodecContext
main external API structure.
Definition: avcodec.h:431
FFVulkanDecodeContext::dedicated_dpb
int dedicated_dpb
Definition: vulkan_decode.h:60
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
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1618
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:1774
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:76
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:217
vulkan_video.h
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:607
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:112
AVVulkanFramesContext::nb_layers
int nb_layers
Number of layers each image will have.
Definition: hwcontext_vulkan.h:274
FFVulkanDecodePicture::slices_buf
AVBufferRef * slices_buf
Definition: vulkan_decode.h:101
mem.h
AVVkFrame::layout
VkImageLayout layout[AV_NUM_DATA_POINTERS]
Definition: hwcontext_vulkan.h:328
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:719
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:904
FFVulkanDecodePicture::destroy_image_view
PFN_vkDestroyImageView destroy_image_view
Definition: vulkan_decode.h:106
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:678
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:1267
FFVulkanDecodePicture::decode_info
VkVideoDecodeInfoKHR decode_info
Definition: vulkan_decode.h:98
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:638
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:277
FFVulkanDecodeContext::quirk_av1_offset
int quirk_av1_offset
Definition: vulkan_decode.h:65
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:1285
src
#define src
Definition: vp8dsp.c:248
free_profile_data
static void free_profile_data(AVHWFramesContext *hwfc)
Definition: vulkan_decode.c:1084
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