From 14a95b862043bbcd3a4ade5e0a98f0b3bd6585a1 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Sun, 17 Mar 2024 10:15:38 +0000 Subject: [PATCH] h264-v4l2m2m: Implement key-frame coercion --- src/h264-encoder-v4l2m2m-impl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/h264-encoder-v4l2m2m-impl.c b/src/h264-encoder-v4l2m2m-impl.c index cfc6059..0ac2a2f 100644 --- a/src/h264-encoder-v4l2m2m-impl.c +++ b/src/h264-encoder-v4l2m2m-impl.c @@ -443,6 +443,14 @@ static int alloc_src_buffers(struct h264_encoder_v4l2m2m* self) return 0; } +static void force_key_frame(struct h264_encoder_v4l2m2m* self) +{ + struct v4l2_control ctrl = { 0 }; + ctrl.id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME; + ctrl.value = 0; + ioctl(self->fd, VIDIOC_S_CTRL, &ctrl); +} + static void encode_buffer(struct h264_encoder_v4l2m2m* self, struct nvnc_fb* fb) { @@ -485,6 +493,10 @@ static void encode_buffer(struct h264_encoder_v4l2m2m* self, srcbuf->buffer.timestamp.tv_sec = fb->pts / UINT64_C(1000000); srcbuf->buffer.timestamp.tv_usec = fb->pts % UINT64_C(1000000); + if (self->base.next_frame_should_be_keyframe) + force_key_frame(self); + self->base.next_frame_should_be_keyframe = false; + int rc = v4l2_qbuf(self->fd, &srcbuf->buffer); if (rc < 0) { nvnc_log(NVNC_LOG_PANIC, "Failed to enqueue buffer: %m");