From dac82a89323ae1a5aeeb46c531810a16c54739b4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 2 Nov 2021 16:46:08 +0200 Subject: [PATCH] multifilesink: Make minimum distance between keyframes in next-file=key-frame mode configurable Previously this was hardcoded to 10s, which is not necessarily the desired behaviour. Part-of: --- .../gst-plugins-good/docs/gst_plugins_cache.json | 14 ++++++++++ .../gst/multifile/gstmultifilesink.c | 30 +++++++++++++++++++--- .../gst/multifile/gstmultifilesink.h | 1 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index 0b5eb8b..c547c7f 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -9679,6 +9679,20 @@ "type": "guint", "writable": true }, + "min-keyframe-distance": { + "blurb": "Minimum distance between keyframes to start a new file", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "10000000000", + "max": "18446744073709551615", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint64", + "writable": true + }, "next-file": { "blurb": "When to start a new file", "conditionally-available": false, diff --git a/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.c b/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.c index 8e8d0ec..acee9b8 100644 --- a/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.c +++ b/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.c @@ -87,6 +87,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_multi_file_sink_debug); #define DEFAULT_MAX_FILE_SIZE G_GUINT64_CONSTANT(2*1024*1024*1024) #define DEFAULT_MAX_FILE_DURATION GST_CLOCK_TIME_NONE #define DEFAULT_AGGREGATE_GOPS FALSE +#define DEFAULT_MIN_KEYFRAME_DISTANCE (10 * GST_SECOND) enum { @@ -98,7 +99,8 @@ enum PROP_MAX_FILES, PROP_MAX_FILE_SIZE, PROP_MAX_FILE_DURATION, - PROP_AGGREGATE_GOPS + PROP_AGGREGATE_GOPS, + PROP_MIN_KEYFRAME_DISTANCE }; static void gst_multi_file_sink_finalize (GObject * object); @@ -257,6 +259,21 @@ gst_multi_file_sink_class_init (GstMultiFileSinkClass * klass) "splitting", DEFAULT_AGGREGATE_GOPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstMultiFileSink:min-keyframe-distance: + * + * Minimum distance between keyframes in `next-file=key-frame` that causes a + * new file to be created. If two keyframes arrive closer to each other they + * will end up in the same file. + * + * Since: 1.20 + */ + g_object_class_install_property (gobject_class, PROP_MIN_KEYFRAME_DISTANCE, + g_param_spec_uint64 ("min-keyframe-distance", "Minimum Keyframe Distance", + "Minimum distance between keyframes to start a new file", 0, + G_MAXUINT64, DEFAULT_MIN_KEYFRAME_DISTANCE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gobject_class->finalize = gst_multi_file_sink_finalize; gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_multi_file_sink_start); @@ -289,6 +306,7 @@ gst_multi_file_sink_init (GstMultiFileSink * multifilesink) multifilesink->max_files = DEFAULT_MAX_FILES; multifilesink->max_file_size = DEFAULT_MAX_FILE_SIZE; multifilesink->max_file_duration = DEFAULT_MAX_FILE_DURATION; + multifilesink->min_keyframe_distance = DEFAULT_MIN_KEYFRAME_DISTANCE; multifilesink->aggregate_gops = DEFAULT_AGGREGATE_GOPS; multifilesink->gop_adapter = NULL; @@ -351,6 +369,9 @@ gst_multi_file_sink_set_property (GObject * object, guint prop_id, case PROP_AGGREGATE_GOPS: sink->aggregate_gops = g_value_get_boolean (value); break; + case PROP_MIN_KEYFRAME_DISTANCE: + sink->min_keyframe_distance = g_value_get_uint64 (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -388,6 +409,9 @@ gst_multi_file_sink_get_property (GObject * object, guint prop_id, case PROP_AGGREGATE_GOPS: g_value_set_boolean (value, sink->aggregate_gops); break; + case PROP_MIN_KEYFRAME_DISTANCE: + g_value_set_uint64 (value, sink->min_keyframe_distance); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -607,7 +631,7 @@ gst_multi_file_sink_write_buffer (GstMultiFileSink * multifilesink, if (multifilesink->next_segment == GST_CLOCK_TIME_NONE) { if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { multifilesink->next_segment = GST_BUFFER_TIMESTAMP (buffer) + - 10 * GST_SECOND; + multifilesink->min_keyframe_distance; } } @@ -618,7 +642,7 @@ gst_multi_file_sink_write_buffer (GstMultiFileSink * multifilesink, first_file = FALSE; gst_multi_file_sink_close_file (multifilesink, buffer); } - multifilesink->next_segment += 10 * GST_SECOND; + multifilesink->next_segment += multifilesink->min_keyframe_distance; } if (multifilesink->file == NULL) { diff --git a/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.h b/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.h index 1478341..bd7eb2a 100644 --- a/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.h +++ b/subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.h @@ -100,6 +100,7 @@ struct _GstMultiFileSink GstClockTime file_pts; GstClockTime max_file_duration; + GstClockTime min_keyframe_distance; gboolean aggregate_gops; GstAdapter *gop_adapter; /* to aggregate GOPs */ -- 2.7.4