mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
vkencoder-private: handle quality level
It creates a new structure for passing the codec quality structure at _start(), where it will be filled. The quality level can be set or changed according encoder limits. Later the quality level will be set at _update_session_parameters() and at each frame encoding. That's why it has to be set at _start(). Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8007>
This commit is contained in:
parent
d63ec09b5e
commit
ab6aafb076
5 changed files with 122 additions and 21 deletions
|
@ -50,6 +50,8 @@ struct _GstVulkanEncoderPrivate
|
|||
|
||||
GstVulkanEncoderPicture *slots[32];
|
||||
|
||||
guint32 quality;
|
||||
|
||||
gboolean started;
|
||||
gboolean session_reset;
|
||||
|
||||
|
@ -222,6 +224,7 @@ gst_vulkan_encoder_new_video_session_parameters (GstVulkanEncoder * self,
|
|||
{
|
||||
GstVulkanEncoderPrivate *priv;
|
||||
VkVideoSessionParametersCreateInfoKHR session_params_info;
|
||||
VkVideoEncodeQualityLevelInfoKHR quality_info;
|
||||
VkResult res;
|
||||
VkVideoSessionParametersKHR session_params;
|
||||
|
||||
|
@ -234,9 +237,14 @@ gst_vulkan_encoder_new_video_session_parameters (GstVulkanEncoder * self,
|
|||
return NULL;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
quality_info = (VkVideoEncodeQualityLevelInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
|
||||
.pNext = params,
|
||||
.qualityLevel = priv->quality,
|
||||
};
|
||||
session_params_info = (VkVideoSessionParametersCreateInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.pNext = params,
|
||||
.pNext = &quality_info,
|
||||
.videoSession = priv->session.session->handle,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
@ -406,6 +414,30 @@ gst_vulkan_encoder_profile_caps (GstVulkanEncoder * self)
|
|||
return gst_caps_ref (priv->profile_caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_encoder_quality_level:
|
||||
* @self: a #GstVulkanEncoder
|
||||
*
|
||||
* Get the current encoding quality level.
|
||||
*
|
||||
* Returns: whether the encoder has started, it will return the quality level;
|
||||
* otherwise it will return -1
|
||||
*/
|
||||
gint32
|
||||
gst_vulkan_encoder_quality_level (GstVulkanEncoder * self)
|
||||
{
|
||||
GstVulkanEncoderPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_ENCODER (self), -1);
|
||||
|
||||
priv = gst_vulkan_encoder_get_instance_private (self);
|
||||
|
||||
if (!priv->started)
|
||||
return -1;
|
||||
|
||||
return priv->quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_encoder_stop:
|
||||
* @self: a #GstVulkanEncoder
|
||||
|
@ -448,6 +480,7 @@ gst_vulkan_encoder_stop (GstVulkanEncoder * self)
|
|||
* gst_vulkan_encoder_start:
|
||||
* @self: a #GstVulkanEncoder
|
||||
* @profile: a #GstVulkanVideoProfile
|
||||
* @codec_quality_props: codec specific quality structure to fetch
|
||||
* @error: (out) : an error result in case of failure or %NULL
|
||||
*
|
||||
* Start the encoding session according to a valid Vulkan profile
|
||||
|
@ -457,7 +490,8 @@ gst_vulkan_encoder_stop (GstVulkanEncoder * self)
|
|||
*/
|
||||
gboolean
|
||||
gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
||||
GstVulkanVideoProfile * profile, GError ** error)
|
||||
GstVulkanVideoProfile * profile,
|
||||
GstVulkanEncoderQualityProperties * codec_quality_props, GError ** error)
|
||||
{
|
||||
GstVulkanEncoderPrivate *priv;
|
||||
VkResult res;
|
||||
|
@ -467,10 +501,13 @@ gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
|||
int codec_idx;
|
||||
GstVulkanCommandPool *cmd_pool;
|
||||
VkQueryPoolVideoEncodeFeedbackCreateInfoKHR query_create;
|
||||
VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR quality_info;
|
||||
VkVideoEncodeQualityLevelPropertiesKHR quality_props;
|
||||
GError *query_err = NULL;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_ENCODER (self), FALSE);
|
||||
g_return_val_if_fail (profile != NULL, FALSE);
|
||||
g_return_val_if_fail (codec_quality_props != NULL, FALSE);
|
||||
|
||||
priv = gst_vulkan_encoder_get_instance_private (self);
|
||||
|
||||
|
@ -652,6 +689,31 @@ gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
|||
!(priv->caps.
|
||||
caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
|
||||
|
||||
if (codec_quality_props->quality_level >= 0) {
|
||||
priv->quality = MIN (codec_quality_props->quality_level,
|
||||
priv->caps.encoder.caps.maxQualityLevels - 1);
|
||||
} else {
|
||||
priv->quality = priv->caps.encoder.caps.maxQualityLevels / 2;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
quality_info = (VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
|
||||
.pVideoProfile = &profile->profile,
|
||||
.qualityLevel = priv->quality,
|
||||
};
|
||||
quality_props = (VkVideoEncodeQualityLevelPropertiesKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR,
|
||||
.pNext = &codec_quality_props->codec,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
res = priv->vk.GetPhysicalDeviceVideoEncodeQualityLevelProperties (gpu,
|
||||
&quality_info, &quality_props);
|
||||
if (gst_vulkan_error_to_g_error (res, error,
|
||||
"vketPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR")
|
||||
!= VK_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
session_create = (VkVideoSessionCreateInfoKHR) {
|
||||
|
@ -943,6 +1005,7 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
VkVideoReferenceSlotInfoKHR ref_slots[37];
|
||||
GstVulkanCommandBuffer *cmd_buf;
|
||||
GArray *barriers;
|
||||
VkVideoEncodeQualityLevelInfoKHR quality_info;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_ENCODER (self), FALSE);
|
||||
g_return_val_if_fail (info != NULL && pic != NULL, FALSE);
|
||||
|
@ -954,9 +1017,16 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
goto bail;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
quality_info = (VkVideoEncodeQualityLevelInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.qualityLevel = priv->quality,
|
||||
};
|
||||
coding_ctrl = (VkVideoCodingControlInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
|
||||
.flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
|
||||
.pNext = &quality_info,
|
||||
.flags = VK_VIDEO_CODING_CONTROL_ENCODE_QUALITY_LEVEL_BIT_KHR
|
||||
| VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ GType gst_vulkan_encoder_get_type (void);
|
|||
|
||||
typedef struct _GstVulkanEncoder GstVulkanEncoder;
|
||||
typedef struct _GstVulkanEncoderClass GstVulkanEncoderClass;
|
||||
typedef struct _GstVulkanEncoderQualityPoperties GstVulkanEncoderQualityProperties;
|
||||
typedef union _GstVulkanEncoderParameters GstVulkanEncoderParameters;
|
||||
typedef union _GstVulkanEncoderParametersOverrides GstVulkanEncoderParametersOverrides;
|
||||
typedef union _GstVulkanEncoderParametersFeedback GstVulkanEncoderParametersFeedback;
|
||||
|
@ -121,6 +122,16 @@ union _GstVulkanEncoderParametersFeedback
|
|||
VkVideoEncodeH265SessionParametersFeedbackInfoKHR h265;
|
||||
};
|
||||
|
||||
struct _GstVulkanEncoderQualityPoperties
|
||||
{
|
||||
gint32 quality_level;
|
||||
union
|
||||
{
|
||||
VkVideoEncodeH264QualityLevelPropertiesKHR h264;
|
||||
VkVideoEncodeH265QualityLevelPropertiesKHR h265;
|
||||
} codec;
|
||||
};
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstVulkanEncoder, gst_object_unref)
|
||||
|
||||
GST_VULKAN_API
|
||||
|
@ -130,6 +141,7 @@ GstVulkanEncoder * gst_vulkan_encoder_create_from_queue (GstVulkanQueue
|
|||
GST_VULKAN_API
|
||||
gboolean gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
||||
GstVulkanVideoProfile * profile,
|
||||
GstVulkanEncoderQualityProperties * codec_quality_props,
|
||||
GError ** error);
|
||||
GST_VULKAN_API
|
||||
gboolean gst_vulkan_encoder_stop (GstVulkanEncoder * self);
|
||||
|
@ -160,6 +172,9 @@ gboolean gst_vulkan_encoder_caps (GstVulkanEncode
|
|||
GstVulkanVideoCapabilities * caps);
|
||||
GST_VULKAN_API
|
||||
GstCaps * gst_vulkan_encoder_profile_caps (GstVulkanEncoder * self);
|
||||
GST_VULKAN_API
|
||||
gint32 gst_vulkan_encoder_quality_level (GstVulkanEncoder * self);
|
||||
|
||||
GST_VULKAN_API
|
||||
gboolean gst_vulkan_encoder_picture_init (GstVulkanEncoderPicture * pic,
|
||||
GstVulkanEncoder * self,
|
||||
|
|
|
@ -63,7 +63,8 @@ typedef enum {
|
|||
V(CmdEndVideoCoding) \
|
||||
V(CmdDecodeVideo) \
|
||||
V(CmdEncodeVideo) \
|
||||
V(GetEncodedVideoSessionParameters)
|
||||
V(GetEncodedVideoSessionParameters) \
|
||||
V(GetPhysicalDeviceVideoEncodeQualityLevelProperties)
|
||||
|
||||
struct _GstVulkanVideoFunctions
|
||||
{
|
||||
|
|
|
@ -595,9 +595,10 @@ setup_h264_encoder (guint32 width, gint32 height, gint sps_id, gint pps_id)
|
|||
StdVideoH264ProfileIdc profile_idc = STD_VIDEO_H264_PROFILE_IDC_HIGH;
|
||||
GstVulkanEncoderParameters enc_params;
|
||||
VkVideoEncodeH264SessionParametersAddInfoKHR params_add;
|
||||
GstVulkanEncoderQualityProperties quality_props;
|
||||
|
||||
profile = (GstVulkanVideoProfile) {
|
||||
/* *INDENT-OFF* */
|
||||
profile = (GstVulkanVideoProfile) {
|
||||
.profile = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR,
|
||||
.pNext = &profile.usage.encode,
|
||||
|
@ -617,8 +618,14 @@ setup_h264_encoder (guint32 width, gint32 height, gint sps_id, gint pps_id)
|
|||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR,
|
||||
.stdProfileIdc = profile_idc,
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
quality_props = (GstVulkanEncoderQualityProperties) {
|
||||
.quality_level = -1,
|
||||
.codec.h264 = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_QUALITY_LEVEL_PROPERTIES_KHR,
|
||||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
for (i = 0; i < instance->n_physical_devices; i++) {
|
||||
GstVulkanDevice *device = gst_vulkan_device_new_with_index (instance, i);
|
||||
|
@ -649,7 +656,11 @@ setup_h264_encoder (guint32 width, gint32 height, gint sps_id, gint pps_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
fail_unless (gst_vulkan_encoder_start (enc, &profile, &err));
|
||||
fail_unless (gst_vulkan_encoder_quality_level (enc) == -1);
|
||||
|
||||
fail_unless (gst_vulkan_encoder_start (enc, &profile, &quality_props, &err));
|
||||
|
||||
fail_unless (gst_vulkan_encoder_quality_level (enc) > -1);
|
||||
|
||||
mbAlignedWidth = GST_ROUND_UP_16 (width);
|
||||
mbAlignedHeight = GST_ROUND_UP_16 (height);
|
||||
|
@ -663,24 +674,21 @@ setup_h264_encoder (guint32 width, gint32 height, gint sps_id, gint pps_id)
|
|||
h264_std_sps.frame_crop_right_offset = mbAlignedWidth - width;
|
||||
h264_std_sps.frame_crop_bottom_offset = mbAlignedHeight - height;
|
||||
|
||||
params_add = (VkVideoEncodeH264SessionParametersAddInfoKHR) {
|
||||
/* *INDENT-OFF* */
|
||||
params_add = (VkVideoEncodeH264SessionParametersAddInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR,
|
||||
.pStdSPSs = &h264_std_sps,
|
||||
.stdSPSCount = 1,
|
||||
.pStdPPSs = &h264_std_pps,
|
||||
.stdPPSCount = 1,
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
enc_params.h264 = (VkVideoEncodeH264SessionParametersCreateInfoKHR) {
|
||||
/* *INDENT-OFF* */
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.maxStdSPSCount = 1,
|
||||
.maxStdPPSCount = 1,
|
||||
.pParametersAddInfo = ¶ms_add
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
fail_unless (gst_vulkan_encoder_update_video_session_parameters (enc,
|
||||
&enc_params, &err));
|
||||
|
|
|
@ -696,9 +696,10 @@ setup_h265_encoder (uint32_t width, uint32_t height, gint vps_id,
|
|||
gint min_ctb_size = 64, max_ctb_size = 16;
|
||||
gint max_tb_size = 0, min_tb_size = 0;
|
||||
gint max_transform_hierarchy;
|
||||
GstVulkanEncoderQualityProperties quality_props;
|
||||
|
||||
profile = (GstVulkanVideoProfile) {
|
||||
/* *INDENT-OFF* */
|
||||
profile = (GstVulkanVideoProfile) {
|
||||
.profile = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR,
|
||||
.pNext = &profile.codec,
|
||||
|
@ -718,8 +719,14 @@ setup_h265_encoder (uint32_t width, uint32_t height, gint vps_id,
|
|||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR,
|
||||
.stdProfileIdc = profile_idc,
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
quality_props = (GstVulkanEncoderQualityProperties) {
|
||||
.quality_level = -1,
|
||||
.codec.h265 = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_QUALITY_LEVEL_PROPERTIES_KHR,
|
||||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
for (i = 0; i < instance->n_physical_devices; i++) {
|
||||
GstVulkanDevice *device = gst_vulkan_device_new_with_index (instance, i);
|
||||
|
@ -750,11 +757,14 @@ setup_h265_encoder (uint32_t width, uint32_t height, gint vps_id,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
fail_unless (gst_vulkan_encoder_start (enc, &profile, &err));
|
||||
fail_unless (gst_vulkan_encoder_quality_level (enc) == -1);
|
||||
|
||||
fail_unless (gst_vulkan_encoder_start (enc, &profile, &quality_props, &err));
|
||||
|
||||
fail_unless (gst_vulkan_encoder_quality_level (enc) > -1);
|
||||
|
||||
fail_unless (gst_vulkan_encoder_caps (enc, &enc_caps));
|
||||
|
||||
|
||||
if (enc_caps.encoder.codec.h265.ctbSizes
|
||||
& VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR)
|
||||
max_ctb_size = 64;
|
||||
|
@ -834,8 +844,8 @@ setup_h265_encoder (uint32_t width, uint32_t height, gint vps_id,
|
|||
h265_std_pps.pps_seq_parameter_set_id = sps_id;
|
||||
h265_std_pps.pps_pic_parameter_set_id = pps_id;
|
||||
|
||||
params_add = (VkVideoEncodeH265SessionParametersAddInfoKHR) {
|
||||
/* *INDENT-OFF* */
|
||||
params_add = (VkVideoEncodeH265SessionParametersAddInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR,
|
||||
.pStdVPSs = &h265_std_vps,
|
||||
.stdVPSCount = 1,
|
||||
|
@ -843,18 +853,15 @@ setup_h265_encoder (uint32_t width, uint32_t height, gint vps_id,
|
|||
.stdSPSCount = 1,
|
||||
.pStdPPSs = &h265_std_pps,
|
||||
.stdPPSCount = 1,
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
enc_params.h265 = (VkVideoEncodeH265SessionParametersCreateInfoKHR) {
|
||||
/* *INDENT-OFF* */
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.maxStdVPSCount = 1,
|
||||
.maxStdSPSCount = 1,
|
||||
.maxStdPPSCount = 1,
|
||||
.pParametersAddInfo = ¶ms_add
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
fail_unless (gst_vulkan_encoder_update_video_session_parameters (enc,
|
||||
&enc_params, &err));
|
||||
|
|
Loading…
Reference in a new issue