multifilesink: Make minimum distance between keyframes in next-file=key-frame mode...
authorSebastian Dröge <sebastian@centricular.com>
Tue, 2 Nov 2021 14:46:08 +0000 (16:46 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 2 Nov 2021 20:21:10 +0000 (20:21 +0000)
Previously this was hardcoded to 10s, which is not necessarily the
desired behaviour.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1292>

subprojects/gst-plugins-good/docs/gst_plugins_cache.json
subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.c
subprojects/gst-plugins-good/gst/multifile/gstmultifilesink.h

index 0b5eb8b..c547c7f 100644 (file)
                         "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,
index 8e8d0ec..acee9b8 100644 (file)
@@ -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) {
index 1478341..bd7eb2a 100644 (file)
@@ -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 */