Go to the documentation of this file.
22 #include "config_components.h"
27 #define DECODER_IS_SDR(codec_id) \
28 ((codec_id) == AV_CODEC_ID_FFV1)
30 #if CONFIG_H264_VULKAN_HWACCEL
33 #if CONFIG_HEVC_VULKAN_HWACCEL
36 #if CONFIG_AV1_VULKAN_HWACCEL
39 #if CONFIG_FFV1_VULKAN_HWACCEL
44 #if CONFIG_H264_VULKAN_HWACCEL
47 #if CONFIG_HEVC_VULKAN_HWACCEL
50 #if CONFIG_AV1_VULKAN_HWACCEL
53 #if CONFIG_FFV1_VULKAN_HWACCEL
69 const VkVideoProfileListInfoKHR *profile_list;
71 VkStructureType profile_struct_type =
75 VK_STRUCTURE_TYPE_MAX_ENUM;
76 if (profile_struct_type == VK_STRUCTURE_TYPE_MAX_ENUM)
80 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
84 for (
int i = 0;
i < profile_list->profileCount;
i++)
86 return &profile_list->pProfiles[
i];
140 vkpic->
view.
ref[
i] = VK_NULL_HANDLE;
141 vkpic->
view.
out[
i] = VK_NULL_HANDLE;
142 vkpic->
view.
dst[
i] = VK_NULL_HANDLE;
165 if (
ctx->common.layered_dpb && alloc_dpb) {
166 vkpic->
view.
ref[0] =
ctx->common.layered_view;
168 }
else if (alloc_dpb) {
179 dpb_hwfc->format[0], !is_current);
186 if (!alloc_dpb || is_current) {
193 hwfc->format[0], !is_current);
236 if (!alloc_dpb || is_current) {
254 const uint8_t *
data,
size_t size,
int add_startcode,
255 uint32_t *nb_slices,
const uint32_t **
offsets)
260 static const uint8_t startcode_prefix[3] = { 0x0, 0x0, 0x1 };
261 const size_t startcode_len = add_startcode ?
sizeof(startcode_prefix) : 0;
262 const int nb = *nb_slices;
268 ctx->caps.minBitstreamBufferSizeAlignment;
269 new_size =
FFALIGN(new_size,
ctx->caps.minBitstreamBufferSizeAlignment);
272 (nb + 1)*
sizeof(slice_off));
280 if (!vkbuf || vkbuf->
size < new_size) {
286 size_t buf_size =
FFMAX(new_size, 1024*1024);
290 buf_size = 2 <<
av_log2(buf_size);
294 (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
295 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) :
296 VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR,
297 ctx->s.hwfc->create_pnext, buf_size,
298 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
300 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0));
318 memcpy(slices + vp->
slices_size, startcode_prefix, startcode_len);
335 VkVideoBeginCodingInfoKHR decode_start = {
336 .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
337 .videoSession =
ctx->common.session,
338 .videoSessionParameters =
ctx->empty_session_params,
340 VkVideoCodingControlInfoKHR decode_ctrl = {
341 .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
342 .
flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
345 .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
348 VkCommandBuffer cmd_buf;
359 vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
360 vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
361 vk->CmdEndVideoCodingKHR(cmd_buf, &
decode_end);
371 VkCommandBuffer cmd_buf;
382 const int layered_dpb =
ctx->common.layered_dpb;
384 VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)dec->
session_params->
data;
385 VkVideoBeginCodingInfoKHR decode_start = {
386 .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
387 .videoSession =
ctx->common.session,
388 .videoSessionParameters = *par,
389 .referenceSlotCount = vp->
decode_info.referenceSlotCount,
390 .pReferenceSlots = vp->
decode_info.pReferenceSlots,
393 .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
396 VkImageMemoryBarrier2 img_bar[37];
399 ctx->caps.minBitstreamBufferSizeAlignment);
404 VkVideoReferenceSlotInfoKHR *cur_vk_ref;
405 cur_vk_ref = (
void *)&decode_start.pReferenceSlots[decode_start.referenceSlotCount];
407 cur_vk_ref[0].slotIndex = -1;
408 decode_start.referenceSlotCount++;
413 if (!(sd_buf->
flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
414 VkMappedMemoryRange flush_buf = {
415 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
416 .memory = sd_buf->
mem,
419 ctx->s.props.properties.limits.nonCoherentAtomSize),
422 ret = vk->FlushMappedMemoryRanges(
ctx->s.hwctx->act_dev, 1, &flush_buf);
423 if (
ret != VK_SUCCESS) {
452 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
453 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
463 img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
464 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
466 .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
467 .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
468 .srcAccessMask = VK_ACCESS_2_NONE,
469 .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
470 .oldLayout = vkf->
layout[0],
471 .newLayout = (layered_dpb || vp->
dpb_frame) ?
472 VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
473 VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
475 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
476 .image = vkf->
img[0],
477 .subresourceRange = (VkImageSubresourceRange) {
484 &img_bar[nb_img_bar], &nb_img_bar);
489 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
490 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
504 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
505 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
520 img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
521 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
523 .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
524 .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
525 .srcAccessMask = VK_ACCESS_2_NONE,
526 .dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR |
527 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR,
528 .oldLayout = rvkf->
layout[0],
529 .newLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
531 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
532 .image = rvkf->
img[0],
533 .subresourceRange = (VkImageSubresourceRange) {
540 &img_bar[nb_img_bar], &nb_img_bar);
547 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR,
548 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR);
554 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
555 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
556 .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
557 .pImageMemoryBarriers = img_bar,
558 .imageMemoryBarrierCount = nb_img_bar,
562 vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
564 vk->CmdEndVideoCodingKHR(cmd_buf, &
decode_end);
574 VkSemaphoreWaitInfo
sem_wait = (VkSemaphoreWaitInfo) {
575 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
576 .pSemaphores = &vp->
sem,
616 if (
ctx->empty_session_params)
617 vk->DestroyVideoSessionParametersKHR(
s->hwctx->act_dev,
618 ctx->empty_session_params,
625 if (
ctx->sd_ctx_free)
654 if (vk_desc->
queue_flags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
657 VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME);
677 VkVideoDecodeH264CapabilitiesKHR *h264_caps,
678 VkVideoDecodeH265CapabilitiesKHR *h265_caps,
679 VkVideoDecodeAV1CapabilitiesKHR *av1_caps,
680 VkVideoCapabilitiesKHR *caps,
681 VkVideoDecodeCapabilitiesKHR *dec_caps,
684 VkVideoDecodeUsageInfoKHR *
usage = &prof->
usage;
686 VkVideoProfileListInfoKHR *profile_list = &prof->
profile_list;
688 VkVideoDecodeH264ProfileInfoKHR *h264_profile = &prof->
h264_profile;
689 VkVideoDecodeH265ProfileInfoKHR *h265_profile = &prof->
h265_profile;
690 VkVideoDecodeAV1ProfileInfoKHR *av1_profile = &prof->
av1_profile;
697 dec_caps->pNext = h264_caps;
698 usage->pNext = h264_profile;
699 h264_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
708 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR :
709 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
711 dec_caps->pNext = h265_caps;
712 usage->pNext = h265_profile;
713 h265_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
714 h265_profile->stdProfileIdc = cur_profile;
716 dec_caps->pNext = av1_caps;
717 usage->pNext = av1_profile;
718 av1_profile->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
719 av1_profile->stdProfile = cur_profile;
723 usage->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR;
724 usage->videoUsageHints = VK_VIDEO_DECODE_USAGE_DEFAULT_KHR;
726 profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
733 profile_list->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
734 profile_list->profileCount = 1;
735 profile_list->pProfiles =
profile;
738 caps->sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
739 caps->pNext = dec_caps;
740 dec_caps->sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR;
743 return vk->GetPhysicalDeviceVideoCapabilitiesKHR(hwctx->
phys_dev,
profile,
753 int max_level, base_profile, cur_profile;
766 VkVideoCapabilitiesKHR *caps = &
ctx->caps;
767 VkVideoDecodeCapabilitiesKHR *dec_caps = &
ctx->dec_caps;
769 VkVideoDecodeH264CapabilitiesKHR h264_caps = {
770 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR,
772 VkVideoDecodeH265CapabilitiesKHR h265_caps = {
773 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR,
775 VkVideoDecodeAV1CapabilitiesKHR av1_caps = {
776 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_CAPABILITIES_KHR,
779 VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
780 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
783 VkVideoFormatPropertiesKHR *ret_info;
784 uint32_t nb_out_fmts = 0;
805 if (
ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR &&
807 avctx->
profile != base_profile) {
809 "again with profile %s\n",
813 cur_profile = base_profile;
823 if (
ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
825 "%s profile \"%s\" not supported!\n",
829 }
else if (
ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
831 "format (%s) not supported!\n",
834 }
else if (
ret == VK_ERROR_FEATURE_NOT_PRESENT ||
835 ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
837 }
else if (
ret != VK_SUCCESS) {
850 max_level, avctx->
level);
852 caps->minCodedExtent.width, caps->maxCodedExtent.width);
854 caps->minCodedExtent.height, caps->maxCodedExtent.height);
856 caps->pictureAccessGranularity.width);
858 caps->pictureAccessGranularity.height);
860 caps->minBitstreamBufferOffsetAlignment);
862 caps->minBitstreamBufferSizeAlignment);
866 caps->maxActiveReferencePictures);
868 caps->stdHeaderVersion.extensionName,
870 av_log(avctx,
AV_LOG_VERBOSE,
" Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
871 CODEC_VER(caps->stdHeaderVersion.specVersion),
874 dec_caps->flags ?
"" :
876 dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR ?
877 " reuse_dst_dpb" :
"",
878 dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR ?
879 " dedicated_dpb" :
"");
883 caps->flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
885 caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
886 " separate_references" :
"");
889 if (avctx->
coded_width < caps->minCodedExtent.width ||
896 avctx->
level > max_level)
900 if (!(dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
901 VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR))) {
903 "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR nor "
904 "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR are set!\n");
906 }
else if ((dec_caps->flags & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR |
907 VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ==
908 VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) &&
909 !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR)) {
910 av_log(avctx,
AV_LOG_ERROR,
"Cannot initialize Vulkan decoding session, buggy driver: "
911 "VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set "
912 "but VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!\n");
916 dec->
dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR);
918 !(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
921 fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
923 fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
924 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
925 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
926 VK_IMAGE_USAGE_SAMPLED_BIT;
930 fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
934 ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->
phys_dev,
937 if (
ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
938 (!nb_out_fmts &&
ret == VK_SUCCESS)) {
940 }
else if (
ret != VK_SUCCESS) {
946 ret_info =
av_mallocz(
sizeof(*ret_info)*nb_out_fmts);
950 for (
int i = 0;
i < nb_out_fmts;
i++)
951 ret_info[
i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
953 ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(hwctx->
phys_dev,
955 &nb_out_fmts, ret_info);
956 if (
ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
957 (!nb_out_fmts &&
ret == VK_SUCCESS)) {
960 }
else if (
ret != VK_SUCCESS) {
969 *vk_fmt = best_vkfmt = VK_FORMAT_UNDEFINED;
972 av_log(avctx,
AV_LOG_DEBUG,
"Choosing best pixel format for decoding from %i:\n", nb_out_fmts);
973 for (
int i = 0;
i < nb_out_fmts;
i++) {
981 if (
tmp == best_format)
982 best_vkfmt = ret_info[
i].format;
992 av_log(avctx,
AV_LOG_ERROR,
"No valid/compatible pixel format found for decoding!\n");
1000 *vk_fmt = best_vkfmt;
1014 VkFormat vkfmt = VK_FORMAT_UNDEFINED;
1015 int err, dedicated_dpb;
1034 prof, &dedicated_dpb);
1043 hwfc->create_pnext = &prof->profile_list;
1067 hwfc->format[0] = vkfmt;
1068 hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
1069 hwfc->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1070 VK_IMAGE_USAGE_SAMPLED_BIT;
1075 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
1076 if (!dec->dedicated_dpb)
1077 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1079 ctx = dec->shared_ctx;
1082 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1084 hwfc->usage |= VK_IMAGE_USAGE_STORAGE_BIT;
1094 VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)
data;
1095 vk->DestroyVideoSessionParametersKHR(
ctx->s.hwctx->act_dev, *par,
1096 ctx->s.hwctx->alloc);
1101 const VkVideoSessionParametersCreateInfoKHR *session_params_create)
1103 VkVideoSessionParametersKHR *par =
av_malloc(
sizeof(*par));
1111 ret = vk->CreateVideoSessionParametersKHR(
ctx->s.hwctx->act_dev, session_params_create,
1112 ctx->s.hwctx->alloc, par);
1113 if (
ret != VK_SUCCESS) {
1114 av_log(logctx,
AV_LOG_ERROR,
"Unable to create Vulkan video session parameters: %s!\n",
1147 VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
1148 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
1150 VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
1151 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
1153 StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
1154 VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
1155 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
1156 .pStdSequenceHeader = &av1_empty_seq,
1158 VkVideoSessionParametersCreateInfoKHR session_params_create = {
1159 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1164 .videoSession =
ctx->common.session,
1167 ret = vk->CreateVideoSessionParametersKHR(
s->hwctx->act_dev, &session_params_create,
1168 s->hwctx->alloc, &
ctx->empty_session_params);
1169 if (
ret != VK_SUCCESS) {
1170 av_log(avctx,
AV_LOG_ERROR,
"Unable to create empty Vulkan video session parameters: %s!\n",
1185 const VkVideoProfileInfoKHR *
profile;
1187 const VkPhysicalDeviceDriverProperties *driver_props;
1189 VkVideoSessionCreateInfoKHR session_create = {
1190 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
1222 session_create.queueFamilyIndex =
ctx->qf->idx;
1223 session_create.maxCodedExtent =
ctx->caps.maxCodedExtent;
1224 session_create.maxDpbSlots =
ctx->caps.maxDpbSlots;
1225 session_create.maxActiveReferencePictures =
ctx->caps.maxActiveReferencePictures;
1226 session_create.pictureFormat =
s->hwfc->format[0];
1227 session_create.referencePictureFormat = session_create.pictureFormat;
1228 session_create.pStdHeaderVersion = &vk_desc->
ext_props;
1229 session_create.pVideoProfile =
profile;
1230 #ifdef VK_KHR_video_maintenance2
1232 session_create.flags = VK_VIDEO_SESSION_CREATE_INLINE_SESSION_PARAMETERS_BIT_KHR;
1238 async_depth = 2*
ctx->qf->num;
1245 async_depth, 0, 0, 0,
profile);
1261 if (!
ctx->common.dpb_hwfc_ref) {
1274 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
1275 dpb_hwfc->
format[0] =
s->hwfc->format[0];
1276 dpb_hwfc->
tiling = VK_IMAGE_TILING_OPTIMAL;
1277 dpb_hwfc->
usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1278 VK_IMAGE_USAGE_SAMPLED_BIT;
1280 if (
ctx->common.layered_dpb)
1287 if (
ctx->common.layered_dpb) {
1289 if (!
ctx->common.layered_frame) {
1295 &
ctx->common.layered_view,
1296 &
ctx->common.layered_aspect,
1298 s->hwfc->format[0], 1);
1317 if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
1318 driver_props->conformanceVersion.major == 1 &&
1319 driver_props->conformanceVersion.minor == 3 &&
1320 driver_props->conformanceVersion.subminor == 8 &&
1321 driver_props->conformanceVersion.patch < 3)
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
#define AV_PIX_FMT_GBRAP16
#define AV_LOG_WARNING
Something somehow does not look correct.
VkPhysicalDevice phys_dev
Physical device.
AVPixelFormat
Pixel format.
VkVideoProfileInfoKHR profile
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
#define AV_PROFILE_H264_INTRA
VkVideoDecodeH265ProfileInfoKHR h265_profile
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.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
uint8_t * data
The data buffer.
FFVulkanDecodeShared * shared_ctx
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.
RefStruct is an API for creating reference-counted objects with minimal overhead.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
#define FF_VK_EXT_VIDEO_MAINTENANCE_2
#define AV_PROFILE_HEVC_MAIN
void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth)
Get Vulkan's bit depth from an [8:12] integer.
This structure describes decoded (raw) audio or video data.
const FFVulkanDecodeDescriptor ff_vk_dec_av1_desc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
void(* free)(struct AVHWFramesContext *ctx)
This field may be set by the caller before calling av_hwframe_ctx_init().
enum AVFieldOrder field_order
Field order.
void * create_pnext
Extension data for image creation.
static const void * ff_vk_find_struct(const void *chain, VkStructureType stype)
static int create_empty_session_parameters(AVCodecContext *avctx, FFVulkanDecodeShared *ctx)
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.
uint32_t frame_id_alloc_mask
#define AV_LOG_VERBOSE
Detailed information.
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.
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
const char * avcodec_profile_name(enum AVCodecID codec_id, int profile)
Return a name for the specified profile, if available.
VkImageView dst[AV_NUM_DATA_POINTERS]
int width
The allocated dimensions of the frames in this pool.
VkVideoDecodeAV1ProfileInfoKHR av1_profile
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
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.
#define AV_HWACCEL_FLAG_IGNORE_LEVEL
Hardware acceleration should be used for decoding even if the codec level used is unknown or higher t...
FFVkShaderRepFormat
Returns the format to use for images in shaders.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
@ AV_HWDEVICE_TYPE_VULKAN
AVBufferRef * session_params
VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFmtDescriptor *desc)
Get Vulkan's chroma subsampling from a pixfmt descriptor.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
VkVideoCodecOperationFlagBitsKHR decode_op
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
#define AV_PIX_FMT_GBRP10
if it could not because there are no more frames
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
int flags
AV_CODEC_FLAG_*.
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
int ff_vk_decode_frame(AVCodecContext *avctx, AVFrame *pic, FFVulkanDecodePicture *vp, AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
Decode a frame.
static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ref, enum AVPixelFormat *pix_fmt, VkFormat *vk_fmt, FFVulkanDecodeProfileData *prof, int *dpb_dedicate)
static void init_frame(FFVulkanDecodeContext *dec, FFVulkanDecodePicture *vkpic)
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
VkVideoDecodeH264ProfileInfoKHR h264_profile
#define FF_ARRAY_ELEMS(a)
VkVideoProfileListInfoKHR profile_list
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.
PFN_vkWaitSemaphores wait_semaphores
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.
int ff_vk_decode_create_params(AVBufferRef **par_ref, void *logctx, FFVulkanDecodeShared *ctx, const VkVideoSessionParametersCreateInfoKHR *session_params_create)
Create VkVideoSessionParametersKHR wrapped in an AVBufferRef.
int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore *dst, uint64_t *dst_val, AVFrame *f)
static const int offsets[]
VkPhysicalDeviceDriverProperties driver_props
int flags
Flags modifying the (de)muxer behaviour.
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
static enum AVPixelFormat pix_fmt
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.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e, AVBufferRef **deps, int nb_deps, int ref)
Execution dependency management.
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
static const VkVideoProfileInfoKHR * get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
#define AV_PIX_FMT_RGBA64
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
int nb_enabled_dev_extensions
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
av_cold void ff_vk_video_common_uninit(FFVulkanContext *s, FFVkVideoCommon *common)
Free video session and required resources.
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
struct AVCodecInternal * internal
Private context used for internal data.
VkVideoDecodeUsageInfoKHR usage
FFVulkanExtensions decode_extension
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
Hardware acceleration should still be attempted for decoding when the codec profile does not match th...
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
VkImageUsageFlagBits usage
Defines extra usage of output frames.
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
VkImageAspectFlags aspect[AV_NUM_DATA_POINTERS]
VkImageAspectFlags aspect_ref[AV_NUM_DATA_POINTERS]
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...
int level
Encoding level descriptor.
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.
AVCodecID
Identify the syntax and semantics of the bitstream.
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.
#define AV_PIX_FMT_X2BGR10
static void free_common(AVRefStructOpaque unused, void *obj)
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level)
void * hwaccel_priv_data
hwaccel-specific private data
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
VkImageView ref[AV_NUM_DATA_POINTERS]
#define AV_NUM_DATA_POINTERS
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
VkMemoryPropertyFlagBits flags
const FFVulkanDecodeDescriptor ff_vk_dec_h264_desc
unsigned int slice_off_max
uint32_t queue_family[AV_NUM_DATA_POINTERS]
Queue family of the images.
#define AVERROR_EXTERNAL
Generic error in an external library.
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
static void vk_decode_free_params(void *opaque, uint8_t *data)
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
VkImageView out[AV_NUM_DATA_POINTERS]
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
#define i(width, name, range_min, range_max)
VkExtensionProperties ext_props
int ff_vk_h264_level_to_av(StdVideoH264LevelIdc level)
Convert level from Vulkan to AV.
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define DECODER_IS_SDR(codec_id)
VkVideoReferenceSlotInfoKHR ref_slot
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
This struct describes a set or pool of "hardware" frames (i.e.
void ff_vk_decode_flush(AVCodecContext *avctx)
Flush decoder.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
void * user_opaque
Arbitrary user data, to be used e.g.
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.
#define AV_PROFILE_H264_CONSTRAINED
static const FFVulkanDecodeDescriptor * dec_descs[]
struct HEVCHeaderSet * hevc_headers
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
#define AV_INPUT_BUFFER_PADDING_SIZE
struct FFVulkanDecodePicture::@293 view
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
const FFVulkanDecodeDescriptor ff_vk_dec_hevc_desc
static const FFVulkanDecodeDescriptor * get_codecdesc(enum AVCodecID codec_id)
main external API structure.
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.
const FFVulkanDecodeDescriptor ff_vk_dec_ffv1_desc
void av_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
static int ref[MAX_W *MAX_W]
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
Removes current session parameters to recreate them.
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
VkImageTiling tiling
Controls the tiling of allocated frames.
int coded_width
Bitstream width / height, may be different from width/height e.g.
const char *const * enabled_dev_extensions
Enabled device extensions.
int nb_layers
Number of layers each image will have.
VkImageLayout layout[AV_NUM_DATA_POINTERS]
A reference to a data buffer.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
VkQueueFlagBits queue_flags
VkDevice act_dev
Active device.
static av_cold int decode_end(AVCodecContext *avctx)
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)
static AVFrame * vk_get_dpb_pool(FFVulkanDecodeShared *ctx)
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
PFN_vkDestroyImageView destroy_image_view
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
static int vulkan_decode_bootstrap(AVCodecContext *avctx, AVBufferRef *frames_ref)
enum AVPixelFormat ff_vk_pix_fmt_from_vkfmt(VkFormat vkf)
Get pixfmt from a Vulkan format.
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
VkVideoDecodeInfoKHR decode_info
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
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.
static void free_profile_data(AVHWFramesContext *hwfc)
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
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.