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
22 #include "config_components.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
81 #if CONFIG_VP9_VULKAN_HWACCEL
82 VkVideoDecodeVP9ProfileInfoKHR vp9_profile;
83 #endif
85
86 VkVideoDecodeUsageInfoKHR
usage;
90
92 {
98 }
99
101 {
102 const VkVideoProfileListInfoKHR *profile_list;
103
104 VkStructureType profile_struct_type =
107 #if CONFIG_VP9_VULKAN_HWACCEL
109 #endif
111 VK_STRUCTURE_TYPE_MAX_ENUM;
112 if (profile_struct_type == VK_STRUCTURE_TYPE_MAX_ENUM)
114
116 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
117 if (!profile_list)
119
120 for (
int i = 0;
i < profile_list->profileCount;
i++)
122 return &profile_list->pProfiles[
i];
123
125 }
126
128 {
129 int err;
132
134
136 if (err < 0)
137 return err;
138
141
142 return 0;
143 }
144
146 {
149 return 0;
150 }
151
153 {
154 int err;
156 if (!avf)
158
160 if (err < 0)
162
163 return avf;
164 }
165
167 {
170
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
181 }
182
185 int alloc_dpb)
186 {
187 int err;
189
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 */
195 return 0;
196
198
199 if (
ctx->common.layered_dpb && alloc_dpb) {
200 vkpic->
view.
ref[0] =
ctx->common.layered_view;
202 } else if (alloc_dpb) {
205
209
213 dpb_hwfc->format[0], !is_current);
214 if (err < 0)
215 return err;
216
218 }
219
220 if (!alloc_dpb || is_current) {
223
227 hwfc->format[0], !is_current);
228 if (err < 0)
229 return err;
230
231 if (!alloc_dpb) {
234 }
235 }
236
237 return 0;
238 }
239
243 {
244 int err;
247
249
251 return 0;
252
254
256 if (alloc_dpb) {
260
264 if (err < 0)
265 return err;
266
268 }
269
270 if (!alloc_dpb || is_current) {
274 if (err < 0)
275 return err;
276
277 if (!alloc_dpb) {
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;
300
302 ctx->caps.minBitstreamBufferSizeAlignment;
303 new_size =
FFALIGN(new_size,
ctx->caps.minBitstreamBufferSizeAlignment);
304
307 (nb + 1)*sizeof(slice_off));
308 if (!slice_off)
310
312
314 }
315
317 if (!vkbuf || vkbuf->
size < new_size) {
318 int err;
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
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 |
337 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0));
338 if (err < 0)
339 return err;
340
342
343 /* Copy data from the old buffer */
347 }
348
350 vkbuf = new_buf;
351 }
353
354 /* Startcode */
355 memcpy(slices + vp->
slices_size, startcode_prefix, startcode_len);
356
357 /* Slice data */
359
360 if (nb_slices)
361 *nb_slices = nb + 1;
362
364
365 return 0;
366 }
367
369 {
372
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 };
384 .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
385 };
386
387 VkCommandBuffer cmd_buf;
389
390 /* Non-video queues do not need to be reset */
392 return;
393
397
398 vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
399 vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
400 vk->CmdEndVideoCodingKHR(cmd_buf, &
decode_end);
402 }
403
407 {
408 int err;
410 VkCommandBuffer cmd_buf;
412
416
417 /* Output */
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,
428 VK_NULL_HANDLE,
429 .referenceSlotCount = vp->
decode_info.referenceSlotCount,
430 .pReferenceSlots = vp->
decode_info.pReferenceSlots,
431 };
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
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
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) {
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 */
476 if (err < 0)
477 return err;
479
480 /* Slices */
482 if (err < 0)
483 return err;
484 vp->slices_buf =
NULL;
/* Owned by the exec buffer from now on */
485
486 /* Parameters */
488 if (err < 0)
489 return err;
490
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
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,
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 };
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) {
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++) {
542
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) {
553 if (err < 0)
554 return err;
555 }
556
559
560 img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
561 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
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,
571 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
572 .image = rvkf->
img[0],
573 .subresourceRange = (VkImageSubresourceRange) {
575 .layerCount = 1,
576 .levelCount = 1,
577 },
578 };
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 */
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 */
608 }
609
611 {
613
614 VkSemaphoreWaitInfo
sem_wait = (VkSemaphoreWaitInfo) {
615 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
616 .pSemaphores = &vp->
sem,
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. */
626
627 /* Free slices data */
629
630 /* Destroy image view (out) */
634
635 /* Destroy image view (ref, unlayered) */
638 }
639
641 }
642
644 {
648
649 /* Wait on and free execution pool */
651
652 /* This also frees all references from this pool */
654
655 /* Destroy parameters */
656 if (
ctx->empty_session_params)
657 vk->DestroyVideoSessionParametersKHR(
s->hwctx->act_dev,
658 ctx->empty_session_params,
660
662
664
665 if (
ctx->sd_ctx_free)
667
669 }
670
672 {
673 int err;
680
682 return 0;
683
688
690
693
694 if (vk_desc->
queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
697 VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
700 }
701 }
702
704 if (err < 0) {
706 return err;
707 }
708
709 return 0;
710 }
711
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;
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
741
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 */
751
754 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
755 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
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
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
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;
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;
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
803 int *dpb_dedicate)
804 {
806 int max_level, base_profile, cur_profile;
814
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,
840 };
841 VkVideoFormatPropertiesKHR *ret_info;
842 uint32_t nb_out_fmts = 0;
843
848 }
849
853 #if CONFIG_VP9_VULKAN_HWACCEL
855 #endif
857 0;
858
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) {
873 "again with profile %s\n",
877 cur_profile = base_profile;
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) {
892 "%s profile \"%s\" not supported!\n",
896 }
else if (
ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
898 "format (%s) not supported!\n",
901 }
else if (
ret == VK_ERROR_FEATURE_NOT_PRESENT ||
902 ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
904 }
else if (
ret != VK_SUCCESS) {
906 }
907
910 #if CONFIG_VP9_VULKAN_HWACCEL
912 #endif
914 0;
915
920 max_level, avctx->
level);
922 caps->minCodedExtent.width, caps->maxCodedExtent.width);
924 caps->minCodedExtent.height, caps->maxCodedExtent.height);
926 caps->pictureAccessGranularity.width);
928 caps->pictureAccessGranularity.height);
930 caps->minBitstreamBufferOffsetAlignment);
932 caps->minBitstreamBufferSizeAlignment);
934 caps->maxDpbSlots);
936 caps->maxActiveReferencePictures);
938 caps->stdHeaderVersion.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),
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" : "");
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 ||
964
966 avctx->
level > max_level)
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))) {
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");
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");
984 }
985
986 dec->
dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
988 !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
989
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
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)) {
1010 }
else if (
ret != VK_SUCCESS) {
1014 }
1015
1016 ret_info =
av_mallocz(
sizeof(*ret_info)*nb_out_fmts);
1017 if (!ret_info)
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)) {
1030 }
else if (
ret != VK_SUCCESS) {
1035 }
1036
1037 /* Find a format to use */
1039 *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
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++) {
1047 continue;
1048 }
1049
1051 if (
tmp == best_format)
1052 best_vkfmt = ret_info[
i].format;
1053
1057 }
1058
1060
1062 av_log(avctx,
AV_LOG_ERROR,
"No valid/compatible pixel format found for decoding!\n");
1064 } else {
1067 }
1068
1070 *vk_fmt = best_vkfmt;
1071
1073
1074 return 0;
1075 }
1076
1078 {
1080 }
1081
1083 {
1084 VkFormat vkfmt = VK_FORMAT_UNDEFINED;
1085 int err, dedicated_dpb;
1090
1092 if (err < 0)
1093 return err;
1094
1096
1099 if (!prof)
1101
1104 prof, &dedicated_dpb);
1105 if (err < 0) {
1107 return err;
1108 }
1109
1112
1113 hwfc->create_pnext = &prof->profile_list;
1114 } else {
1117 /* This should be more efficient for downloading and using */
1119 break;
1121 /* This saves memory bandwidth when downloading */
1123 break;
1125 /* mpv has issues with bgr0 mapping, so just remap it */
1127 break;
1128 default:
1129 break;
1130 }
1131 }
1132
1137
1138 hwfc->format[0] = vkfmt;
1139 hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1140 hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1141 VK_IMAGE_USAGE_STORAGE_BIT |
1142 VK_IMAGE_USAGE_SAMPLED_BIT;
1143
1144 if (prof) {
1146
1147 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1148 if (!dec->dedicated_dpb)
1149 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1150
1151 ctx = dec->shared_ctx;
1154 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1155 }
1156
1157 return err;
1158 }
1159
1161 {
1164 VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)
data;
1165 vk->DestroyVideoSessionParametersKHR(
ctx->s.hwctx->act_dev, *par,
1166 ctx->s.hwctx->alloc);
1168 }
1169
1171 const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1172 {
1173 VkVideoSessionParametersKHR *par =
av_malloc(
sizeof(*par));
1176
1177 if (!par)
1179
1180 /* Create session parameters */
1181 ret = vk->CreateVideoSessionParametersKHR(
ctx->s.hwctx->act_dev, session_params_create,
1182 ctx->s.hwctx->alloc, par);
1183 if (
ret != VK_SUCCESS) {
1184 av_log(logctx,
AV_LOG_ERROR,
"Unable to create Vulkan video session parameters: %s!\n",
1188 }
1191 if (!*par_ref) {
1194 }
1195
1196 return 0;
1197 }
1198
1200 {
1202
1207 return 0;
1208 }
1209
1212 {
1216
1217 VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
1218 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
1219 };
1220 VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
1221 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1222 };
1223 StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
1224 VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
1225 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
1226 .pStdSequenceHeader = &av1_empty_seq,
1227 };
1228 VkVideoSessionParametersCreateInfoKHR session_params_create = {
1229 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1234 .videoSession =
ctx->common.session,
1235 };
1236
1238 return 0;
1239
1240 ret = vk->CreateVideoSessionParametersKHR(
s->hwctx->act_dev, &session_params_create,
1241 s->hwctx->alloc, &
ctx->empty_session_params);
1242 if (
ret != VK_SUCCESS) {
1243 av_log(avctx,
AV_LOG_ERROR,
"Unable to create empty Vulkan video session parameters: %s!\n",
1246 }
1247
1248 return 0;
1249 }
1250
1252 {
1253 int err;
1257 int async_depth;
1258 const VkVideoProfileInfoKHR *
profile;
1260 const VkPhysicalDeviceDriverProperties *driver_props;
1261
1262 VkVideoSessionCreateInfoKHR session_create = {
1263 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1264 };
1265
1267 if (err < 0)
1268 return err;
1269
1270 /* Initialize contexts */
1273
1275 if (err < 0)
1276 return err;
1277
1279
1284 }
1285
1286 /* Create queue context */
1292 return err;
1293 }
1294
1295 session_create.queueFamilyIndex =
ctx->qf->idx;
1296 session_create.maxCodedExtent =
ctx->caps.maxCodedExtent;
1297 session_create.maxDpbSlots =
ctx->caps.maxDpbSlots;
1298 session_create.maxActiveReferencePictures =
ctx->caps.maxActiveReferencePictures;
1299 session_create.pictureFormat =
s->hwfc->format[0];
1300 session_create.referencePictureFormat = session_create.pictureFormat;
1301 session_create.pStdHeaderVersion = &vk_desc->
ext_props;
1302 session_create.pVideoProfile =
profile;
1303 #ifdef VK_KHR_video_maintenance2
1305 session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1306 #endif
1307
1308 /* Create decode exec context for this specific main thread.
1309 * 2 async contexts per thread was experimentally determined to be optimal
1310 * for a majority of streams. */
1311 async_depth = 2*
ctx->qf->num;
1312 /* We don't need more than 2 per thread context */
1314 /* Make sure there are enough async contexts for each thread */
1316
1318 async_depth, 0, 0, 0,
profile);
1319 if (err < 0)
1321
1324 if (err < 0)
1326 }
1327
1328 /* If doing an out-of-place decoding, create a DPB pool */
1332
1334 if (!
ctx->common.dpb_hwfc_ref) {
1337 }
1338
1344
1347 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1348 dpb_hwfc->
format[0] =
s->hwfc->format[0];
1349 dpb_hwfc->
tiling = VK_IMAGE_TILING_OPTIMAL;
1350 dpb_hwfc->
usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1351 VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */
1352
1353 if (
ctx->common.layered_dpb)
1355
1357 if (err < 0)
1359
1360 if (
ctx->common.layered_dpb) {
1362 if (!
ctx->common.layered_frame) {
1365 }
1366
1368 &
ctx->common.layered_view,
1369 &
ctx->common.layered_aspect,
1371 s->hwfc->format[0], 1);
1372 if (err < 0)
1374 }
1375 }
1376
1380 if (err < 0)
1381 return err;
1382 }
1383 } else {
1384 /* For SDR decoders, this alignment value will be 0. Since this will make
1385 * add_slice() malfunction, set it to a sane default value. */
1387 }
1388
1390 if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1391 driver_props->conformanceVersion.major == 1 &&
1392 driver_props->conformanceVersion.minor == 3 &&
1393 driver_props->conformanceVersion.subminor == 8 &&
1394 driver_props->conformanceVersion.patch < 3)
1396
1398
1400
1401 return 0;
1402
1405
1406 return err;
1407 }