From cd8f9792abc52664121834c5008533fd2d43d1f1 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Mon, 29 Apr 2024 23:45:48 +0200 Subject: [PATCH] BugFix Add keyframes every second of output recording Also compilation warning fix for GValue init. --- src/FrameGrabber.cpp | 14 +++++++++++++- src/FrameGrabber.h | 1 + src/Loopback.cpp | 2 +- src/Recorder.cpp | 5 +++-- src/ShmdataBroadcast.cpp | 2 +- src/Streamer.cpp | 2 +- src/VideoBroadcast.cpp | 2 +- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/FrameGrabber.cpp b/src/FrameGrabber.cpp index d1809c9..72219c7 100644 --- a/src/FrameGrabber.cpp +++ b/src/FrameGrabber.cpp @@ -272,7 +272,7 @@ FrameGrabber::FrameGrabber(): finished_(false), initialized_(false), active_(fal endofstream_(false), accept_buffer_(false), buffering_full_(false), pause_(false), pipeline_(nullptr), src_(nullptr), caps_(nullptr), timer_(nullptr), timer_firstframe_(0), timer_pauseframe_(0), timestamp_(0), duration_(0), pause_duration_(0), frame_count_(0), - buffering_size_(MIN_BUFFER_SIZE), buffering_count_(0), timestamp_on_clock_(true) + keyframe_count_(0), buffering_size_(MIN_BUFFER_SIZE), buffering_count_(0), timestamp_on_clock_(true) { // unique id id_ = BaseToolkit::uniqueId(); @@ -513,6 +513,18 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps) // push frame gst_app_src_push_buffer (src_, buffer); // NB: buffer will be unrefed by the appsrc + + // add a key frame every second (if keyframecount is valid) + if (keyframe_count_ > 1 && frame_count_ % keyframe_count_ < 1) { + GstEvent *event + = gst_video_event_new_downstream_force_key_unit(timestamp_, + GST_CLOCK_TIME_NONE, + GST_CLOCK_TIME_NONE, + FALSE, + frame_count_ / keyframe_count_); + gst_element_send_event(GST_ELEMENT(src_), event); + } + } } } diff --git a/src/FrameGrabber.h b/src/FrameGrabber.h index 90d4fa4..d5544dd 100644 --- a/src/FrameGrabber.h +++ b/src/FrameGrabber.h @@ -84,6 +84,7 @@ protected: GstClockTime pause_duration_; GstClockTime frame_duration_; guint64 frame_count_; + guint64 keyframe_count_; guint64 buffering_size_; guint64 buffering_count_; bool timestamp_on_clock_; diff --git a/src/Loopback.cpp b/src/Loopback.cpp index 72b5e6d..140c681 100644 --- a/src/Loopback.cpp +++ b/src/Loopback.cpp @@ -124,7 +124,7 @@ std::string Loopback::init(GstCaps *caps) // specify streaming framerate in the given caps GstCaps *tmp = gst_caps_copy( caps ); - GValue v = { 0, }; + GValue v = G_VALUE_INIT; g_value_init (&v, GST_TYPE_FRACTION); gst_value_set_fraction (&v, LOOPBACK_FPS, 1); // fixed FPS gst_caps_set_value(tmp, "framerate", &v); diff --git a/src/Recorder.cpp b/src/Recorder.cpp index 4eb5168..7ed08d0 100644 --- a/src/Recorder.cpp +++ b/src/Recorder.cpp @@ -334,7 +334,8 @@ std::string VideoRecorder::init(GstCaps *caps) // apply settings buffering_size_ = MAX( MIN_BUFFER_SIZE, buffering_preset_value[Settings::application.record.buffering_mode]); frame_duration_ = gst_util_uint64_scale_int (1, GST_SECOND, framerate_preset_value[Settings::application.record.framerate_mode]); - timestamp_on_clock_ = Settings::application.record.priority_mode < 1; + timestamp_on_clock_ = Settings::application.record.priority_mode < 1; + keyframe_count_ = framerate_preset_value[Settings::application.record.framerate_mode]; // create a gstreamer pipeline std::string description = "appsrc name=src ! videoconvert ! queue ! "; @@ -440,7 +441,7 @@ std::string VideoRecorder::init(GstCaps *caps) // specify recorder framerate in the given caps GstCaps *tmp = gst_caps_copy( caps ); - GValue v = { 0, }; + GValue v = G_VALUE_INIT; g_value_init (&v, GST_TYPE_FRACTION); gst_value_set_fraction (&v, framerate_preset_value[Settings::application.record.framerate_mode], 1); gst_caps_set_value(tmp, "framerate", &v); diff --git a/src/ShmdataBroadcast.cpp b/src/ShmdataBroadcast.cpp index 63e3734..16f845d 100644 --- a/src/ShmdataBroadcast.cpp +++ b/src/ShmdataBroadcast.cpp @@ -131,7 +131,7 @@ std::string ShmdataBroadcast::init(GstCaps *caps) // specify streaming framerate in the given caps GstCaps *tmp = gst_caps_copy( caps ); - GValue v = { 0, }; + GValue v = G_VALUE_INIT; g_value_init (&v, GST_TYPE_FRACTION); gst_value_set_fraction (&v, SHMDATA_FPS, 1); // fixed 30 FPS gst_caps_set_value(tmp, "framerate", &v); diff --git a/src/Streamer.cpp b/src/Streamer.cpp index 54df70b..272a66f 100644 --- a/src/Streamer.cpp +++ b/src/Streamer.cpp @@ -449,7 +449,7 @@ std::string VideoStreamer::init(GstCaps *caps) // specify streaming framerate in the given caps GstCaps *tmp = gst_caps_copy( caps ); - GValue v = { 0, }; + GValue v = G_VALUE_INIT; g_value_init (&v, GST_TYPE_FRACTION); gst_value_set_fraction (&v, STREAMING_FPS, 1); // fixed 30 FPS gst_caps_set_value(tmp, "framerate", &v); diff --git a/src/VideoBroadcast.cpp b/src/VideoBroadcast.cpp index a2492ad..6180069 100644 --- a/src/VideoBroadcast.cpp +++ b/src/VideoBroadcast.cpp @@ -156,7 +156,7 @@ std::string VideoBroadcast::init(GstCaps *caps) // specify streaming framerate in the given caps GstCaps *tmp = gst_caps_copy( caps ); - GValue v = { 0, }; + GValue v = G_VALUE_INIT; g_value_init (&v, GST_TYPE_FRACTION); gst_value_set_fraction (&v, BROADCAST_FPS, 1); // fixed 30 FPS gst_caps_set_value(tmp, "framerate", &v);