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  /* Vulkan's formats are all LSB-padded */
1117  case AV_PIX_FMT_GRAY10: frames_ctx->sw_format = AV_PIX_FMT_GRAY10MSB; break;
1118  case AV_PIX_FMT_GRAY12: frames_ctx->sw_format = AV_PIX_FMT_GRAY12MSB; break;
1119  case AV_PIX_FMT_GBRP12: frames_ctx->sw_format = AV_PIX_FMT_GBRP12MSB; break;
1120  case AV_PIX_FMT_YUV420P10: frames_ctx->sw_format = AV_PIX_FMT_YUV420P10MSB; break;
1121  case AV_PIX_FMT_YUV420P12: frames_ctx->sw_format = AV_PIX_FMT_YUV420P12MSB; break;
1122  case AV_PIX_FMT_YUV422P10: frames_ctx->sw_format = AV_PIX_FMT_YUV422P10MSB; break;
1123  case AV_PIX_FMT_YUV422P12: frames_ctx->sw_format = AV_PIX_FMT_YUV422P12MSB; break;
1124  case AV_PIX_FMT_YUV444P10: frames_ctx->sw_format = AV_PIX_FMT_YUV444P10MSB; break;
1125  case AV_PIX_FMT_YUV444P12: frames_ctx->sw_format = AV_PIX_FMT_YUV444P12MSB; break;
1126  case AV_PIX_FMT_GBRAP16:
1127  /* This should be more efficient for downloading and using */
1128  frames_ctx->sw_format = AV_PIX_FMT_RGBA64;
1129  break;
1130  case AV_PIX_FMT_GBRP10:
1131  /* This saves memory bandwidth when downloading */
1132  frames_ctx->sw_format = AV_PIX_FMT_X2BGR10;
1133  break;
1134  case AV_PIX_FMT_BGR0:
1135  /* mpv has issues with bgr0 mapping, so just remap it */
1136  frames_ctx->sw_format = AV_PIX_FMT_RGB0;
1137  break;
1138  default:
1139  break;
1140  }
1141  }
1142 
1143  const AVPixFmtDescriptor *pdesc = av_pix_fmt_desc_get(frames_ctx->sw_format);
1144  frames_ctx->width = FFALIGN(avctx->coded_width, 1 << pdesc->log2_chroma_w);
1145  frames_ctx->height = FFALIGN(avctx->coded_height, 1 << pdesc->log2_chroma_h);
1146  frames_ctx->format = AV_PIX_FMT_VULKAN;
1147 
1148  hwfc->format[0] = vkfmt;
1149  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1150  hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1151  VK_IMAGE_USAGE_STORAGE_BIT |
1152  VK_IMAGE_USAGE_SAMPLED_BIT;
1153 
1154  if (prof) {
1156 
1157  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1158  if (!dec->dedicated_dpb)
1159  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1160 
1161  ctx = dec->shared_ctx;
1162  if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
1164  hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1165  }
1166 
1167  return err;
1168 }
1169 
1170 static void vk_decode_free_params(void *opaque, uint8_t *data)
1171 {
1172  FFVulkanDecodeShared *ctx = opaque;
1173  FFVulkanFunctions *vk = &ctx->s.vkfn;
1174  VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)data;
1175  vk->DestroyVideoSessionParametersKHR(ctx->s.hwctx->act_dev, *par,
1176  ctx->s.hwctx->alloc);
1177  av_free(par);
1178 }
1179 
1181  const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1182 {
1183  VkVideoSessionParametersKHR *par = av_malloc(sizeof(*par));
1184  const FFVulkanFunctions *vk = &ctx->s.vkfn;
1185  VkResult ret;
1186 
1187  if (!par)
1188  return AVERROR(ENOMEM);
1189 
1190  /* Create session parameters */
1191  ret = vk->CreateVideoSessionParametersKHR(ctx->s.hwctx->act_dev, session_params_create,
1192  ctx->s.hwctx->alloc, par);
1193  if (ret != VK_SUCCESS) {
1194  av_log(logctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1195  ff_vk_ret2str(ret));
1196  av_free(par);
1197  return AVERROR_EXTERNAL;
1198  }
1199  *par_ref = av_buffer_create((uint8_t *)par, sizeof(*par),
1201  if (!*par_ref) {
1202  vk_decode_free_params(ctx, (uint8_t *)par);
1203  return AVERROR(ENOMEM);
1204  }
1205 
1206  return 0;
1207 }
1208 
1210 {
1212 
1213  av_freep(&dec->hevc_headers);
1216  av_freep(&dec->slice_off);
1217  return 0;
1218 }
1219 
1222 {
1223  VkResult ret;
1224  FFVulkanContext *s = &ctx->s;
1225  FFVulkanFunctions *vk = &s->vkfn;
1226 
1227  VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
1228  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
1229  };
1230  VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
1231  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1232  };
1233  StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
1234  VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
1235  .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
1236  .pStdSequenceHeader = &av1_empty_seq,
1237  };
1238  VkVideoSessionParametersCreateInfoKHR session_params_create = {
1239  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1240  .pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
1241  avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
1242  avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
1243  NULL,
1244  .videoSession = ctx->common.session,
1245  };
1246 
1247  if (avctx->codec_id == AV_CODEC_ID_VP9)
1248  return 0;
1249 
1250  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1251  s->hwctx->alloc, &ctx->empty_session_params);
1252  if (ret != VK_SUCCESS) {
1253  av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
1254  ff_vk_ret2str(ret));
1255  return AVERROR_EXTERNAL;
1256  }
1257 
1258  return 0;
1259 }
1260 
1262 {
1263  int err;
1266  FFVulkanContext *s;
1267  int async_depth;
1268  const VkVideoProfileInfoKHR *profile;
1269  const FFVulkanDecodeDescriptor *vk_desc;
1270  const VkPhysicalDeviceDriverProperties *driver_props;
1271 
1272  VkVideoSessionCreateInfoKHR session_create = {
1273  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1274  };
1275 
1277  if (err < 0)
1278  return err;
1279 
1280  /* Initialize contexts */
1281  ctx = dec->shared_ctx;
1282  s = &ctx->s;
1283 
1284  err = ff_vk_init(s, avctx, NULL, avctx->hw_frames_ctx);
1285  if (err < 0)
1286  return err;
1287 
1288  vk_desc = get_codecdesc(avctx->codec_id);
1289 
1291  if ((vk_desc->queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) && !profile) {
1292  av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
1293  return AVERROR(EINVAL);
1294  }
1295 
1296  /* Create queue context */
1297  vk_desc = get_codecdesc(avctx->codec_id);
1298  ctx->qf = ff_vk_qf_find(s, vk_desc->queue_flags, vk_desc->decode_op);
1299  if (!ctx->qf) {
1300  av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
1301  avcodec_get_name(avctx->codec_id));
1302  return err;
1303  }
1304 
1305  session_create.queueFamilyIndex = ctx->qf->idx;
1306  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1307  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1308  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1309  session_create.pictureFormat = s->hwfc->format[0];
1310  session_create.referencePictureFormat = session_create.pictureFormat;
1311  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1312  session_create.pVideoProfile = profile;
1313 #ifdef VK_KHR_video_maintenance2
1314  if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)
1315  session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1316 #endif
1317 
1318  /* Create decode exec context for this specific main thread.
1319  * 2 async contexts per thread was experimentally determined to be optimal
1320  * for a majority of streams. */
1321  async_depth = 2*ctx->qf->num;
1322  /* We don't need more than 2 per thread context */
1323  async_depth = FFMIN(async_depth, 2*avctx->thread_count);
1324  /* Make sure there are enough async contexts for each thread */
1325  async_depth = FFMAX(async_depth, avctx->thread_count);
1326 
1327  err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
1328  async_depth, 0, 0, 0, profile);
1329  if (err < 0)
1330  goto fail;
1331 
1332  if (!DECODER_IS_SDR(avctx->codec_id)) {
1333  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1334  if (err < 0)
1335  goto fail;
1336  }
1337 
1338  /* If doing an out-of-place decoding, create a DPB pool */
1339  if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) {
1341  AVVulkanFramesContext *dpb_hwfc;
1342 
1343  ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref);
1344  if (!ctx->common.dpb_hwfc_ref) {
1345  err = AVERROR(ENOMEM);
1346  goto fail;
1347  }
1348 
1349  dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data;
1350  dpb_frames->format = s->frames->format;
1351  dpb_frames->sw_format = s->frames->sw_format;
1352  dpb_frames->width = s->frames->width;
1353  dpb_frames->height = s->frames->height;
1354 
1355  dpb_hwfc = dpb_frames->hwctx;
1356  dpb_hwfc->create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
1357  VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1358  dpb_hwfc->format[0] = s->hwfc->format[0];
1359  dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1360  dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1361  VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */
1362 
1363  if (ctx->common.layered_dpb)
1364  dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
1365 
1366  err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref);
1367  if (err < 0)
1368  goto fail;
1369 
1370  if (ctx->common.layered_dpb) {
1371  ctx->common.layered_frame = vk_get_dpb_pool(ctx);
1372  if (!ctx->common.layered_frame) {
1373  err = AVERROR(ENOMEM);
1374  goto fail;
1375  }
1376 
1377  err = ff_vk_create_view(&ctx->s, &ctx->common,
1378  &ctx->common.layered_view,
1379  &ctx->common.layered_aspect,
1380  (AVVkFrame *)ctx->common.layered_frame->data[0],
1381  s->hwfc->format[0], 1);
1382  if (err < 0)
1383  goto fail;
1384  }
1385  }
1386 
1387  if (!DECODER_IS_SDR(avctx->codec_id)) {
1388  if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
1389  err = create_empty_session_parameters(avctx, ctx);
1390  if (err < 0)
1391  return err;
1392  }
1393  } else {
1394  /* For SDR decoders, this alignment value will be 0. Since this will make
1395  * add_slice() malfunction, set it to a sane default value. */
1396  ctx->caps.minBitstreamBufferSizeAlignment = AV_INPUT_BUFFER_PADDING_SIZE;
1397  }
1398 
1399  driver_props = &dec->shared_ctx->s.driver_props;
1400  if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1401  driver_props->conformanceVersion.major == 1 &&
1402  driver_props->conformanceVersion.minor == 3 &&
1403  driver_props->conformanceVersion.subminor == 8 &&
1404  driver_props->conformanceVersion.patch < 3)
1405  dec->quirk_av1_offset = 1;
1406 
1407  ff_vk_decode_flush(avctx);
1408 
1409  av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization successful\n");
1410 
1411  return 0;
1412 
1413 fail:
1414  ff_vk_decode_uninit(avctx);
1415 
1416  return err;
1417 }
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:584
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:3594
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_PIX_FMT_YUV444P10MSB
#define AV_PIX_FMT_YUV444P10MSB
Definition: pixfmt.h:573
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:130
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
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:1220
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:293
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:552
FFVulkanDecodePicture::view
struct FFVulkanDecodePicture::@324 view
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:2968
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:2956
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
AV_PIX_FMT_YUV444P12MSB
#define AV_PIX_FMT_YUV444P12MSB
Definition: pixfmt.h:574
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:117
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3634
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
AV_PIX_FMT_GBRP12MSB
#define AV_PIX_FMT_GBRP12MSB
Definition: pixfmt.h:588
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:577
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
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:555
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:367
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:1180
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
AV_PIX_FMT_GRAY10MSB
#define AV_PIX_FMT_GRAY10MSB
Definition: pixfmt.h:567
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
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
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:532
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
AV_PIX_FMT_YUV422P10MSB
#define AV_PIX_FMT_YUV422P10MSB
Definition: pixfmt.h:571
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:542
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:337
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:66
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:1209
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
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:553
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
AV_PIX_FMT_YUV420P10MSB
#define AV_PIX_FMT_YUV420P10MSB
Definition: pixfmt.h:569
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:1871
AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_X2BGR10
Definition: pixfmt.h:633
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:57
ff_vk_h265_level_to_av
int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
Definition: vulkan_video.c:193
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
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:557
size
int size
Definition: twinvq_data.h:10344
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:428
ref_frame
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
Definition: dec.c:616
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:559
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:1170
FFVulkanDecodeProfileData
Definition: vulkan_decode.c:78
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
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
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:578
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:141
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_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:556
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:3873
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
AV_PIX_FMT_YUV422P12MSB
#define AV_PIX_FMT_YUV422P12MSB
Definition: pixfmt.h:572
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:101
ff_vk_decode_init
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
Definition: vulkan_decode.c:1261
AV_PIX_FMT_YUV420P12MSB
#define AV_PIX_FMT_YUV420P12MSB
Definition: pixfmt.h:570
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_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:533
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: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_PIX_FMT_GRAY12MSB
#define AV_PIX_FMT_GRAY12MSB
Definition: pixfmt.h:568
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:3514