mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
vkencoder-private: implement callback to chain codec specific structures
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8007>
This commit is contained in:
parent
ab6aafb076
commit
b99276a7f9
4 changed files with 127 additions and 42 deletions
|
@ -37,6 +37,10 @@ struct _GstVulkanEncoderPrivate
|
||||||
|
|
||||||
GstCaps *profile_caps;
|
GstCaps *profile_caps;
|
||||||
|
|
||||||
|
GstVulkanEncoderCallbacks callbacks;
|
||||||
|
gpointer callbacks_user_data;
|
||||||
|
GDestroyNotify callbacks_notify;
|
||||||
|
|
||||||
GstVulkanOperation *exec;
|
GstVulkanOperation *exec;
|
||||||
|
|
||||||
GstVulkanVideoSession session;
|
GstVulkanVideoSession session;
|
||||||
|
@ -106,6 +110,14 @@ static void
|
||||||
gst_vulkan_encoder_finalize (GObject * object)
|
gst_vulkan_encoder_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstVulkanEncoder *self = GST_VULKAN_ENCODER (object);
|
GstVulkanEncoder *self = GST_VULKAN_ENCODER (object);
|
||||||
|
GstVulkanEncoderPrivate *priv =
|
||||||
|
gst_vulkan_encoder_get_instance_private (self);
|
||||||
|
|
||||||
|
if (priv->callbacks_user_data && priv->callbacks_notify) {
|
||||||
|
priv->callbacks_notify (priv->callbacks_user_data);
|
||||||
|
priv->callbacks_user_data = NULL;
|
||||||
|
priv->callbacks_notify = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
gst_clear_object (&self->queue);
|
gst_clear_object (&self->queue);
|
||||||
|
|
||||||
|
@ -1066,7 +1078,7 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
||||||
};
|
};
|
||||||
pic->dpb_slot = (VkVideoReferenceSlotInfoKHR) {
|
pic->dpb_slot = (VkVideoReferenceSlotInfoKHR) {
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
|
||||||
.pNext = pic->codec_dpb_slot_info,
|
.pNext = NULL, /* to fill in callback */
|
||||||
.slotIndex = slot_index,
|
.slotIndex = slot_index,
|
||||||
.pPictureResource = &pic->dpb,
|
.pPictureResource = &pic->dpb,
|
||||||
};
|
};
|
||||||
|
@ -1110,7 +1122,7 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
encode_info = (VkVideoEncodeInfoKHR) {
|
encode_info = (VkVideoEncodeInfoKHR) {
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR,
|
||||||
.pNext = pic->codec_pic_info,
|
.pNext = NULL, /* to fill in callback */
|
||||||
.flags = 0x0,
|
.flags = 0x0,
|
||||||
.dstBuffer = ((GstVulkanBufferMemory *) mem)->buffer,
|
.dstBuffer = ((GstVulkanBufferMemory *) mem)->buffer,
|
||||||
.dstBufferOffset = pic->offset,
|
.dstBufferOffset = pic->offset,
|
||||||
|
@ -1137,6 +1149,10 @@ gst_vulkan_encoder_encode (GstVulkanEncoder * self, GstVideoInfo * info,
|
||||||
encode_info.dstBufferRange = GST_ROUND_DOWN_N (encode_info.dstBufferRange,
|
encode_info.dstBufferRange = GST_ROUND_DOWN_N (encode_info.dstBufferRange,
|
||||||
priv->caps.caps.minBitstreamBufferSizeAlignment);
|
priv->caps.caps.minBitstreamBufferSizeAlignment);
|
||||||
|
|
||||||
|
g_assert (priv->callbacks.setup_codec_pic);
|
||||||
|
priv->callbacks.setup_codec_pic (pic, &encode_info,
|
||||||
|
priv->callbacks_user_data);
|
||||||
|
|
||||||
gst_vulkan_operation_add_dependency_frame (priv->exec, pic->in_buffer,
|
gst_vulkan_operation_add_dependency_frame (priv->exec, pic->in_buffer,
|
||||||
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||||
VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
|
VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
|
||||||
|
@ -1277,3 +1293,21 @@ gst_vulkan_encoder_create_from_queue (GstVulkanQueue * queue, guint codec)
|
||||||
|
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_vulkan_encoder_set_callbacks (GstVulkanEncoder * self,
|
||||||
|
GstVulkanEncoderCallbacks * callbacks, gpointer user_data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GstVulkanEncoderPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GST_IS_VULKAN_ENCODER (self) && callbacks);
|
||||||
|
|
||||||
|
priv = gst_vulkan_encoder_get_instance_private (self);
|
||||||
|
|
||||||
|
priv->callbacks = *callbacks;
|
||||||
|
if (priv->callbacks_user_data && priv->callbacks_notify)
|
||||||
|
priv->callbacks_notify (priv->callbacks_user_data);
|
||||||
|
priv->callbacks_user_data = user_data;
|
||||||
|
priv->callbacks_notify = notify;
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,21 @@ typedef union _GstVulkanEncoderParameters GstVulkanEncoderParameters;
|
||||||
typedef union _GstVulkanEncoderParametersOverrides GstVulkanEncoderParametersOverrides;
|
typedef union _GstVulkanEncoderParametersOverrides GstVulkanEncoderParametersOverrides;
|
||||||
typedef union _GstVulkanEncoderParametersFeedback GstVulkanEncoderParametersFeedback;
|
typedef union _GstVulkanEncoderParametersFeedback GstVulkanEncoderParametersFeedback;
|
||||||
typedef struct _GstVulkanEncoderPicture GstVulkanEncoderPicture;
|
typedef struct _GstVulkanEncoderPicture GstVulkanEncoderPicture;
|
||||||
|
typedef struct _GstVulkaneEncoderCallbacks GstVulkanEncoderCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVulkaneEncoderCallbacks:
|
||||||
|
* @setup_codec_pic: Called after VkVideoEncodeInfoKHR and
|
||||||
|
* VkVideoReferenceSlotInfoKHR are filled so they can be chained with the
|
||||||
|
* specific codec structures. Called in gst_vulkan_encoder_encode().
|
||||||
|
*
|
||||||
|
* See gst_vulkan_encoder_set_callbacks()
|
||||||
|
*/
|
||||||
|
struct _GstVulkaneEncoderCallbacks
|
||||||
|
{
|
||||||
|
void (*setup_codec_pic) (GstVulkanEncoderPicture * pic,
|
||||||
|
VkVideoEncodeInfoKHR * info, gpointer data);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVulkanEncoderPicture:
|
* GstVulkanEncoderPicture:
|
||||||
|
@ -66,8 +81,6 @@ struct _GstVulkanEncoderPicture
|
||||||
VkVideoReferenceSlotInfoKHR dpb_slot;
|
VkVideoReferenceSlotInfoKHR dpb_slot;
|
||||||
|
|
||||||
gpointer codec_rc_info;
|
gpointer codec_rc_info;
|
||||||
gpointer codec_pic_info;
|
|
||||||
gpointer codec_dpb_slot_info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,6 +151,12 @@ GST_VULKAN_API
|
||||||
GstVulkanEncoder * gst_vulkan_encoder_create_from_queue (GstVulkanQueue * queue,
|
GstVulkanEncoder * gst_vulkan_encoder_create_from_queue (GstVulkanQueue * queue,
|
||||||
guint codec);
|
guint codec);
|
||||||
|
|
||||||
|
GST_VULKAN_API
|
||||||
|
void gst_vulkan_encoder_set_callbacks (GstVulkanEncoder * self,
|
||||||
|
GstVulkanEncoderCallbacks * callbacks,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
gboolean gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
gboolean gst_vulkan_encoder_start (GstVulkanEncoder * self,
|
||||||
GstVulkanVideoProfile * profile,
|
GstVulkanVideoProfile * profile,
|
||||||
|
|
|
@ -370,8 +370,40 @@ allocate_frame (GstVulkanEncoder * enc, int width,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PICTURE_TYPE(slice_type, is_ref) \
|
#define PICTURE_TYPE(slice_type, is_ref) \
|
||||||
(slice_type == STD_VIDEO_H264_SLICE_TYPE_I && is_ref) ? \
|
(slice_type == STD_VIDEO_H264_SLICE_TYPE_I && is_ref) \
|
||||||
STD_VIDEO_H264_PICTURE_TYPE_IDR : (StdVideoH264PictureType) slice_type
|
? STD_VIDEO_H264_PICTURE_TYPE_IDR \
|
||||||
|
: (StdVideoH264PictureType)slice_type
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_codec_pic (GstVulkanEncoderPicture * pic, VkVideoEncodeInfoKHR * info,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GstVulkanH264EncodeFrame *frame = (GstVulkanH264EncodeFrame *) pic;
|
||||||
|
GstVulkanVideoCapabilities *enc_caps = data;
|
||||||
|
|
||||||
|
info->pNext = &frame->enc_pic_info;
|
||||||
|
pic->dpb_slot.pNext = &frame->dpb_slot_info;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
frame->enc_pic_info = (VkVideoEncodeH264PictureInfoKHR) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PICTURE_INFO_KHR,
|
||||||
|
.pNext = NULL,
|
||||||
|
.naluSliceEntryCount = 1,
|
||||||
|
.pNaluSliceEntries = &frame->slice_info,
|
||||||
|
.pStdPictureInfo = &frame->pic_info,
|
||||||
|
.generatePrefixNalu =
|
||||||
|
(enc_caps->encoder.codec.h264.flags
|
||||||
|
& VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR),
|
||||||
|
};
|
||||||
|
frame->dpb_slot_info = (VkVideoEncodeH264DpbSlotInfoKHR) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR,
|
||||||
|
.pNext = NULL,
|
||||||
|
.pStdReferenceInfo = &frame->ref_info,
|
||||||
|
};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encode_frame (GstVulkanEncoder * enc, GstVulkanH264EncodeFrame * frame,
|
encode_frame (GstVulkanEncoder * enc, GstVulkanH264EncodeFrame * frame,
|
||||||
|
@ -383,11 +415,14 @@ encode_frame (GstVulkanEncoder * enc, GstVulkanH264EncodeFrame * frame,
|
||||||
int i, ref_pics_num = 0;
|
int i, ref_pics_num = 0;
|
||||||
GstVulkanEncoderPicture *ref_pics[16] = { NULL, };
|
GstVulkanEncoderPicture *ref_pics[16] = { NULL, };
|
||||||
GstVulkanEncoderPicture *picture = &frame->picture;
|
GstVulkanEncoderPicture *picture = &frame->picture;
|
||||||
|
GstVulkanEncoderCallbacks cb = { setup_codec_pic };
|
||||||
|
|
||||||
GST_DEBUG ("Encoding frame num:%d", frame_num);
|
GST_DEBUG ("Encoding frame num:%d", frame_num);
|
||||||
|
|
||||||
fail_unless (gst_vulkan_encoder_caps (enc, &enc_caps));
|
fail_unless (gst_vulkan_encoder_caps (enc, &enc_caps));
|
||||||
|
|
||||||
|
gst_vulkan_encoder_set_callbacks (enc, &cb, &enc_caps, NULL);
|
||||||
|
|
||||||
frame->slice_hdr = (StdVideoEncodeH264SliceHeader) {
|
frame->slice_hdr = (StdVideoEncodeH264SliceHeader) {
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
.flags = (StdVideoEncodeH264SliceHeaderFlags) {
|
.flags = (StdVideoEncodeH264SliceHeaderFlags) {
|
||||||
|
@ -462,16 +497,6 @@ encode_frame (GstVulkanEncoder * enc, GstVulkanH264EncodeFrame * frame,
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_KHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
frame->enc_pic_info = (VkVideoEncodeH264PictureInfoKHR) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PICTURE_INFO_KHR,
|
|
||||||
.pNext = NULL,
|
|
||||||
.naluSliceEntryCount = 1,
|
|
||||||
.pNaluSliceEntries = &frame->slice_info,
|
|
||||||
.pStdPictureInfo = &frame->pic_info,
|
|
||||||
.generatePrefixNalu = (enc_caps.encoder.codec.h264.flags
|
|
||||||
& VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR),
|
|
||||||
};
|
|
||||||
|
|
||||||
frame->ref_info = (StdVideoEncodeH264ReferenceInfo) {
|
frame->ref_info = (StdVideoEncodeH264ReferenceInfo) {
|
||||||
.flags = {
|
.flags = {
|
||||||
.used_for_long_term_reference = 0,
|
.used_for_long_term_reference = 0,
|
||||||
|
@ -483,17 +508,9 @@ encode_frame (GstVulkanEncoder * enc, GstVulkanH264EncodeFrame * frame,
|
||||||
.long_term_frame_idx = 0,
|
.long_term_frame_idx = 0,
|
||||||
.temporal_id = 0,
|
.temporal_id = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
frame->dpb_slot_info = (VkVideoEncodeH264DpbSlotInfoKHR) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR,
|
|
||||||
.pNext = NULL,
|
|
||||||
.pStdReferenceInfo = &frame->ref_info,
|
|
||||||
};
|
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
picture->codec_pic_info = &frame->enc_pic_info;
|
|
||||||
picture->codec_rc_info = &frame->rc_info;
|
picture->codec_rc_info = &frame->rc_info;
|
||||||
picture->codec_dpb_slot_info = &frame->dpb_slot_info;
|
|
||||||
|
|
||||||
for (i = 0; i < list0_num; i++) {
|
for (i = 0; i < list0_num; i++) {
|
||||||
ref_pics[i] = &list0[i]->picture;
|
ref_pics[i] = &list0[i]->picture;
|
||||||
|
|
|
@ -383,6 +383,34 @@ allocate_frame (GstVulkanEncoder * enc, int width,
|
||||||
slice_type == STD_VIDEO_H265_SLICE_TYPE_B ? STD_VIDEO_H265_PICTURE_TYPE_B: \
|
slice_type == STD_VIDEO_H265_SLICE_TYPE_B ? STD_VIDEO_H265_PICTURE_TYPE_B: \
|
||||||
(StdVideoH265PictureType) slice_type
|
(StdVideoH265PictureType) slice_type
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_codec_pic (GstVulkanEncoderPicture * pic, VkVideoEncodeInfoKHR * info,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GstVulkanH265EncodeFrame *frame = (GstVulkanH265EncodeFrame *) pic;
|
||||||
|
|
||||||
|
info->pNext = &frame->enc_pic_info;
|
||||||
|
pic->dpb_slot.pNext = &frame->dpb_slot_info;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
frame->enc_pic_info = (VkVideoEncodeH265PictureInfoKHR) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR,
|
||||||
|
.pNext = NULL,
|
||||||
|
.naluSliceSegmentEntryCount = 1,
|
||||||
|
.pNaluSliceSegmentEntries = &frame->slice_info,
|
||||||
|
.pStdPictureInfo = &frame->pic_info,
|
||||||
|
};
|
||||||
|
frame->dpb_slot_info = (VkVideoEncodeH265DpbSlotInfoKHR) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR,
|
||||||
|
.pNext = NULL,
|
||||||
|
.pStdReferenceInfo = &frame->ref_info,
|
||||||
|
};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encode_frame (GstVulkanEncoder * enc, GstVulkanH265EncodeFrame * frame,
|
encode_frame (GstVulkanEncoder * enc, GstVulkanH265EncodeFrame * frame,
|
||||||
StdVideoH265SliceType slice_type, guint frame_num,
|
StdVideoH265SliceType slice_type, guint frame_num,
|
||||||
|
@ -394,10 +422,13 @@ encode_frame (GstVulkanEncoder * enc, GstVulkanH265EncodeFrame * frame,
|
||||||
GstVulkanEncoderPicture *ref_pics[16] = { NULL, };
|
GstVulkanEncoderPicture *ref_pics[16] = { NULL, };
|
||||||
gint16 delta_poc_s0_minus1 = 0, delta_poc_s1_minus1 = 0;
|
gint16 delta_poc_s0_minus1 = 0, delta_poc_s1_minus1 = 0;
|
||||||
GstVulkanEncoderPicture *picture = &frame->picture;
|
GstVulkanEncoderPicture *picture = &frame->picture;
|
||||||
gint picture_type = PICTURE_TYPE(slice_type, frame->is_ref);
|
gint picture_type = PICTURE_TYPE (slice_type, frame->is_ref);
|
||||||
|
GstVulkanEncoderCallbacks cb = { setup_codec_pic };
|
||||||
|
|
||||||
GST_DEBUG ("Encoding frame num: %d", frame_num);
|
GST_DEBUG ("Encoding frame num: %d", frame_num);
|
||||||
|
|
||||||
|
gst_vulkan_encoder_set_callbacks (enc, &cb, NULL, NULL);
|
||||||
|
|
||||||
ref_pics_num = list0_num + list1_num;
|
ref_pics_num = list0_num + list1_num;
|
||||||
|
|
||||||
frame->slice_wt = (StdVideoEncodeH265WeightTable) {
|
frame->slice_wt = (StdVideoEncodeH265WeightTable) {
|
||||||
|
@ -534,14 +565,6 @@ encode_frame (GstVulkanEncoder * enc, GstVulkanH265EncodeFrame * frame,
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_KHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
frame->enc_pic_info = (VkVideoEncodeH265PictureInfoKHR) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR,
|
|
||||||
.pNext = NULL,
|
|
||||||
.naluSliceSegmentEntryCount = 1,
|
|
||||||
.pNaluSliceSegmentEntries = &frame->slice_info,
|
|
||||||
.pStdPictureInfo = &frame->pic_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
frame->ref_info = (StdVideoEncodeH265ReferenceInfo) {
|
frame->ref_info = (StdVideoEncodeH265ReferenceInfo) {
|
||||||
.flags = (StdVideoEncodeH265ReferenceInfoFlags) {
|
.flags = (StdVideoEncodeH265ReferenceInfoFlags) {
|
||||||
.used_for_long_term_reference = 0,
|
.used_for_long_term_reference = 0,
|
||||||
|
@ -551,17 +574,9 @@ encode_frame (GstVulkanEncoder * enc, GstVulkanH265EncodeFrame * frame,
|
||||||
.PicOrderCntVal = frame->pic_order_cnt,
|
.PicOrderCntVal = frame->pic_order_cnt,
|
||||||
.TemporalId = 0,
|
.TemporalId = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
frame->dpb_slot_info = (VkVideoEncodeH265DpbSlotInfoKHR) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR,
|
|
||||||
.pNext = NULL,
|
|
||||||
.pStdReferenceInfo = &frame->ref_info,
|
|
||||||
};
|
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
picture->codec_pic_info = &frame->enc_pic_info;
|
|
||||||
picture->codec_rc_info = &frame->rc_info;
|
picture->codec_rc_info = &frame->rc_info;
|
||||||
picture->codec_dpb_slot_info = &frame->dpb_slot_info;
|
|
||||||
|
|
||||||
for (i = 0; i < list0_num; i++) {
|
for (i = 0; i < list0_num; i++) {
|
||||||
ref_pics[i] = &list0[i]->picture;
|
ref_pics[i] = &list0[i]->picture;
|
||||||
|
|
Loading…
Reference in a new issue