From cf7bb1dd6061de058c33dbc9cd268441af784309 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 8 Aug 2023 16:13:35 +0200 Subject: [PATCH] v4l2codecs: add key frame signaling Propagate V4L2 keyframe flags signaling to upstream elements by setting GstBuffer delta-unit flag & GstVideoCodecFrame sync point flag. Signed-off-by: Hugues Fruchet --- sys/v4l2codecs/gstv4l2codecvp8enc.c | 11 ++++++++++- sys/v4l2codecs/gstv4l2encoder.c | 7 ++++--- sys/v4l2codecs/gstv4l2encoder.h | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/sys/v4l2codecs/gstv4l2codecvp8enc.c b/sys/v4l2codecs/gstv4l2codecvp8enc.c index 2f15caf..71c7dd2 100644 --- a/sys/v4l2codecs/gstv4l2codecvp8enc.c +++ b/sys/v4l2codecs/gstv4l2codecvp8enc.c @@ -542,6 +542,7 @@ gst_v4l2_codec_vp8_enc_encode_frame (GstVp8Encoder * encoder, GstVideoCodecFrame *frame = vp8_frame->frame; GstBuffer *resized_buffer; guint32 bytesused; + guint32 flags; /* *INDENT-OFF* */ struct v4l2_ext_control control[] = { @@ -596,7 +597,7 @@ gst_v4l2_codec_vp8_enc_encode_frame (GstVp8Encoder * encoder, goto done; } - if (!gst_v4l2_encoder_request_set_done (request, &bytesused)) { + if (!gst_v4l2_encoder_request_set_done (request, &bytesused, &flags)) { GST_ELEMENT_ERROR (self, RESOURCE, WRITE, ("Driver did not ack the request."), (NULL)); goto done; @@ -609,6 +610,14 @@ gst_v4l2_codec_vp8_enc_encode_frame (GstVp8Encoder * encoder, gst_buffer_replace (&frame->output_buffer, resized_buffer); gst_buffer_unref (resized_buffer); + if (flags & V4L2_BUF_FLAG_KEYFRAME) { + GST_BUFFER_FLAG_UNSET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame); + } else { + GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT); + GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame); + } + return gst_video_encoder_finish_frame (venc, frame); done: diff --git a/sys/v4l2codecs/gstv4l2encoder.c b/sys/v4l2codecs/gstv4l2encoder.c index 5ae2cfa..e2ef423 100644 --- a/sys/v4l2codecs/gstv4l2encoder.c +++ b/sys/v4l2codecs/gstv4l2encoder.c @@ -696,7 +696,7 @@ gst_v4l2_encoder_dequeue_sink (GstV4l2Encoder * self) static gboolean gst_v4l2_encoder_dequeue_src (GstV4l2Encoder * self, guint32 * out_frame_num, - guint32 * bytesused) + guint32 * bytesused, guint32 * flags) { gint ret; struct v4l2_plane planes[GST_VIDEO_MAX_PLANES] = { {0} }; @@ -718,6 +718,7 @@ gst_v4l2_encoder_dequeue_src (GstV4l2Encoder * self, guint32 * out_frame_num, *out_frame_num = buf.timestamp.tv_usec; *bytesused = buf.m.planes[0].bytesused; + *flags = buf.flags; GST_TRACE_OBJECT (self, "Dequeued bitstream buffer %i, %d bytes used", buf.index, buf.m.planes[0].bytesused); @@ -1137,7 +1138,7 @@ gst_v4l2_encoder_request_queue (GstV4l2Request * request, guint flags) gint gst_v4l2_encoder_request_set_done (GstV4l2Request * request, - guint32 * bytesused) + guint32 * bytesused, guint32 * flags) { GstV4l2Encoder *encoder = request->encoder; GstV4l2Request *pending_req = NULL; @@ -1167,7 +1168,7 @@ gst_v4l2_encoder_request_set_done (GstV4l2Request * request, if (!pending_req->hold_pic_buf) { guint32 frame_num = G_MAXUINT32; - if (!gst_v4l2_encoder_dequeue_src (encoder, &frame_num, bytesused)) { + if (!gst_v4l2_encoder_dequeue_src (encoder, &frame_num, bytesused, flags)) { pending_req->failed = TRUE; } else if (frame_num != pending_req->frame_num) { GST_WARNING_OBJECT (encoder, diff --git a/sys/v4l2codecs/gstv4l2encoder.h b/sys/v4l2codecs/gstv4l2encoder.h index 7ff01a9..9acb0e3 100644 --- a/sys/v4l2codecs/gstv4l2encoder.h +++ b/sys/v4l2codecs/gstv4l2encoder.h @@ -128,7 +128,7 @@ void gst_v4l2_encoder_ro_request_unref (GstV4l2Request * request); gboolean gst_v4l2_encoder_request_queue (GstV4l2Request * request, guint flags); -gint gst_v4l2_encoder_request_set_done (GstV4l2Request * request, guint32 * bytesused); +gint gst_v4l2_encoder_request_set_done (GstV4l2Request * request, guint32 * bytesused, guint32 * flags); gboolean gst_v4l2_encoder_request_failed (GstV4l2Request * request); -- 2.25.1