x265: Fix duplicate SEI at startup IDR frame problem

x265 encoder_headers return headers with SEI after encoding the frame,
while the output frame also contains SEI so two identical header
blocks appeared.
Cache the headers at init, leaving only a single copy in the stream.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9604>
This commit is contained in:
Vivian LEE 2025-08-25 09:44:01 +08:00 committed by GStreamer Marge Bot
parent 321601f069
commit 5801dd0593
2 changed files with 12 additions and 5 deletions

View File

@ -199,6 +199,8 @@ static void gst_x265_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean x265enc_element_init (GstPlugin * plugin);
static GstBuffer *gst_x265_enc_get_header_buffer (GstX265Enc * encoder);
#define gst_x265_enc_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstX265Enc, gst_x265_enc, GST_TYPE_VIDEO_ENCODER,
G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
@ -561,6 +563,7 @@ static void
gst_x265_enc_init (GstX265Enc * encoder)
{
encoder->push_header = TRUE;
encoder->header_buffer = NULL;
encoder->bitrate = PROP_BITRATE_DEFAULT;
encoder->qp = PROP_QP_DEFAULT;
@ -658,6 +661,7 @@ gst_x265_enc_stop (GstVideoEncoder * encoder)
GST_DEBUG_OBJECT (encoder, "stop encoder");
gst_clear_buffer (&x265enc->header_buffer);
gst_x265_enc_flush_frames (x265enc, FALSE);
gst_x265_enc_close_encoder (x265enc);
gst_x265_enc_dequeue_all_frames (x265enc);
@ -693,6 +697,8 @@ gst_x265_enc_finalize (GObject * object)
{
GstX265Enc *encoder = GST_X265_ENC (object);
gst_clear_buffer (&encoder->header_buffer);
if (encoder->input_state)
gst_video_codec_state_unref (encoder->input_state);
encoder->input_state = NULL;
@ -997,6 +1003,7 @@ gst_x265_enc_init_encoder_locked (GstX265Enc * encoder)
}
encoder->push_header = TRUE;
encoder->header_buffer = gst_x265_enc_get_header_buffer (encoder);
return TRUE;
}
@ -1613,12 +1620,11 @@ gst_x265_enc_encode_frame (GstX265Enc * encoder, x265_picture * pic_in,
frame->output_buffer = out_buf;
if (encoder->push_header) {
GstBuffer *header;
header = gst_x265_enc_get_header_buffer (encoder);
frame->output_buffer = gst_buffer_append (header, frame->output_buffer);
if (encoder->push_header && encoder->header_buffer) {
frame->output_buffer =
gst_buffer_append (encoder->header_buffer, frame->output_buffer);
encoder->push_header = FALSE;
encoder->header_buffer = NULL;
}
GST_LOG_OBJECT (encoder,

View File

@ -50,6 +50,7 @@ struct _GstX265Enc
x265_param x265param;
GstClockTime dts_offset;
gboolean push_header;
GstBuffer *header_buffer;
const x265_api *api;
/* List of frame/buffer mapping structs for