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