mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 21:06:17 +00:00
vkencoder-private: enhance algorithm to get the slot index
The algorithm for generating the current slot index is a simple round robin, nonetheless it's not assured that the next slot index it's not still used by a still living encode picture. This new way holds an array with the still living encode pictures and the next slot index looks for a released index in the array. Its downside is deallocating a picture need to be removed from the array, so the helper has to be passed to the uninit() function Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8007>
This commit is contained in:
parent
d4de932664
commit
8fc2af44c8
4 changed files with 47 additions and 34 deletions
|
@ -61,7 +61,7 @@ struct _GstVulkanEncoderPrivate
|
|||
gboolean vk_loaded;
|
||||
GstVulkanVideoFunctions vk;
|
||||
|
||||
gint current_slot_index;
|
||||
GstVulkanEncoderPicture *slots[32];
|
||||
|
||||
gboolean started;
|
||||
gboolean first_encode_cmd;
|
||||
|
@ -436,14 +436,26 @@ gst_vulkan_encoder_picture_init (GstVulkanEncoderPicture * pic,
|
|||
/**
|
||||
* gst_vulkan_encoder_picture_clear:
|
||||
* @pic: the #GstVulkanEncoderPicture to free.
|
||||
* @self: the #GstVulkanEncoder instance.
|
||||
*
|
||||
* Release data of @pic.
|
||||
*/
|
||||
void
|
||||
gst_vulkan_encoder_picture_clear (GstVulkanEncoderPicture * pic)
|
||||
gst_vulkan_encoder_picture_clear (GstVulkanEncoderPicture * pic,
|
||||
GstVulkanEncoder * self)
|
||||
{
|
||||
GstVulkanEncoderPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_VULKAN_ENCODER (self));
|
||||
g_return_if_fail (pic != NULL);
|
||||
|
||||
priv = gst_vulkan_encoder_get_instance_private (self);
|
||||
|
||||
if (pic->dpb_slot.slotIndex > 0) {
|
||||
priv->slots[pic->dpb_slot.slotIndex] = NULL;
|
||||
pic->dpb_slot.slotIndex = -1;
|
||||
}
|
||||
|
||||
gst_clear_buffer (&pic->in_buffer);
|
||||
gst_clear_buffer (&pic->dpb_buffer);
|
||||
gst_clear_buffer (&pic->out_buffer);
|
||||
|
@ -1069,7 +1081,7 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
GError *err = NULL;
|
||||
gboolean ret = TRUE;
|
||||
GstMemory *mem;
|
||||
int i;
|
||||
int i, slot_index = -1;
|
||||
GstVulkanEncodeQueryResult *encode_res;
|
||||
VkVideoEncodeRateControlLayerInfoKHR rate_control_layer;
|
||||
VkVideoEncodeQualityLevelInfoKHR quality_level_info;
|
||||
|
@ -1077,7 +1089,6 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
VkVideoBeginCodingInfoKHR begin_coding;
|
||||
VkVideoEncodeInfoKHR encode_info;
|
||||
VkVideoEndCodingInfoKHR end_coding;
|
||||
gint maxDpbSlots;
|
||||
VkVideoReferenceSlotInfoKHR ref_slots[37];
|
||||
GstVulkanCommandBuffer *cmd_buf;
|
||||
GArray *barriers;
|
||||
|
@ -1087,8 +1098,6 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
|
||||
priv = gst_vulkan_encoder_get_instance_private (self);
|
||||
|
||||
maxDpbSlots = priv->layered_dpb ? 2 : priv->caps.caps.maxDpbSlots;
|
||||
|
||||
/* initialize the vulkan operation */
|
||||
if (!gst_vulkan_operation_begin (priv->exec, &err))
|
||||
goto bail;
|
||||
|
@ -1108,7 +1117,6 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
|
||||
/* First run, some information such as rate_control and slot index must be initialized. */
|
||||
if (!priv->first_encode_cmd) {
|
||||
priv->current_slot_index = 0;
|
||||
GST_OBJECT_LOCK (self);
|
||||
/* *INDENT-OFF* */
|
||||
rate_control_layer = (VkVideoEncodeRateControlLayerInfoKHR) {
|
||||
|
@ -1150,6 +1158,16 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
g_assert (pic->in_buffer && pic->img_view);
|
||||
g_assert (pic->out_buffer);
|
||||
|
||||
/* Attribute a free slot index to the picture to be used later as a reference.
|
||||
* The picture is kept until it remains useful to the encoding process.*/
|
||||
for (i = 0; i < priv->caps.caps.maxDpbSlots; i++) {
|
||||
if (!priv->slots[i]) {
|
||||
priv->slots[i] = pic;
|
||||
slot_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the ref slots according to the pic refs to bound the video
|
||||
session encoding. It should contain all the references + 1 to book
|
||||
a new slotIndex (-1) for the current picture. */
|
||||
|
@ -1168,7 +1186,7 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
pic->dpb_slot = (VkVideoReferenceSlotInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
|
||||
.pNext = pic->codec_dpb_slot_info,
|
||||
.slotIndex = priv->current_slot_index,
|
||||
.slotIndex = slot_index,
|
||||
.pPictureResource = &pic->dpb,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
@ -1229,12 +1247,6 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
/* Peek the output memory to be used by VkVideoEncodeInfoKHR.dstBuffer */
|
||||
mem = gst_buffer_peek_memory (pic->out_buffer, 0);
|
||||
|
||||
/* Attribute a free slot index to the picture to be used later as a reference.
|
||||
* The picture is kept until it remains useful to the encoding process.*/
|
||||
priv->current_slot_index++;
|
||||
if (priv->current_slot_index >= maxDpbSlots)
|
||||
priv->current_slot_index = 0;
|
||||
|
||||
/* Setup the encode info */
|
||||
/* *INDENT-OFF* */
|
||||
encode_info = (VkVideoEncodeInfoKHR) {
|
||||
|
@ -1244,7 +1256,7 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
|||
.dstBuffer = ((GstVulkanBufferMemory *) mem)->buffer,
|
||||
.dstBufferOffset = pic->offset,
|
||||
.dstBufferRange = gst_memory_get_sizes (mem, NULL, NULL),
|
||||
.srcPictureResource = (VkVideoPictureResourceInfoKHR) { // SPEC: this should be separate
|
||||
.srcPictureResource = (VkVideoPictureResourceInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.codedOffset = { 0, 0 },
|
||||
|
|
|
@ -168,4 +168,5 @@ gboolean gst_vulkan_encoder_picture_init (GstVulkanEncode
|
|||
GstBuffer * in_buffer,
|
||||
gsize size);
|
||||
GST_VULKAN_API
|
||||
void gst_vulkan_encoder_picture_clear (GstVulkanEncoderPicture * pic);
|
||||
void gst_vulkan_encoder_picture_clear (GstVulkanEncoderPicture * pic,
|
||||
GstVulkanEncoder * self);
|
||||
|
|
|
@ -79,11 +79,11 @@ _h264_encode_frame_new (GstVulkanEncoder * enc, GstBuffer * img_buffer,
|
|||
}
|
||||
|
||||
static void
|
||||
_h264_encode_frame_free (gpointer pframe)
|
||||
_h264_encode_frame_free (GstVulkanEncoder * enc, gpointer pframe)
|
||||
{
|
||||
GstVulkanH264EncodeFrame *frame = pframe;
|
||||
|
||||
gst_vulkan_encoder_picture_clear (&frame->picture);
|
||||
gst_vulkan_encoder_picture_clear (&frame->picture, enc);
|
||||
g_free (frame);
|
||||
}
|
||||
|
||||
|
@ -803,7 +803,7 @@ GST_START_TEST (test_encoder_h264_i)
|
|||
check_encoded_frame (frame, GST_H264_NAL_SLICE_IDR);
|
||||
|
||||
frame_num++;
|
||||
_h264_encode_frame_free (frame);
|
||||
_h264_encode_frame_free (enc, frame);
|
||||
}
|
||||
|
||||
fail_unless (gst_buffer_pool_set_active (buffer_pool, FALSE));
|
||||
|
@ -855,12 +855,12 @@ GST_START_TEST (test_encoder_h264_i_p)
|
|||
encode_frame (enc, frame, STD_VIDEO_H264_SLICE_TYPE_P,
|
||||
frame_num, list0, list0_num, NULL, 0, sps_id, pps_id);
|
||||
check_encoded_frame (frame, GST_H264_NAL_SLICE);
|
||||
_h264_encode_frame_free (list0[0]);
|
||||
_h264_encode_frame_free (enc, list0[0]);
|
||||
list0[0] = frame;
|
||||
frame_num++;
|
||||
}
|
||||
|
||||
_h264_encode_frame_free (list0[0]);
|
||||
_h264_encode_frame_free (enc, list0[0]);
|
||||
|
||||
fail_unless (gst_buffer_pool_set_active (buffer_pool, FALSE));
|
||||
gst_object_unref (buffer_pool);
|
||||
|
@ -931,7 +931,7 @@ GST_START_TEST (test_encoder_h264_i_p_b)
|
|||
frame_num, list0, list0_num, list1, list1_num, sps_id, pps_id);
|
||||
check_encoded_frame (frame, GST_H264_NAL_SLICE);
|
||||
frame_num++;
|
||||
_h264_encode_frame_free (frame);
|
||||
_h264_encode_frame_free (enc, frame);
|
||||
|
||||
/* Encode third picture as a B-Frame */
|
||||
frame = allocate_frame (enc, width, height, FALSE);
|
||||
|
@ -942,10 +942,10 @@ GST_START_TEST (test_encoder_h264_i_p_b)
|
|||
frame_num, list0, list0_num, list1, list1_num, sps_id, pps_id);
|
||||
check_encoded_frame (frame, GST_H264_NAL_SLICE);
|
||||
frame_num++;
|
||||
_h264_encode_frame_free (frame);
|
||||
_h264_encode_frame_free (enc, frame);
|
||||
|
||||
_h264_encode_frame_free (list0[0]);
|
||||
_h264_encode_frame_free (list1[0]);
|
||||
_h264_encode_frame_free (enc, list0[0]);
|
||||
_h264_encode_frame_free (enc, list1[0]);
|
||||
|
||||
fail_unless (gst_buffer_pool_set_active (buffer_pool, FALSE));
|
||||
gst_object_unref (buffer_pool);
|
||||
|
|
|
@ -84,11 +84,11 @@ _h265_encode_frame_new (GstVulkanEncoder * enc, GstBuffer * img_buffer,
|
|||
}
|
||||
|
||||
static void
|
||||
_h265_encode_frame_free (gpointer pframe)
|
||||
_h265_encode_frame_free (GstVulkanEncoder * enc, gpointer pframe)
|
||||
{
|
||||
GstVulkanH265EncodeFrame *frame = pframe;
|
||||
|
||||
gst_vulkan_encoder_picture_clear (&frame->picture);
|
||||
gst_vulkan_encoder_picture_clear (&frame->picture, enc);
|
||||
g_free (frame);
|
||||
}
|
||||
|
||||
|
@ -975,7 +975,7 @@ GST_START_TEST (test_encoder_h265_i)
|
|||
check_encoded_frame (frame, GST_H265_NAL_SLICE_IDR_W_RADL);
|
||||
|
||||
frame_num++;
|
||||
_h265_encode_frame_free (frame);
|
||||
_h265_encode_frame_free (enc, frame);
|
||||
}
|
||||
|
||||
fail_unless (gst_buffer_pool_set_active (buffer_pool, FALSE));
|
||||
|
@ -1026,11 +1026,11 @@ GST_START_TEST (test_encoder_h265_i_p)
|
|||
encode_frame (enc, frame, STD_VIDEO_H265_SLICE_TYPE_P,
|
||||
frame_num, list0, list0_num, NULL, 0, vps_id, sps_id, pps_id);
|
||||
check_encoded_frame (frame, GST_H265_NAL_SLICE_TRAIL_R);
|
||||
_h265_encode_frame_free (list0[0]);
|
||||
_h265_encode_frame_free (enc, list0[0]);
|
||||
list0[0] = frame;
|
||||
frame_num++;
|
||||
}
|
||||
_h265_encode_frame_free (list0[0]);
|
||||
_h265_encode_frame_free (enc, list0[0]);
|
||||
fail_unless (gst_buffer_pool_set_active (buffer_pool, FALSE));
|
||||
gst_object_unref (buffer_pool);
|
||||
fail_unless (gst_buffer_pool_set_active (img_pool, FALSE));
|
||||
|
@ -1098,7 +1098,7 @@ GST_START_TEST (test_encoder_h265_i_p_b)
|
|||
frame_num, list0, list0_num, list1, list1_num, vps_id, sps_id, pps_id);
|
||||
check_encoded_frame (frame, GST_H265_NAL_SLICE_TRAIL_N);
|
||||
frame_num++;
|
||||
_h265_encode_frame_free (frame);
|
||||
_h265_encode_frame_free (enc, frame);
|
||||
|
||||
/* Encode 3rd picture as a B-Frame */
|
||||
frame = allocate_frame (enc, width, height, FALSE);
|
||||
|
@ -1107,10 +1107,10 @@ GST_START_TEST (test_encoder_h265_i_p_b)
|
|||
frame_num, list0, list0_num, list1, list1_num, vps_id, sps_id, pps_id);
|
||||
check_encoded_frame (frame, GST_H265_NAL_SLICE_TRAIL_N);
|
||||
frame_num++;
|
||||
_h265_encode_frame_free (frame);
|
||||
_h265_encode_frame_free (enc, frame);
|
||||
|
||||
_h265_encode_frame_free (list0[0]);
|
||||
_h265_encode_frame_free (list1[0]);
|
||||
_h265_encode_frame_free (enc, list0[0]);
|
||||
_h265_encode_frame_free (enc, list1[0]);
|
||||
|
||||
fail_unless (gst_buffer_pool_set_active (buffer_pool, FALSE));
|
||||
gst_object_unref (buffer_pool);
|
||||
|
|
Loading…
Reference in a new issue