Imported Upstream version 6.1
[platform/upstream/ffmpeg.git] / libavcodec / vulkan_video.c
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 "codec_id.h"
20
21 #include "vulkan_video.h"
22
23 const FFVkCodecMap ff_vk_codec_map[AV_CODEC_ID_FIRST_AUDIO] = {
24     [AV_CODEC_ID_H264] = {
25                            0,
26                            0,
27                            FF_VK_EXT_VIDEO_DECODE_H264,
28                            VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR,
29     },
30     [AV_CODEC_ID_HEVC] = {
31                            0,
32                            0,
33                            FF_VK_EXT_VIDEO_DECODE_H265,
34                            VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR
35     },
36     [AV_CODEC_ID_AV1] = {
37                            0,
38                            0,
39                            FF_VK_EXT_VIDEO_DECODE_AV1,
40                            0x01000000 /* TODO fix this */
41     },
42 };
43
44 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
45 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
46
47 static const struct FFVkFormatMapEntry {
48     VkFormat vkf;
49     enum AVPixelFormat pixfmt;
50     VkImageAspectFlags aspect;
51 } vk_format_map[] = {
52     /* Gray formats */
53     { VK_FORMAT_R8_UNORM,   AV_PIX_FMT_GRAY8,   VK_IMAGE_ASPECT_COLOR_BIT },
54     { VK_FORMAT_R16_UNORM,  AV_PIX_FMT_GRAY16,  VK_IMAGE_ASPECT_COLOR_BIT },
55     { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT },
56
57     /* RGB formats */
58     { VK_FORMAT_R16G16B16A16_UNORM,       AV_PIX_FMT_XV36,    VK_IMAGE_ASPECT_COLOR_BIT },
59     { VK_FORMAT_B8G8R8A8_UNORM,           AV_PIX_FMT_BGRA,    VK_IMAGE_ASPECT_COLOR_BIT },
60     { VK_FORMAT_R8G8B8A8_UNORM,           AV_PIX_FMT_RGBA,    VK_IMAGE_ASPECT_COLOR_BIT },
61     { VK_FORMAT_R8G8B8_UNORM,             AV_PIX_FMT_RGB24,   VK_IMAGE_ASPECT_COLOR_BIT },
62     { VK_FORMAT_B8G8R8_UNORM,             AV_PIX_FMT_BGR24,   VK_IMAGE_ASPECT_COLOR_BIT },
63     { VK_FORMAT_R16G16B16_UNORM,          AV_PIX_FMT_RGB48,   VK_IMAGE_ASPECT_COLOR_BIT },
64     { VK_FORMAT_R16G16B16A16_UNORM,       AV_PIX_FMT_RGBA64,  VK_IMAGE_ASPECT_COLOR_BIT },
65     { VK_FORMAT_R5G6B5_UNORM_PACK16,      AV_PIX_FMT_RGB565,  VK_IMAGE_ASPECT_COLOR_BIT },
66     { VK_FORMAT_B5G6R5_UNORM_PACK16,      AV_PIX_FMT_BGR565,  VK_IMAGE_ASPECT_COLOR_BIT },
67     { VK_FORMAT_B8G8R8A8_UNORM,           AV_PIX_FMT_BGR0,    VK_IMAGE_ASPECT_COLOR_BIT },
68     { VK_FORMAT_R8G8B8A8_UNORM,           AV_PIX_FMT_RGB0,    VK_IMAGE_ASPECT_COLOR_BIT },
69     { VK_FORMAT_A2R10G10B10_UNORM_PACK32, AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT },
70
71     /* Planar RGB */
72     { VK_FORMAT_R8_UNORM,   AV_PIX_FMT_GBRAP,    VK_IMAGE_ASPECT_COLOR_BIT },
73     { VK_FORMAT_R16_UNORM,  AV_PIX_FMT_GBRAP16,  VK_IMAGE_ASPECT_COLOR_BIT },
74     { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRPF32,  VK_IMAGE_ASPECT_COLOR_BIT },
75     { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRAPF32, VK_IMAGE_ASPECT_COLOR_BIT },
76
77     /* Two-plane 420 YUV at 8, 10, 12 and 16 bits */
78     { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,                  AV_PIX_FMT_NV12, ASPECT_2PLANE },
79     { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, AV_PIX_FMT_P010, ASPECT_2PLANE },
80     { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, AV_PIX_FMT_P012, ASPECT_2PLANE },
81     { VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,               AV_PIX_FMT_P016, ASPECT_2PLANE },
82
83     /* Two-plane 422 YUV at 8, 10 and 16 bits */
84     { VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,                  AV_PIX_FMT_NV16, ASPECT_2PLANE },
85     { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, AV_PIX_FMT_P210, ASPECT_2PLANE },
86     { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, AV_PIX_FMT_P212, ASPECT_2PLANE },
87     { VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,               AV_PIX_FMT_P216, ASPECT_2PLANE },
88
89     /* Two-plane 444 YUV at 8, 10 and 16 bits */
90     { VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,                  AV_PIX_FMT_NV24, ASPECT_2PLANE },
91     { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, AV_PIX_FMT_P410, ASPECT_2PLANE },
92     { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, AV_PIX_FMT_P412, ASPECT_2PLANE },
93     { VK_FORMAT_G16_B16R16_2PLANE_444_UNORM,               AV_PIX_FMT_P416, ASPECT_2PLANE },
94
95     /* Three-plane 420, 422, 444 at 8, 10, 12 and 16 bits */
96     { VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,    AV_PIX_FMT_YUV420P,   ASPECT_3PLANE },
97     { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P10, ASPECT_3PLANE },
98     { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P12, ASPECT_3PLANE },
99     { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, AV_PIX_FMT_YUV420P16, ASPECT_3PLANE },
100     { VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,    AV_PIX_FMT_YUV422P,   ASPECT_3PLANE },
101     { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P10, ASPECT_3PLANE },
102     { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P12, ASPECT_3PLANE },
103     { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, AV_PIX_FMT_YUV422P16, ASPECT_3PLANE },
104     { VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,    AV_PIX_FMT_YUV444P,   ASPECT_3PLANE },
105     { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P10, ASPECT_3PLANE },
106     { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P12, ASPECT_3PLANE },
107     { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, AV_PIX_FMT_YUV444P16, ASPECT_3PLANE },
108
109     /* Single plane 422 at 8, 10 and 12 bits */
110     { VK_FORMAT_G8B8G8R8_422_UNORM,                     AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT },
111     { VK_FORMAT_B8G8R8G8_422_UNORM,                     AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT },
112     { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, AV_PIX_FMT_Y210,    VK_IMAGE_ASPECT_COLOR_BIT },
113     { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, AV_PIX_FMT_Y212,    VK_IMAGE_ASPECT_COLOR_BIT },
114 };
115 static const int nb_vk_format_map = FF_ARRAY_ELEMS(vk_format_map);
116
117 enum AVPixelFormat ff_vk_pix_fmt_from_vkfmt(VkFormat vkf)
118 {
119     for (int i = 0; i < nb_vk_format_map; i++)
120         if (vk_format_map[i].vkf == vkf)
121             return vk_format_map[i].pixfmt;
122     return AV_PIX_FMT_NONE;
123 }
124
125 VkImageAspectFlags ff_vk_aspect_bits_from_vkfmt(VkFormat vkf)
126 {
127     for (int i = 0; i < nb_vk_format_map; i++)
128         if (vk_format_map[i].vkf == vkf)
129             return vk_format_map[i].aspect;
130     return VK_IMAGE_ASPECT_NONE;
131 }
132
133 VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFmtDescriptor *desc)
134 {
135     if (desc->nb_components == 1)
136         return VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR;
137     else if (!desc->log2_chroma_w && !desc->log2_chroma_h)
138         return VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR;
139     else if (!desc->log2_chroma_w && desc->log2_chroma_h == 1)
140         return VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR;
141     else if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1)
142         return VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR;
143     return VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR;
144 }
145
146 VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth)
147 {
148     switch (depth) {
149     case  8: return VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR;
150     case 10: return VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR;
151     case 12: return VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR;
152     default: break;
153     }
154     return VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR;
155 }
156
157 int ff_vk_h264_level_to_av(StdVideoH264LevelIdc level)
158 {
159     switch (level) {
160     case STD_VIDEO_H264_LEVEL_IDC_1_0: return 10;
161     case STD_VIDEO_H264_LEVEL_IDC_1_1: return 11;
162     case STD_VIDEO_H264_LEVEL_IDC_1_2: return 12;
163     case STD_VIDEO_H264_LEVEL_IDC_1_3: return 13;
164     case STD_VIDEO_H264_LEVEL_IDC_2_0: return 20;
165     case STD_VIDEO_H264_LEVEL_IDC_2_1: return 21;
166     case STD_VIDEO_H264_LEVEL_IDC_2_2: return 22;
167     case STD_VIDEO_H264_LEVEL_IDC_3_0: return 30;
168     case STD_VIDEO_H264_LEVEL_IDC_3_1: return 31;
169     case STD_VIDEO_H264_LEVEL_IDC_3_2: return 32;
170     case STD_VIDEO_H264_LEVEL_IDC_4_0: return 40;
171     case STD_VIDEO_H264_LEVEL_IDC_4_1: return 41;
172     case STD_VIDEO_H264_LEVEL_IDC_4_2: return 42;
173     case STD_VIDEO_H264_LEVEL_IDC_5_0: return 50;
174     case STD_VIDEO_H264_LEVEL_IDC_5_1: return 51;
175     case STD_VIDEO_H264_LEVEL_IDC_5_2: return 52;
176     case STD_VIDEO_H264_LEVEL_IDC_6_0: return 60;
177     case STD_VIDEO_H264_LEVEL_IDC_6_1: return 61;
178     default:
179     case STD_VIDEO_H264_LEVEL_IDC_6_2: return 62;
180     }
181 }
182
183 int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
184 {
185     switch (level) {
186     case STD_VIDEO_H265_LEVEL_IDC_1_0: return 10;
187     case STD_VIDEO_H265_LEVEL_IDC_2_0: return 20;
188     case STD_VIDEO_H265_LEVEL_IDC_2_1: return 21;
189     case STD_VIDEO_H265_LEVEL_IDC_3_0: return 30;
190     case STD_VIDEO_H265_LEVEL_IDC_3_1: return 31;
191     case STD_VIDEO_H265_LEVEL_IDC_4_0: return 40;
192     case STD_VIDEO_H265_LEVEL_IDC_4_1: return 41;
193     case STD_VIDEO_H265_LEVEL_IDC_5_0: return 50;
194     case STD_VIDEO_H265_LEVEL_IDC_5_1: return 51;
195     case STD_VIDEO_H265_LEVEL_IDC_6_0: return 60;
196     case STD_VIDEO_H265_LEVEL_IDC_6_1: return 61;
197     default:
198     case STD_VIDEO_H265_LEVEL_IDC_6_2: return 62;
199     }
200 }
201
202 static void free_data_buf(void *opaque, uint8_t *data)
203 {
204     FFVulkanContext *ctx = opaque;
205     FFVkVideoBuffer *buf = (FFVkVideoBuffer *)data;
206     ff_vk_unmap_buffer(ctx, &buf->buf, 0);
207     ff_vk_free_buf(ctx, &buf->buf);
208     av_free(data);
209 }
210
211 static AVBufferRef *alloc_data_buf(void *opaque, size_t size)
212 {
213     AVBufferRef *ref;
214     uint8_t *buf = av_mallocz(size);
215     if (!buf)
216         return NULL;
217
218     ref = av_buffer_create(buf, size, free_data_buf, opaque, 0);
219     if (!ref)
220         av_free(buf);
221     return ref;
222 }
223
224 int ff_vk_video_get_buffer(FFVulkanContext *ctx, FFVkVideoCommon *s,
225                            AVBufferRef **buf, VkBufferUsageFlags usage,
226                            void *create_pNext, size_t size)
227 {
228     int err;
229     AVBufferRef *ref;
230     FFVkVideoBuffer *data;
231
232     if (!s->buf_pool) {
233         s->buf_pool = av_buffer_pool_init2(sizeof(FFVkVideoBuffer), ctx,
234                                            alloc_data_buf, NULL);
235         if (!s->buf_pool)
236             return AVERROR(ENOMEM);
237     }
238
239     *buf = ref = av_buffer_pool_get(s->buf_pool);
240     if (!ref)
241         return AVERROR(ENOMEM);
242
243     data = (FFVkVideoBuffer *)ref->data;
244
245     if (data->buf.size >= size)
246         return 0;
247
248     /* No point in requesting anything smaller. */
249     size = FFMAX(size, 1024*1024);
250
251     /* Align buffer to nearest power of two. Makes fragmentation management
252      * easier, and gives us ample headroom. */
253     size--;
254     size |= size >>  1;
255     size |= size >>  2;
256     size |= size >>  4;
257     size |= size >>  8;
258     size |= size >> 16;
259     size++;
260
261     ff_vk_free_buf(ctx, &data->buf);
262     memset(data, 0, sizeof(FFVkVideoBuffer));
263
264     err = ff_vk_create_buf(ctx, &data->buf, size,
265                            create_pNext, NULL, usage,
266                            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
267     if (err < 0) {
268         av_buffer_unref(&ref);
269         return err;
270     }
271
272     /* Map the buffer */
273     err = ff_vk_map_buffer(ctx, &data->buf, &data->mem, 0);
274     if (err < 0) {
275         av_buffer_unref(&ref);
276         return err;
277     }
278
279     return 0;
280 }
281
282 av_cold void ff_vk_video_common_uninit(FFVulkanContext *s,
283                                        FFVkVideoCommon *common)
284 {
285     FFVulkanFunctions *vk = &s->vkfn;
286
287     if (common->session) {
288         vk->DestroyVideoSessionKHR(s->hwctx->act_dev, common->session,
289                                    s->hwctx->alloc);
290         common->session = NULL;
291     }
292
293     if (common->nb_mem && common->mem)
294         for (int i = 0; i < common->nb_mem; i++)
295             vk->FreeMemory(s->hwctx->act_dev, common->mem[i], s->hwctx->alloc);
296
297     av_freep(&common->mem);
298
299     av_buffer_pool_uninit(&common->buf_pool);
300 }
301
302 av_cold int ff_vk_video_common_init(void *log, FFVulkanContext *s,
303                                     FFVkVideoCommon *common,
304                                     VkVideoSessionCreateInfoKHR *session_create)
305 {
306     int err;
307     VkResult ret;
308     FFVulkanFunctions *vk = &s->vkfn;
309     VkMemoryRequirements2 *mem_req = NULL;
310     VkVideoSessionMemoryRequirementsKHR *mem = NULL;
311     VkBindVideoSessionMemoryInfoKHR *bind_mem = NULL;
312
313     /* Create session */
314     ret = vk->CreateVideoSessionKHR(s->hwctx->act_dev, session_create,
315                                     s->hwctx->alloc, &common->session);
316     if (ret != VK_SUCCESS)
317         return AVERROR_EXTERNAL;
318
319     /* Get memory requirements */
320     ret = vk->GetVideoSessionMemoryRequirementsKHR(s->hwctx->act_dev,
321                                                    common->session,
322                                                    &common->nb_mem,
323                                                    NULL);
324     if (ret != VK_SUCCESS) {
325         err = AVERROR_EXTERNAL;
326         goto fail;
327     }
328
329     /* Allocate all memory needed to actually allocate memory */
330     common->mem = av_mallocz(sizeof(*common->mem)*common->nb_mem);
331     if (!common->mem) {
332         err = AVERROR(ENOMEM);
333         goto fail;
334     }
335     mem = av_mallocz(sizeof(*mem)*common->nb_mem);
336     if (!mem) {
337         err = AVERROR(ENOMEM);
338         goto fail;
339     }
340     mem_req = av_mallocz(sizeof(*mem_req)*common->nb_mem);
341     if (!mem_req) {
342         err = AVERROR(ENOMEM);
343         goto fail;
344     }
345     bind_mem = av_mallocz(sizeof(*bind_mem)*common->nb_mem);
346     if (!bind_mem) {
347         err = AVERROR(ENOMEM);
348         goto fail;
349     }
350
351     /* Set the needed fields to get the memory requirements */
352     for (int i = 0; i < common->nb_mem; i++) {
353         mem_req[i] = (VkMemoryRequirements2) {
354             .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
355         };
356         mem[i] = (VkVideoSessionMemoryRequirementsKHR) {
357             .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR,
358             .memoryRequirements = mem_req[i].memoryRequirements,
359         };
360     }
361
362     /* Finally get the memory requirements */
363     ret = vk->GetVideoSessionMemoryRequirementsKHR(s->hwctx->act_dev,
364                                                    common->session, &common->nb_mem,
365                                                    mem);
366     if (ret != VK_SUCCESS) {
367         err = AVERROR_EXTERNAL;
368         goto fail;
369     }
370
371     /* Now allocate each requested memory.
372      * For ricing, could pool together memory that ends up in the same index. */
373     for (int i = 0; i < common->nb_mem; i++) {
374         err = ff_vk_alloc_mem(s, &mem[i].memoryRequirements,
375                               UINT32_MAX, NULL, NULL, &common->mem[i]);
376         if (err < 0)
377             goto fail;
378
379         bind_mem[i] = (VkBindVideoSessionMemoryInfoKHR) {
380             .sType = VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR,
381             .memory = common->mem[i],
382             .memoryBindIndex = mem[i].memoryBindIndex,
383             .memoryOffset = 0,
384             .memorySize = mem[i].memoryRequirements.size,
385         };
386
387         av_log(log, AV_LOG_VERBOSE, "Allocating %"SIZE_SPECIFIER" bytes in bind index %i for video session\n",
388                bind_mem[i].memorySize, bind_mem[i].memoryBindIndex);
389     }
390
391     /* Bind the allocated memory */
392     ret = vk->BindVideoSessionMemoryKHR(s->hwctx->act_dev, common->session,
393                                         common->nb_mem, bind_mem);
394     if (ret != VK_SUCCESS) {
395         err = AVERROR_EXTERNAL;
396         goto fail;
397     }
398
399     av_freep(&mem);
400     av_freep(&mem_req);
401     av_freep(&bind_mem);
402
403     return 0;
404
405 fail:
406     av_freep(&mem);
407     av_freep(&mem_req);
408     av_freep(&bind_mem);
409
410     ff_vk_video_common_uninit(s, common);
411     return err;
412 }