summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Raghavan <arun@asymptotic.io>2021-08-12 11:03:58 -0400
committerArun Raghavan <arun@asymptotic.io>2021-08-18 10:51:15 -0400
commit2c6be7373f3213ef90a858504e7b981e8f94908d (patch)
treebfd711e3aa10515faabc50ea4818288e82722595
parent508a565163990e6f24e00d73f0b9715eec668443 (diff)
matroska-mux: Add a timestamp-offset property
Adds a user-controllable timestamp offset to clusters and blocks. This should be useful if we want to have timestamps that have significance outside of the current file (for example, we might set the offset to the wallclock when the file is being created, or some other common base, if we want to correlate streams across multiple files). Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/1051>
-rw-r--r--docs/gst_plugins_cache.json14
-rw-r--r--gst/matroska/matroska-mux.c27
-rw-r--r--gst/matroska/matroska-mux.h1
3 files changed, 42 insertions, 0 deletions
diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json
index 29807956a..0d7eeb229 100644
--- a/docs/gst_plugins_cache.json
+++ b/docs/gst_plugins_cache.json
@@ -9120,6 +9120,20 @@
}
},
"properties": {
+ "cluster-timestamp-offset": {
+ "blurb": "An offset to add to all clusters/blocks (in nanoseconds)",
+ "conditionally-available": false,
+ "construct": false,
+ "construct-only": false,
+ "controllable": false,
+ "default": "0",
+ "max": "18446744073709551615",
+ "min": "0",
+ "mutable": "null",
+ "readable": true,
+ "type": "guint64",
+ "writable": true
+ },
"creation-time": {
"blurb": "Date and time of creation. This will be used for the DateUTC field. NULL means that the current time will be used.",
"conditionally-available": false,
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index 1d003b488..7dd8901ff 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -76,6 +76,7 @@ enum
PROP_MAX_CLUSTER_DURATION,
PROP_OFFSET_TO_ZERO,
PROP_CREATION_TIME,
+ PROP_CLUSTER_TIMESTAMP_OFFSET,
};
#define DEFAULT_DOCTYPE_VERSION 2
@@ -86,6 +87,7 @@ enum
#define DEFAULT_MIN_CLUSTER_DURATION 500 * GST_MSECOND
#define DEFAULT_MAX_CLUSTER_DURATION 65535 * GST_MSECOND
#define DEFAULT_OFFSET_TO_ZERO FALSE
+#define DEFAULT_CLUSTER_TIMESTAMP_OFFSET 0
/* WAVEFORMATEX is gst_riff_strf_auds + an extra guint16 extension size */
#define WAVEFORMATEX_SIZE (2 + sizeof (gst_riff_strf_auds))
@@ -380,6 +382,20 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
" NULL means that the current time will be used.",
G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstMatroskaMux:cluster-timestamp-offset:
+ *
+ * An offset to add to all clusters/blocks (in nanoseconds)
+ *
+ * Since: 1.20
+ */
+ g_object_class_install_property (gobject_class, PROP_CLUSTER_TIMESTAMP_OFFSET,
+ g_param_spec_uint64 ("cluster-timestamp-offset",
+ "Cluster timestamp offset",
+ "An offset to add to all clusters/blocks (in nanoseconds)", 0,
+ G_MAXUINT64, DEFAULT_CLUSTER_TIMESTAMP_OFFSET,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state);
gstelement_class->request_new_pad =
@@ -508,6 +524,7 @@ gst_matroska_mux_init (GstMatroskaMux * mux, gpointer g_class)
mux->time_scale = DEFAULT_TIMECODESCALE;
mux->min_cluster_duration = DEFAULT_MIN_CLUSTER_DURATION;
mux->max_cluster_duration = DEFAULT_MAX_CLUSTER_DURATION;
+ mux->cluster_timestamp_offset = DEFAULT_CLUSTER_TIMESTAMP_OFFSET;
/* initialize internal variables */
mux->index = NULL;
@@ -3915,6 +3932,10 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
}
}
+ /* From this point on we use the buffer_timestamp to do cluster and other
+ * related arithmetic, so apply the timestamp offset if we have one */
+ buffer_timestamp += mux->cluster_timestamp_offset;
+
is_audio_only = (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
(mux->num_streams == 1);
is_min_duration_reached = (mux->min_cluster_duration == 0
@@ -4303,6 +4324,9 @@ gst_matroska_mux_set_property (GObject * object,
g_clear_pointer (&mux->creation_time, g_date_time_unref);
mux->creation_time = g_value_dup_boxed (value);
break;
+ case PROP_CLUSTER_TIMESTAMP_OFFSET:
+ mux->cluster_timestamp_offset = g_value_get_uint64 (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4346,6 +4370,9 @@ gst_matroska_mux_get_property (GObject * object,
case PROP_CREATION_TIME:
g_value_set_boxed (value, mux->creation_time);
break;
+ case PROP_CLUSTER_TIMESTAMP_OFFSET:
+ g_value_set_uint64 (value, mux->cluster_timestamp_offset);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/gst/matroska/matroska-mux.h b/gst/matroska/matroska-mux.h
index ff208f7ba..bcb61a929 100644
--- a/gst/matroska/matroska-mux.h
+++ b/gst/matroska/matroska-mux.h
@@ -116,6 +116,7 @@ struct _GstMatroskaMux {
/* earliest timestamp (time, ns) if offsetting to zero */
gboolean offset_to_zero;
+ guint64 cluster_timestamp_offset;
guint64 earliest_time;
/* length, position (time, ns) */
guint64 duration;