vulkan: add basic AV1 encode support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8841>
This commit is contained in:
parent
ea133d97a0
commit
167e41c343
@ -293,6 +293,10 @@ static const struct extension optional_extensions[] = {
|
||||
OPTIONAL_VIDEO_EXTENSION (VK_KHR_VIDEO_MAINTENANCE_2_EXTENSION_NAME,
|
||||
VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, video_maintenance2),
|
||||
# endif
|
||||
# if defined(VK_KHR_video_encode_av1)
|
||||
OPTIONAL_VIDEO_EXTENSION (VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME,
|
||||
VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME, video_encode_av1),
|
||||
# endif
|
||||
#endif /* GST_VULKAN_HAVE_VIDEO_EXTENSIONS */
|
||||
};
|
||||
|
||||
|
@ -79,6 +79,7 @@ G_DEFINE_TYPE_WITH_CODE (GstVulkanEncoder, gst_vulkan_encoder,
|
||||
const uint32_t _vk_codec_supported_extensions[] = {
|
||||
[GST_VK_VIDEO_EXTENSION_ENCODE_H264] = VK_MAKE_VIDEO_STD_VERSION (0, 9, 11),
|
||||
[GST_VK_VIDEO_EXTENSION_ENCODE_H265] = VK_MAKE_VIDEO_STD_VERSION (0, 9, 12),
|
||||
[GST_VK_VIDEO_EXTENSION_ENCODE_AV1] = VK_MAKE_VIDEO_STD_VERSION (0, 9, 1),
|
||||
};
|
||||
|
||||
static gboolean
|
||||
@ -648,6 +649,20 @@ gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
codec_idx = GST_VK_VIDEO_EXTENSION_ENCODE_H265;
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:
|
||||
if (!gst_vulkan_video_profile_is_valid (profile, self->codec)) {
|
||||
g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
|
||||
"Invalid profile");
|
||||
return FALSE;
|
||||
}
|
||||
priv->caps.encoder.codec.av1 = (VkVideoEncodeAV1CapabilitiesKHR) {
|
||||
/* *INDENT-OFF* */
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
codec_idx = GST_VK_VIDEO_EXTENSION_ENCODE_AV1;
|
||||
|
||||
break;
|
||||
default:
|
||||
g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
|
||||
@ -919,7 +934,6 @@ gst_vulkan_encoder_video_session_parameters_overrides (GstVulkanEncoder * self,
|
||||
gboolean write;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_ENCODER (self), FALSE);
|
||||
g_return_val_if_fail (params != NULL && feedback != NULL, FALSE);
|
||||
|
||||
priv = gst_vulkan_encoder_get_instance_private (self);
|
||||
if (!priv->started)
|
||||
@ -927,6 +941,7 @@ gst_vulkan_encoder_video_session_parameters_overrides (GstVulkanEncoder * self,
|
||||
|
||||
switch (self->codec) {
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
|
||||
g_return_val_if_fail (params != NULL && feedback != NULL, FALSE);
|
||||
if (params->h264.sType !=
|
||||
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_GET_INFO_KHR) {
|
||||
gst_vulkan_error_to_g_error (GST_VULKAN_ERROR, error,
|
||||
@ -940,6 +955,7 @@ gst_vulkan_encoder_video_session_parameters_overrides (GstVulkanEncoder * self,
|
||||
}
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
|
||||
g_return_val_if_fail (params != NULL && feedback != NULL, FALSE);
|
||||
if (params->h265.sType !=
|
||||
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_GET_INFO_KHR) {
|
||||
gst_vulkan_error_to_g_error (GST_VULKAN_ERROR, error,
|
||||
@ -953,6 +969,10 @@ gst_vulkan_encoder_video_session_parameters_overrides (GstVulkanEncoder * self,
|
||||
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_FEEDBACK_INFO_KHR;
|
||||
}
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:
|
||||
g_return_val_if_fail (params == NULL && feedback == NULL, FALSE);
|
||||
write = TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@ -1373,6 +1393,8 @@ static const struct
|
||||
VK_KHR_VIDEO_ENCODE_H264_EXTENSION_NAME},
|
||||
{VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR,
|
||||
VK_KHR_VIDEO_ENCODE_H265_EXTENSION_NAME},
|
||||
{VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR,
|
||||
VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -132,6 +132,7 @@ union _GstVulkanEncoderParameters
|
||||
/*< private >*/
|
||||
VkVideoEncodeH264SessionParametersCreateInfoKHR h264;
|
||||
VkVideoEncodeH265SessionParametersCreateInfoKHR h265;
|
||||
VkVideoEncodeAV1SessionParametersCreateInfoKHR av1;
|
||||
};
|
||||
|
||||
union _GstVulkanEncoderParametersOverrides
|
||||
@ -154,6 +155,7 @@ struct _GstVulkanEncoderQualityPoperties
|
||||
{
|
||||
VkVideoEncodeH264QualityLevelPropertiesKHR h264;
|
||||
VkVideoEncodeH265QualityLevelPropertiesKHR h265;
|
||||
VkVideoEncodeAV1QualityLevelPropertiesKHR av1;
|
||||
} codec;
|
||||
};
|
||||
|
||||
|
@ -43,6 +43,9 @@ gboolean gst_vulkan_physical_device_has_feature_video_mainten
|
||||
gboolean gst_vulkan_physical_device_has_feature_video_maintenance2
|
||||
(GstVulkanPhysicalDevice * device);
|
||||
|
||||
gboolean gst_vulkan_physical_device_has_feature_video_encode_av1
|
||||
(GstVulkanPhysicalDevice * device);
|
||||
|
||||
static inline void
|
||||
vk_link_struct (gpointer chain, gconstpointer in)
|
||||
{
|
||||
|
@ -87,6 +87,9 @@ struct _GstVulkanPhysicalDevicePrivate
|
||||
#if defined (VK_KHR_video_maintenance2)
|
||||
VkPhysicalDeviceVideoMaintenance2FeaturesKHR videomaintenance2;
|
||||
#endif
|
||||
#if defined (VK_KHR_video_encode_av1)
|
||||
VkPhysicalDeviceVideoEncodeAV1FeaturesKHR video_encoder_av1;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
@ -571,6 +574,12 @@ dump_features_extras (GstVulkanPhysicalDevice * device,
|
||||
videoMaintenance2);
|
||||
}
|
||||
#endif
|
||||
#if defined (VK_KHR_video_encode_av1)
|
||||
if (chain->sType ==
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR) {
|
||||
DEBUG_BOOL_STRUCT ("support for", &priv->video_encoder_av1, videoEncodeAV1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1074,12 +1083,17 @@ add_extra_features (GstVulkanPhysicalDevice * device)
|
||||
#if defined (VK_KHR_video_maintenance1)
|
||||
priv->videomaintenance1.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR;
|
||||
vk_link_struct (&priv->features13, &priv->videomaintenance1);
|
||||
vk_link_struct (&priv->features12, &priv->videomaintenance1);
|
||||
#endif
|
||||
#if defined (VK_KHR_video_maintenance2)
|
||||
priv->videomaintenance2.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR;
|
||||
vk_link_struct (&priv->features13, &priv->videomaintenance2);
|
||||
vk_link_struct (&priv->features12, &priv->videomaintenance2);
|
||||
#endif
|
||||
#if defined (VK_KHR_video_encode_av1)
|
||||
priv->video_encoder_av1.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR;
|
||||
vk_link_struct (&priv->features12, &priv->video_encoder_av1);
|
||||
#endif
|
||||
}
|
||||
#endif /* VK_API_VERSION_1_2 */
|
||||
@ -1502,6 +1516,21 @@ gboolean
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vulkan_physical_device_has_feature_video_encode_av1 (GstVulkanPhysicalDevice
|
||||
* device)
|
||||
{
|
||||
#if defined (VK_KHR_video_encode_av1)
|
||||
GstVulkanPhysicalDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
|
||||
|
||||
priv = GET_PRIV (device);
|
||||
return priv->video_encoder_av1.videoEncodeAV1;
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_physical_device_get_api_version:
|
||||
* @device: a #GstVulkanPhysicalDevice
|
||||
|
@ -45,6 +45,10 @@ const VkExtensionProperties _vk_codec_extensions[] = {
|
||||
[GST_VK_VIDEO_EXTENSION_ENCODE_H265] = {
|
||||
.extensionName = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME,
|
||||
.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION,
|
||||
},
|
||||
[GST_VK_VIDEO_EXTENSION_ENCODE_AV1] = {
|
||||
.extensionName = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME,
|
||||
.specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,6 +45,7 @@ typedef enum {
|
||||
GST_VK_VIDEO_EXTENSION_DECODE_H265,
|
||||
GST_VK_VIDEO_EXTENSION_ENCODE_H264,
|
||||
GST_VK_VIDEO_EXTENSION_ENCODE_H265,
|
||||
GST_VK_VIDEO_EXTENSION_ENCODE_AV1,
|
||||
} GST_VK_VIDEO_EXTENSIONS;
|
||||
|
||||
#define GST_VULKAN_VIDEO_FN_LIST(V) \
|
||||
@ -73,7 +74,7 @@ struct _GstVulkanVideoFunctions
|
||||
#undef DEFINE_FUNCTION
|
||||
};
|
||||
|
||||
extern const VkExtensionProperties _vk_codec_extensions[4];
|
||||
extern const VkExtensionProperties _vk_codec_extensions[5];
|
||||
extern const VkComponentMapping _vk_identity_component_map;
|
||||
|
||||
gboolean gst_vulkan_video_get_vk_functions (GstVulkanInstance * instance,
|
||||
|
@ -39,6 +39,8 @@ static const struct {
|
||||
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR },
|
||||
{ GST_VULKAN_VIDEO_OPERATION_ENCODE, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR, "video/x-h265",
|
||||
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR },
|
||||
{ GST_VULKAN_VIDEO_OPERATION_ENCODE, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR, "video/x-av1",
|
||||
VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
@ -92,6 +94,14 @@ static const struct {
|
||||
{ STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS, "scc-extensions" },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
StdVideoAV1Profile vk_profile;
|
||||
const char *profile_str;
|
||||
} av1_profile_map[] = {
|
||||
{ STD_VIDEO_AV1_PROFILE_MAIN, "main" },
|
||||
{ STD_VIDEO_AV1_PROFILE_HIGH, "high" },
|
||||
{ STD_VIDEO_AV1_PROFILE_PROFESSIONAL, "professional" },
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**
|
||||
@ -168,6 +178,16 @@ gst_vulkan_video_profile_to_caps (const GstVulkanVideoProfile * profile)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:
|
||||
if (profile->codec.av1enc.sType == video_codecs_map[i].stype) {
|
||||
int j;
|
||||
for (j = 0; j < G_N_ELEMENTS (av1_profile_map); j++) {
|
||||
if (profile->codec.av1enc.stdProfile
|
||||
== av1_profile_map[j].vk_profile)
|
||||
profile_str = av1_profile_map[j].profile_str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -336,6 +356,22 @@ gst_vulkan_video_profile_from_caps (GstVulkanVideoProfile * profile,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:{
|
||||
int j;
|
||||
|
||||
profile->codec.av1enc.sType = video_codecs_map[i].stype;
|
||||
profile->codec.av1enc.stdProfile = STD_VIDEO_AV1_PROFILE_INVALID;
|
||||
profile->profile.pNext = &profile->codec;
|
||||
|
||||
profile_str = gst_structure_get_string (structure, "profile");
|
||||
for (j = 0; profile_str && j < G_N_ELEMENTS (av1_profile_map); j++) {
|
||||
if (g_strcmp0 (profile_str, av1_profile_map[j].profile_str) == 0) {
|
||||
profile->codec.av1enc.stdProfile = av1_profile_map[j].vk_profile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
profile->usage.decode.pNext = NULL;
|
||||
break;
|
||||
|
@ -65,6 +65,12 @@ struct _GstVulkanVideoProfile
|
||||
* Since: 1.26
|
||||
**/
|
||||
VkVideoEncodeH265ProfileInfoKHR h265enc;
|
||||
/**
|
||||
* GstVulkanVideoProfile.usage.codec.av1enc:
|
||||
*
|
||||
* Since: 1.28
|
||||
**/
|
||||
VkVideoEncodeAV1ProfileInfoKHR av1enc;
|
||||
} codec;
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
@ -100,6 +106,13 @@ struct _GstVulkanVideoCapabilities
|
||||
/*< private >*/
|
||||
VkVideoEncodeH264CapabilitiesKHR h264;
|
||||
VkVideoEncodeH265CapabilitiesKHR h265;
|
||||
/**
|
||||
* _GstVulkanVideoCapabilities.encoder.codec.av1:
|
||||
*
|
||||
* Since: 1.28
|
||||
**/
|
||||
VkVideoEncodeAV1CapabilitiesKHR av1;
|
||||
|
||||
} codec;
|
||||
} encoder;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user