FFmpeg
vulkan_video.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/mem.h"
20 #include "vulkan_video.h"
21 
22 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
23 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
24 
25 static const struct FFVkFormatMapEntry {
28  VkImageAspectFlags aspect;
29 } vk_format_map[] = {
30  /* Gray formats */
31  { VK_FORMAT_R8_UNORM, AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT },
32  { VK_FORMAT_R16_UNORM, AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT },
33  { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT },
34 
35  /* RGB formats */
36  { VK_FORMAT_R16G16B16A16_UNORM, AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT },
37  { VK_FORMAT_B8G8R8A8_UNORM, AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT },
38  { VK_FORMAT_R8G8B8A8_UNORM, AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT },
39  { VK_FORMAT_R8G8B8_UNORM, AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT },
40  { VK_FORMAT_B8G8R8_UNORM, AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT },
41  { VK_FORMAT_R16G16B16_UNORM, AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT },
42  { VK_FORMAT_R16G16B16A16_UNORM, AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT },
43  { VK_FORMAT_R5G6B5_UNORM_PACK16, AV_PIX_FMT_RGB565, VK_IMAGE_ASPECT_COLOR_BIT },
44  { VK_FORMAT_B5G6R5_UNORM_PACK16, AV_PIX_FMT_BGR565, VK_IMAGE_ASPECT_COLOR_BIT },
45  { VK_FORMAT_B8G8R8A8_UNORM, AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT },
46  { VK_FORMAT_R8G8B8A8_UNORM, AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT },
47  { VK_FORMAT_A2R10G10B10_UNORM_PACK32, AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT },
48 
49  /* Planar RGB */
50  { VK_FORMAT_R8_UNORM, AV_PIX_FMT_GBRAP, VK_IMAGE_ASPECT_COLOR_BIT },
51  { VK_FORMAT_R16_UNORM, AV_PIX_FMT_GBRAP16, VK_IMAGE_ASPECT_COLOR_BIT },
52  { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRPF32, VK_IMAGE_ASPECT_COLOR_BIT },
53  { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRAPF32, VK_IMAGE_ASPECT_COLOR_BIT },
54 
55  /* Two-plane 420 YUV at 8, 10, 12 and 16 bits */
56  { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, AV_PIX_FMT_NV12, ASPECT_2PLANE },
57  { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, AV_PIX_FMT_P010, ASPECT_2PLANE },
58  { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, AV_PIX_FMT_P012, ASPECT_2PLANE },
59  { VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, AV_PIX_FMT_P016, ASPECT_2PLANE },
60 
61  /* Two-plane 422 YUV at 8, 10 and 16 bits */
62  { VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, AV_PIX_FMT_NV16, ASPECT_2PLANE },
63  { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, AV_PIX_FMT_P210, ASPECT_2PLANE },
64  { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, AV_PIX_FMT_P212, ASPECT_2PLANE },
65  { VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, AV_PIX_FMT_P216, ASPECT_2PLANE },
66 
67  /* Two-plane 444 YUV at 8, 10 and 16 bits */
68  { VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, AV_PIX_FMT_NV24, ASPECT_2PLANE },
69  { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, AV_PIX_FMT_P410, ASPECT_2PLANE },
70  { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, AV_PIX_FMT_P412, ASPECT_2PLANE },
71  { VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, AV_PIX_FMT_P416, ASPECT_2PLANE },
72 
73  /* Three-plane 420, 422, 444 at 8, 10, 12 and 16 bits */
74  { VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P, ASPECT_3PLANE },
75  { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P10, ASPECT_3PLANE },
76  { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P12, ASPECT_3PLANE },
77  { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P16, ASPECT_3PLANE },
78  { VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P, ASPECT_3PLANE },
79  { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P10, ASPECT_3PLANE },
80  { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P12, ASPECT_3PLANE },
81  { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P16, ASPECT_3PLANE },
82  { VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P, ASPECT_3PLANE },
83  { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P10, ASPECT_3PLANE },
84  { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P12, ASPECT_3PLANE },
85  { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P16, ASPECT_3PLANE },
86 
87  /* Single plane 422 at 8, 10 and 12 bits */
88  { VK_FORMAT_G8B8G8R8_422_UNORM, AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT },
89  { VK_FORMAT_B8G8R8G8_422_UNORM, AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT },
90  { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT },
91  { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT },
92 };
94 
96 {
97  for (int i = 0; i < nb_vk_format_map; i++)
98  if (vk_format_map[i].vkf == vkf)
99  return vk_format_map[i].pixfmt;
100  return AV_PIX_FMT_NONE;
101 }
102 
103 VkImageAspectFlags ff_vk_aspect_bits_from_vkfmt(VkFormat vkf)
104 {
105  for (int i = 0; i < nb_vk_format_map; i++)
106  if (vk_format_map[i].vkf == vkf)
107  return vk_format_map[i].aspect;
108  return VK_IMAGE_ASPECT_NONE;
109 }
110 
111 VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFmtDescriptor *desc)
112 {
113  if (desc->nb_components == 1)
114  return VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR;
115  else if (!desc->log2_chroma_w && !desc->log2_chroma_h)
116  return VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR;
117  else if (!desc->log2_chroma_w && desc->log2_chroma_h == 1)
118  return VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR;
119  else if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1)
120  return VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR;
121  return VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR;
122 }
123 
124 VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth)
125 {
126  switch (depth) {
127  case 8: return VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR;
128  case 10: return VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR;
129  case 12: return VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR;
130  default: break;
131  }
132  return VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR;
133 }
134 
135 int ff_vk_h264_level_to_av(StdVideoH264LevelIdc level)
136 {
137  switch (level) {
138  case STD_VIDEO_H264_LEVEL_IDC_1_0: return 10;
139  case STD_VIDEO_H264_LEVEL_IDC_1_1: return 11;
140  case STD_VIDEO_H264_LEVEL_IDC_1_2: return 12;
141  case STD_VIDEO_H264_LEVEL_IDC_1_3: return 13;
142  case STD_VIDEO_H264_LEVEL_IDC_2_0: return 20;
143  case STD_VIDEO_H264_LEVEL_IDC_2_1: return 21;
144  case STD_VIDEO_H264_LEVEL_IDC_2_2: return 22;
145  case STD_VIDEO_H264_LEVEL_IDC_3_0: return 30;
146  case STD_VIDEO_H264_LEVEL_IDC_3_1: return 31;
147  case STD_VIDEO_H264_LEVEL_IDC_3_2: return 32;
148  case STD_VIDEO_H264_LEVEL_IDC_4_0: return 40;
149  case STD_VIDEO_H264_LEVEL_IDC_4_1: return 41;
150  case STD_VIDEO_H264_LEVEL_IDC_4_2: return 42;
151  case STD_VIDEO_H264_LEVEL_IDC_5_0: return 50;
152  case STD_VIDEO_H264_LEVEL_IDC_5_1: return 51;
153  case STD_VIDEO_H264_LEVEL_IDC_5_2: return 52;
154  case STD_VIDEO_H264_LEVEL_IDC_6_0: return 60;
155  case STD_VIDEO_H264_LEVEL_IDC_6_1: return 61;
156  default:
157  case STD_VIDEO_H264_LEVEL_IDC_6_2: return 62;
158  }
159 }
160 
161 StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc)
162 {
163  switch (level_idc) {
164  case 10: return STD_VIDEO_H264_LEVEL_IDC_1_0;
165  case 11: return STD_VIDEO_H264_LEVEL_IDC_1_1;
166  case 12: return STD_VIDEO_H264_LEVEL_IDC_1_2;
167  case 13: return STD_VIDEO_H264_LEVEL_IDC_1_3;
168  case 20: return STD_VIDEO_H264_LEVEL_IDC_2_0;
169  case 21: return STD_VIDEO_H264_LEVEL_IDC_2_1;
170  case 22: return STD_VIDEO_H264_LEVEL_IDC_2_2;
171  case 30: return STD_VIDEO_H264_LEVEL_IDC_3_0;
172  case 31: return STD_VIDEO_H264_LEVEL_IDC_3_1;
173  case 32: return STD_VIDEO_H264_LEVEL_IDC_3_2;
174  case 40: return STD_VIDEO_H264_LEVEL_IDC_4_0;
175  case 41: return STD_VIDEO_H264_LEVEL_IDC_4_1;
176  case 42: return STD_VIDEO_H264_LEVEL_IDC_4_2;
177  case 50: return STD_VIDEO_H264_LEVEL_IDC_5_0;
178  case 51: return STD_VIDEO_H264_LEVEL_IDC_5_1;
179  case 52: return STD_VIDEO_H264_LEVEL_IDC_5_2;
180  case 60: return STD_VIDEO_H264_LEVEL_IDC_6_0;
181  case 61: return STD_VIDEO_H264_LEVEL_IDC_6_1;
182  default:
183  case 62: return STD_VIDEO_H264_LEVEL_IDC_6_2;
184  }
185 }
186 
187 int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
188 {
189  switch (level) {
190  case STD_VIDEO_H265_LEVEL_IDC_1_0: return 10;
191  case STD_VIDEO_H265_LEVEL_IDC_2_0: return 20;
192  case STD_VIDEO_H265_LEVEL_IDC_2_1: return 21;
193  case STD_VIDEO_H265_LEVEL_IDC_3_0: return 30;
194  case STD_VIDEO_H265_LEVEL_IDC_3_1: return 31;
195  case STD_VIDEO_H265_LEVEL_IDC_4_0: return 40;
196  case STD_VIDEO_H265_LEVEL_IDC_4_1: return 41;
197  case STD_VIDEO_H265_LEVEL_IDC_5_0: return 50;
198  case STD_VIDEO_H265_LEVEL_IDC_5_1: return 51;
199  case STD_VIDEO_H265_LEVEL_IDC_6_0: return 60;
200  case STD_VIDEO_H265_LEVEL_IDC_6_1: return 61;
201  default:
202  case STD_VIDEO_H265_LEVEL_IDC_6_2: return 62;
203  }
204 }
205 
206 StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc)
207 {
208  switch (level_idc) {
209  case 10: return STD_VIDEO_H265_LEVEL_IDC_1_0;
210  case 20: return STD_VIDEO_H265_LEVEL_IDC_2_0;
211  case 21: return STD_VIDEO_H265_LEVEL_IDC_2_1;
212  case 30: return STD_VIDEO_H265_LEVEL_IDC_3_0;
213  case 31: return STD_VIDEO_H265_LEVEL_IDC_3_1;
214  case 40: return STD_VIDEO_H265_LEVEL_IDC_4_0;
215  case 41: return STD_VIDEO_H265_LEVEL_IDC_4_1;
216  case 50: return STD_VIDEO_H265_LEVEL_IDC_5_0;
217  case 51: return STD_VIDEO_H265_LEVEL_IDC_5_1;
218  case 60: return STD_VIDEO_H265_LEVEL_IDC_6_0;
219  case 61: return STD_VIDEO_H265_LEVEL_IDC_6_1;
220  default:
221  case 62: return STD_VIDEO_H265_LEVEL_IDC_6_2;
222  }
223 }
224 
225 StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)
226 {
227  switch (profile) {
228  case AV_PROFILE_H264_CONSTRAINED_BASELINE: return STD_VIDEO_H264_PROFILE_IDC_BASELINE;
229  case AV_PROFILE_H264_MAIN: return STD_VIDEO_H264_PROFILE_IDC_MAIN;
230  case AV_PROFILE_H264_HIGH: return STD_VIDEO_H264_PROFILE_IDC_HIGH;
231  case AV_PROFILE_H264_HIGH_444_PREDICTIVE: return STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE;
232  default: return STD_VIDEO_H264_PROFILE_IDC_INVALID;
233  }
234 }
235 
236 StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile)
237 {
238  switch (profile) {
239  case AV_PROFILE_HEVC_MAIN: return STD_VIDEO_H265_PROFILE_IDC_MAIN;
240  case AV_PROFILE_HEVC_MAIN_10: return STD_VIDEO_H265_PROFILE_IDC_MAIN_10;
241  case AV_PROFILE_HEVC_REXT: return STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS;
242  default: return STD_VIDEO_H265_PROFILE_IDC_INVALID;
243  }
244 }
245 
246 int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile)
247 {
248  switch (profile) {
249  case STD_VIDEO_H264_PROFILE_IDC_BASELINE: return AV_PROFILE_H264_CONSTRAINED_BASELINE;
250  case STD_VIDEO_H264_PROFILE_IDC_MAIN: return AV_PROFILE_H264_MAIN;
251  case STD_VIDEO_H264_PROFILE_IDC_HIGH: return AV_PROFILE_H264_HIGH;
252  case STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE: return AV_PROFILE_H264_HIGH_444_PREDICTIVE;
253  default: return AV_PROFILE_UNKNOWN;
254  }
255 }
256 
257 int ff_vk_h265_profile_to_av(StdVideoH264ProfileIdc profile)
258 {
259  switch (profile) {
260  case STD_VIDEO_H265_PROFILE_IDC_MAIN: return AV_PROFILE_HEVC_MAIN;
261  case STD_VIDEO_H265_PROFILE_IDC_MAIN_10: return AV_PROFILE_HEVC_MAIN_10;
262  case STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS: return AV_PROFILE_HEVC_REXT;
263  default: return AV_PROFILE_UNKNOWN;
264  }
265 }
266 
268  VkQueueFlagBits family, VkVideoCodecOperationFlagBitsKHR caps)
269 {
270  for (int i = 0; i < s->hwctx->nb_qf; i++) {
271  if ((s->hwctx->qf[i].flags & family) &&
272  (s->hwctx->qf[i].video_caps & caps)) {
273  qf->queue_family = s->hwctx->qf[i].idx;
274  qf->nb_queues = s->hwctx->qf[i].num;
275  return 0;
276  }
277  }
278  return AVERROR(ENOTSUP);
279 }
280 
281 int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
282  VkImageView *view, VkImageAspectFlags *aspect,
283  AVVkFrame *src, VkFormat vkf, int is_dpb)
284 {
285  VkResult ret;
286  FFVulkanFunctions *vk = &s->vkfn;
287  VkImageAspectFlags aspect_mask = ff_vk_aspect_bits_from_vkfmt(vkf);
288 
289  VkSamplerYcbcrConversionInfo yuv_sampler_info = {
290  .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
291  .conversion = common->yuv_sampler,
292  };
293  VkImageViewCreateInfo img_view_create_info = {
294  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
295  .pNext = &yuv_sampler_info,
296  .viewType = common->layered_dpb && is_dpb ?
297  VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
298  .format = vkf,
299  .image = src->img[0],
300  .components = (VkComponentMapping) {
301  .r = VK_COMPONENT_SWIZZLE_IDENTITY,
302  .g = VK_COMPONENT_SWIZZLE_IDENTITY,
303  .b = VK_COMPONENT_SWIZZLE_IDENTITY,
304  .a = VK_COMPONENT_SWIZZLE_IDENTITY,
305  },
306  .subresourceRange = (VkImageSubresourceRange) {
307  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
308  .baseArrayLayer = 0,
309  .layerCount = common->layered_dpb && is_dpb ?
310  VK_REMAINING_ARRAY_LAYERS : 1,
311  .levelCount = 1,
312  },
313  };
314 
315  ret = vk->CreateImageView(s->hwctx->act_dev, &img_view_create_info,
316  s->hwctx->alloc, view);
317  if (ret != VK_SUCCESS)
318  return AVERROR_EXTERNAL;
319 
320  *aspect = aspect_mask;
321 
322  return 0;
323 }
324 
326  FFVkVideoCommon *common)
327 {
328  FFVulkanFunctions *vk = &s->vkfn;
329 
330  if (common->session) {
331  vk->DestroyVideoSessionKHR(s->hwctx->act_dev, common->session,
332  s->hwctx->alloc);
333  common->session = VK_NULL_HANDLE;
334  }
335 
336  if (common->nb_mem && common->mem)
337  for (int i = 0; i < common->nb_mem; i++)
338  vk->FreeMemory(s->hwctx->act_dev, common->mem[i], s->hwctx->alloc);
339 
340  av_freep(&common->mem);
341 
342  if (common->layered_view)
343  vk->DestroyImageView(s->hwctx->act_dev, common->layered_view,
344  s->hwctx->alloc);
345 
346  av_frame_free(&common->layered_frame);
347 
348  av_buffer_unref(&common->dpb_hwfc_ref);
349 
350  if (common->yuv_sampler)
351  vk->DestroySamplerYcbcrConversion(s->hwctx->act_dev, common->yuv_sampler,
352  s->hwctx->alloc);
353 }
354 
356  FFVkVideoCommon *common,
357  VkVideoSessionCreateInfoKHR *session_create)
358 {
359  int err;
360  VkResult ret;
361  FFVulkanFunctions *vk = &s->vkfn;
362  VkVideoSessionMemoryRequirementsKHR *mem = NULL;
363  VkBindVideoSessionMemoryInfoKHR *bind_mem = NULL;
364 
365  int cxpos = 0, cypos = 0;
366  VkSamplerYcbcrConversionCreateInfo yuv_sampler_info = {
367  .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
368  .components = ff_comp_identity_map,
369  .ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
370  .ycbcrRange = avctx->color_range == AVCOL_RANGE_MPEG, /* Ignored */
371  .format = session_create->pictureFormat,
372  };
373 
374  /* Create identity YUV sampler
375  * (VkImageViews of YUV image formats require it, even if it does nothing) */
377  yuv_sampler_info.xChromaOffset = cxpos >> 7;
378  yuv_sampler_info.yChromaOffset = cypos >> 7;
379  ret = vk->CreateSamplerYcbcrConversion(s->hwctx->act_dev, &yuv_sampler_info,
380  s->hwctx->alloc, &common->yuv_sampler);
381  if (ret != VK_SUCCESS)
382  return AVERROR_EXTERNAL;
383 
384  /* Create session */
385  ret = vk->CreateVideoSessionKHR(s->hwctx->act_dev, session_create,
386  s->hwctx->alloc, &common->session);
387  if (ret != VK_SUCCESS)
388  return AVERROR_EXTERNAL;
389 
390  /* Get memory requirements */
391  ret = vk->GetVideoSessionMemoryRequirementsKHR(s->hwctx->act_dev,
392  common->session,
393  &common->nb_mem,
394  NULL);
395  if (ret != VK_SUCCESS) {
396  err = AVERROR_EXTERNAL;
397  goto fail;
398  }
399 
400  /* Allocate all memory needed to actually allocate memory */
401  common->mem = av_mallocz(sizeof(*common->mem)*common->nb_mem);
402  if (!common->mem) {
403  err = AVERROR(ENOMEM);
404  goto fail;
405  }
406  mem = av_mallocz(sizeof(*mem)*common->nb_mem);
407  if (!mem) {
408  err = AVERROR(ENOMEM);
409  goto fail;
410  }
411  bind_mem = av_mallocz(sizeof(*bind_mem)*common->nb_mem);
412  if (!bind_mem) {
413  err = AVERROR(ENOMEM);
414  goto fail;
415  }
416 
417  /* Set the needed fields to get the memory requirements */
418  for (int i = 0; i < common->nb_mem; i++) {
419  mem[i] = (VkVideoSessionMemoryRequirementsKHR) {
420  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR,
421  };
422  }
423 
424  /* Finally get the memory requirements */
425  ret = vk->GetVideoSessionMemoryRequirementsKHR(s->hwctx->act_dev,
426  common->session, &common->nb_mem,
427  mem);
428  if (ret != VK_SUCCESS) {
429  err = AVERROR_EXTERNAL;
430  goto fail;
431  }
432 
433  /* Now allocate each requested memory.
434  * For ricing, could pool together memory that ends up in the same index. */
435  for (int i = 0; i < common->nb_mem; i++) {
436  err = ff_vk_alloc_mem(s, &mem[i].memoryRequirements,
437  UINT32_MAX, NULL, NULL, &common->mem[i]);
438  if (err < 0)
439  goto fail;
440 
441  bind_mem[i] = (VkBindVideoSessionMemoryInfoKHR) {
442  .sType = VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR,
443  .memory = common->mem[i],
444  .memoryBindIndex = mem[i].memoryBindIndex,
445  .memoryOffset = 0,
446  .memorySize = mem[i].memoryRequirements.size,
447  };
448 
449  av_log(avctx, AV_LOG_VERBOSE, "Allocating %"PRIu64" bytes in bind index %i for video session\n",
450  bind_mem[i].memorySize, bind_mem[i].memoryBindIndex);
451  }
452 
453  /* Bind the allocated memory */
454  ret = vk->BindVideoSessionMemoryKHR(s->hwctx->act_dev, common->session,
455  common->nb_mem, bind_mem);
456  if (ret != VK_SUCCESS) {
457  err = AVERROR_EXTERNAL;
458  goto fail;
459  }
460 
461  av_freep(&mem);
462  av_freep(&bind_mem);
463 
464  return 0;
465 
466 fail:
467  av_freep(&mem);
468  av_freep(&bind_mem);
469 
470  ff_vk_video_common_uninit(s, common);
471  return err;
472 }
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:501
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
level
uint8_t level
Definition: svq3.c:205
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
ff_comp_identity_map
const VkComponentMapping ff_comp_identity_map
Definition: vulkan.c:27
ff_vk_video_qf_init
int ff_vk_video_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf, VkQueueFlagBits family, VkVideoCodecOperationFlagBitsKHR caps)
Chooses a QF and loads it into a context.
Definition: vulkan_video.c:267
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:112
AV_PROFILE_HEVC_MAIN
#define AV_PROFILE_HEVC_MAIN
Definition: defs.h:159
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
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:124
level_idc
int level_idc
Definition: h264_levels.c:29
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:281
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:478
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
FFVkFormatMapEntry::vkf
VkFormat vkf
Definition: vulkan_video.c:26
AV_PIX_FMT_P212
#define AV_PIX_FMT_P212
Definition: pixfmt.h:541
ff_vk_h264_profile_to_vk
StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)
Convert profile from/to AV to Vulkan.
Definition: vulkan_video.c:225
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:111
ASPECT_3PLANE
#define ASPECT_3PLANE
Definition: vulkan_video.c:23
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:212
fail
#define fail()
Definition: checkasm.h:188
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:462
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:481
AV_PIX_FMT_Y210
#define AV_PIX_FMT_Y210
Definition: pixfmt.h:532
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:490
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:355
av_chroma_location_enum_to_pos
int av_chroma_location_enum_to_pos(int *xpos, int *ypos, enum AVChromaLocation pos)
Converts AVChromaLocation to swscale x/y chroma position.
Definition: pixdesc.c:3383
FFVkFormatMapEntry::pixfmt
enum AVPixelFormat pixfmt
Definition: vulkan_video.c:27
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:491
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:489
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_PIX_FMT_GRAYF32
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:511
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:468
ff_vk_alloc_mem
int ff_vk_alloc_mem(FFVulkanContext *s, VkMemoryRequirements *req, VkMemoryPropertyFlagBits req_flags, void *alloc_extension, VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
Memory/buffer/image allocation helpers.
Definition: vulkan.c:873
NULL
#define NULL
Definition: coverity.c:32
ASPECT_2PLANE
#define ASPECT_2PLANE
Definition: vulkan_video.c:22
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:701
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
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:325
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
ff_vk_h265_profile_to_av
int ff_vk_h265_profile_to_av(StdVideoH264ProfileIdc profile)
Definition: vulkan_video.c:257
AV_PIX_FMT_P410
#define AV_PIX_FMT_P410
Definition: pixfmt.h:540
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:479
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
FFVulkanContext
Definition: vulkan.h:263
AV_PROFILE_HEVC_MAIN_10
#define AV_PROFILE_HEVC_MAIN_10
Definition: defs.h:160
AV_PROFILE_HEVC_REXT
#define AV_PROFILE_HEVC_REXT
Definition: defs.h:162
ff_vk_h264_profile_to_av
int ff_vk_h264_profile_to_av(StdVideoH264ProfileIdc profile)
Definition: vulkan_video.c:246
vk_format_map
static const struct FFVkFormatMapEntry vk_format_map[]
ff_vk_h265_level_to_av
int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
Definition: vulkan_video.c:187
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
AV_PIX_FMT_P012
#define AV_PIX_FMT_P012
Definition: pixfmt.h:529
AVVkFrame
Definition: hwcontext_vulkan.h:302
AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:508
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:483
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:464
FFVkQueueFamilyCtx
Definition: vulkan.h:102
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:485
AV_PIX_FMT_NV16
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:198
ff_vk_h265_level_to_vk
StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc)
Definition: vulkan_video.c:206
ff_vk_h264_level_to_vk
StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc)
Definition: vulkan_video.c:161
AV_PIX_FMT_Y212
#define AV_PIX_FMT_Y212
Definition: pixfmt.h:533
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
AV_PIX_FMT_P216
#define AV_PIX_FMT_P216
Definition: pixfmt.h:543
AV_PIX_FMT_P210
#define AV_PIX_FMT_P210
Definition: pixfmt.h:539
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFVkFormatMapEntry::aspect
VkImageAspectFlags aspect
Definition: vulkan_video.c:28
VkFormat
enum VkFormat VkFormat
Definition: hwcontext_stub.c:25
AV_PIX_FMT_NV24
@ AV_PIX_FMT_NV24
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:371
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:135
AV_PIX_FMT_X2RGB10
#define AV_PIX_FMT_X2RGB10
Definition: pixfmt.h:536
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
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:708
AV_PIX_FMT_BGR565
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:470
profile
int profile
Definition: mxfenc.c:2228
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:669
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:530
AV_PIX_FMT_RGB565
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:465
FFVkFormatMapEntry
Definition: vulkan_video.c:25
AV_PROFILE_H264_HIGH_444_PREDICTIVE
#define AV_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: defs.h:122
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:482
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
FFVkQueueFamilyCtx::nb_queues
int nb_queues
Definition: vulkan.h:104
AVCodecContext
main external API structure.
Definition: avcodec.h:451
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:114
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:509
AV_PROFILE_H264_CONSTRAINED_BASELINE
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition: defs.h:111
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
nb_vk_format_map
static const int nb_vk_format_map
Definition: vulkan_video.c:93
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:528
vulkan_video.h
desc
const char * desc
Definition: libsvtav1.c:79
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
mem.h
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_P416
#define AV_PIX_FMT_P416
Definition: pixfmt.h:544
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AV_PIX_FMT_XV36
#define AV_PIX_FMT_XV36
Definition: pixfmt.h:535
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_PIX_FMT_P412
#define AV_PIX_FMT_P412
Definition: pixfmt.h:542
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:95
ff_vk_aspect_bits_from_vkfmt
VkImageAspectFlags ff_vk_aspect_bits_from_vkfmt(VkFormat vkf)
Get aspect bits which include all planes from a VkFormat.
Definition: vulkan_video.c:103
ff_vk_h265_profile_to_vk
StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile)
Definition: vulkan_video.c:236
FFVulkanFunctions
Definition: vulkan_functions.h:263
src
#define src
Definition: vp8dsp.c:248
FFVkQueueFamilyCtx::queue_family
int queue_family
Definition: vulkan.h:103