From 08060dd97bd53a9ec4450166e49cab8f2f7f3668 Mon Sep 17 00:00:00 2001 From: Linus Svensson Date: Thu, 31 May 2018 10:29:43 +0200 Subject: [PATCH] matroskamux: Add property to set DateUTC Add a property that makes it possible for an application to set the DateUTC header field in matroska files. This is useful for live feeds, where the DateUTC header can be set to a UTC timestamp, matching the beginning of the file. Needs gstreamer!323 Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/issues/481 --- gst/matroska/matroska-mux.c | 24 ++++++++++++++++++++++-- gst/matroska/matroska-mux.h | 3 +++ gst/matroska/matroska-read-common.c | 8 ++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index cff58eb..b82dccd 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -74,6 +74,7 @@ enum PROP_MIN_CLUSTER_DURATION, PROP_MAX_CLUSTER_DURATION, PROP_OFFSET_TO_ZERO, + PROP_CREATION_TIME, }; #define DEFAULT_DOCTYPE_VERSION 2 @@ -369,6 +370,11 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass) g_param_spec_boolean ("offset-to-zero", "Offset To Zero", "Offsets all streams so that the " "earliest stream starts at 0.", DEFAULT_OFFSET_TO_ZERO, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CREATION_TIME, + g_param_spec_boxed ("creation-time", "Creation Time", + "Date and time of creation. This will be used for the DateUTC field." + " NULL means that the current time will be used.", + G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state); @@ -528,6 +534,7 @@ gst_matroska_mux_finalize (GObject * object) gst_object_unref (mux->collect); gst_object_unref (mux->ebml_write); g_free (mux->writing_app); + g_clear_pointer (&mux->creation_time, g_date_time_unref); if (mux->internal_toc) { gst_toc_unref (mux->internal_toc); @@ -2960,6 +2967,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux, GstMatroskaPad * first_pad, GstClockTime earliest_time = GST_CLOCK_TIME_NONE; GstClockTime duration = 0; guint32 segment_uid[4]; + gint64 time; gchar s_id[32]; GstToc *toc; @@ -3097,8 +3105,13 @@ gst_matroska_mux_start (GstMatroskaMux * mux, GstMatroskaPad * first_pad, if (mux->writing_app && mux->writing_app[0]) { gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_WRITINGAPP, mux->writing_app); } - gst_ebml_write_date (ebml, GST_MATROSKA_ID_DATEUTC, - g_get_real_time () * GST_USECOND); + if (mux->creation_time != NULL) { + time = g_date_time_to_unix (mux->creation_time) * GST_SECOND; + time += g_date_time_get_microsecond (mux->creation_time) * GST_USECOND; + } else { + time = g_get_real_time () * GST_USECOND; + } + gst_ebml_write_date (ebml, GST_MATROSKA_ID_DATEUTC, time); gst_ebml_write_master_finish (ebml, master); /* tracks */ @@ -4235,6 +4248,10 @@ gst_matroska_mux_set_property (GObject * object, case PROP_OFFSET_TO_ZERO: mux->offset_to_zero = g_value_get_boolean (value); break; + case PROP_CREATION_TIME: + g_clear_pointer (&mux->creation_time, g_date_time_unref); + mux->creation_time = g_value_dup_boxed (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -4275,6 +4292,9 @@ gst_matroska_mux_get_property (GObject * object, case PROP_OFFSET_TO_ZERO: g_value_set_boolean (value, mux->offset_to_zero); break; + case PROP_CREATION_TIME: + g_value_set_boxed (value, mux->creation_time); + 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 3c8ee42..ff208f7 100644 --- a/gst/matroska/matroska-mux.h +++ b/gst/matroska/matroska-mux.h @@ -91,6 +91,9 @@ struct _GstMatroskaMux { /* Application name (for the writing application header element) */ gchar *writing_app; + /* Date (for the DateUTC header element) */ + GDateTime *creation_time; + /* EBML DocType. */ const gchar *doctype; diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c index 3228a10..90d6e38 100644 --- a/gst/matroska/matroska-read-common.c +++ b/gst/matroska/matroska-read-common.c @@ -1974,12 +1974,20 @@ gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common, case GST_MATROSKA_ID_DATEUTC:{ gint64 time; + GstDateTime *datetime; + GstTagList *taglist; if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK) break; GST_DEBUG_OBJECT (common->sinkpad, "DateUTC: %" G_GINT64_FORMAT, time); common->created = time; + datetime = + gst_date_time_new_from_unix_epoch_utc_usecs (time / GST_USECOND); + taglist = gst_tag_list_new (GST_TAG_DATE_TIME, datetime, NULL); + gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL); + gst_matroska_read_common_found_global_tag (common, el, taglist); + gst_date_time_unref (datetime); break; } -- 2.7.4