diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt
index 8c78664bc4..4a2c0ead5f 100644
--- a/docs/gst/gstreamer-sections.txt
+++ b/docs/gst/gstreamer-sections.txt
@@ -2588,6 +2588,7 @@ gst_search_mode_get_type
gstdatetime
GstDateTime
GstDateTime
+GST_TYPE_DATE_TIME
gst_date_time_get_day
gst_date_time_get_month
gst_date_time_get_hour
@@ -2667,6 +2668,9 @@ GST_TYPE_DATE
gst_value_set_date
gst_value_get_date
+
+GST_VALUE_HOLDS_DATE_TIME
+
GST_VALUE_HOLDS_CAPS
gst_value_set_caps
@@ -2723,6 +2727,7 @@ gst_value_array_prepend_value
gst_date_get_type
+gst_date_time_get_type
gst_double_range_get_type
gst_fourcc_get_type
gst_fraction_get_type
diff --git a/gst/gst_private.h b/gst/gst_private.h
index 36e03efe29..426353f02a 100644
--- a/gst/gst_private.h
+++ b/gst/gst_private.h
@@ -124,6 +124,9 @@ gboolean gst_registry_binary_write_cache (GstRegistry * registry, const char *
((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
((c) == '.'))
+/* This is only meant for internal uses */
+gint priv_gst_date_time_compare (gconstpointer dt1, gconstpointer dt2);
+
#ifndef GST_DISABLE_REGISTRY
/* Secret variable to initialise gst without registry cache */
extern gboolean _gst_disable_registry_cache;
diff --git a/gst/gstdatetime.c b/gst/gstdatetime.c
index bd015bc576..d68a397e1b 100644
--- a/gst/gstdatetime.c
+++ b/gst/gstdatetime.c
@@ -557,3 +557,34 @@ gst_date_time_new_now_utc (void)
gst_date_time_unref (now);
return utc;
}
+
+gint
+priv_gst_date_time_compare (gconstpointer dt1, gconstpointer dt2)
+{
+ GstDateTime *a, *b;
+ gint res = 0;
+
+ a = gst_date_time_to_utc (dt1);
+ b = gst_date_time_to_utc (dt2);
+
+#define GST_DATE_TIME_COMPARE_VALUE(a,b,v) \
+ if ((a)->v > (b)->v) { \
+ res = 1; \
+ goto done; \
+ } else if ((a)->v < (b)->v) { \
+ res = -1; \
+ goto done; \
+ }
+
+ GST_DATE_TIME_COMPARE_VALUE (a, b, year);
+ GST_DATE_TIME_COMPARE_VALUE (a, b, month);
+ GST_DATE_TIME_COMPARE_VALUE (a, b, day);
+ GST_DATE_TIME_COMPARE_VALUE (a, b, usec);
+
+#undef GST_DATE_TIME_COMPARE_VALUE
+
+done:
+ gst_date_time_unref (a);
+ gst_date_time_unref (b);
+ return res;
+}
diff --git a/gst/gststructure.c b/gst/gststructure.c
index 8ae21cfd46..231e15e15c 100644
--- a/gst/gststructure.c
+++ b/gst/gststructure.c
@@ -1548,6 +1548,8 @@ gst_structure_get_abbrs (gint * n_abbrs)
{"s", G_TYPE_STRING}
,
{"structure", GST_TYPE_STRUCTURE}
+ ,
+ {"datetime", GST_TYPE_DATE_TIME}
};
_num = G_N_ELEMENTS (dyn_abbrs);
/* permanently allocate and copy the array now */
diff --git a/gst/gstvalue.c b/gst/gstvalue.c
index a8d58deb00..6abd1b01f2 100644
--- a/gst/gstvalue.c
+++ b/gst/gstvalue.c
@@ -4050,6 +4050,83 @@ gst_value_deserialize_date (GValue * dest, const gchar * s)
return TRUE;
}
+/*************
+ * GstDateTime *
+ *************/
+
+static gint
+gst_value_compare_date_time (const GValue * value1, const GValue * value2)
+{
+ const GstDateTime *date1 = (const GstDateTime *) g_value_get_boxed (value1);
+ const GstDateTime *date2 = (const GstDateTime *) g_value_get_boxed (value2);
+ gint ret;
+
+ if (date1 == date2)
+ return GST_VALUE_EQUAL;
+
+ if ((date1 == NULL) && (date2 != NULL)) {
+ return GST_VALUE_LESS_THAN;
+ }
+ if ((date2 == NULL) && (date1 != NULL)) {
+ return GST_VALUE_LESS_THAN;
+ }
+
+ ret = priv_gst_date_time_compare (date1, date2);
+
+ if (ret == 0)
+ return GST_VALUE_EQUAL;
+ else if (ret < 0)
+ return GST_VALUE_LESS_THAN;
+ else
+ return GST_VALUE_GREATER_THAN;
+}
+
+static gchar *
+gst_value_serialize_date_time (const GValue * val)
+{
+ const GstDateTime *date = (const GstDateTime *) g_value_get_boxed (val);
+ gint offset;
+
+ if (date == NULL)
+ return g_strdup ("null");
+
+ offset = gst_date_time_get_time_zone_offset (date);
+
+ return g_strdup_printf ("\"%04d-%02d-%02dT%02d:%02d:%02d.%06d"
+ "%c%02d%02d\"", gst_date_time_get_year (date),
+ gst_date_time_get_month (date), gst_date_time_get_day (date),
+ gst_date_time_get_hour (date), gst_date_time_get_minute (date),
+ gst_date_time_get_second (date), gst_date_time_get_microsecond (date),
+ offset >= 0 ? '+' : '-', (gint) ABS (offset) / 60,
+ (gint) ABS (offset) % 60);
+}
+
+static gboolean
+gst_value_deserialize_date_time (GValue * dest, const gchar * s)
+{
+ gint year, month, day, hour, minute, second, usecond;
+ gchar signal;
+ gint offset = 0;
+ gint ret;
+
+ if (!s || strcmp (s, "null") == 0) {
+ return FALSE;
+ }
+
+ ret = sscanf (s, "%04d-%02d-%02dT%02d:%02d:%02d.%06d%c%04d",
+ &year, &month, &day, &hour, &minute, &second, &usecond, &signal, &offset);
+ if (ret >= 9) {
+ offset = (offset / 100) * 60 + (offset % 100);
+ if (signal == '-')
+ offset = -offset;
+ } else
+ return FALSE;
+
+ g_value_take_boxed (dest, gst_date_time_new (year, month, day, hour,
+ minute, second, usecond, offset));
+ return TRUE;
+}
+
static void
gst_value_transform_date_string (const GValue * src_value, GValue * dest_value)
{
@@ -4223,6 +4300,21 @@ gst_date_get_type (void)
return gst_date_type;
}
+GType
+gst_date_time_get_type (void)
+{
+ static GType gst_date_time_type = 0;
+
+ if (G_UNLIKELY (gst_date_time_type == 0)) {
+ gst_date_time_type = g_boxed_type_register_static ("GstDateTime",
+ (GBoxedCopyFunc) gst_date_time_ref,
+ (GBoxedFreeFunc) gst_date_time_unref);
+ }
+
+ return gst_date_time_type;
+}
+
+
void
_gst_value_initialize (void)
{
@@ -4374,6 +4466,17 @@ _gst_value_initialize (void)
gst_value.type = gst_date_get_type ();
gst_value_register (&gst_value);
}
+ {
+ static GstValueTable gst_value = {
+ 0,
+ gst_value_compare_date_time,
+ gst_value_serialize_date_time,
+ gst_value_deserialize_date_time,
+ };
+
+ gst_value.type = gst_date_time_get_type ();
+ gst_value_register (&gst_value);
+ }
REGISTER_SERIALIZATION (G_TYPE_DOUBLE, double);
REGISTER_SERIALIZATION (G_TYPE_FLOAT, float);
diff --git a/gst/gstvalue.h b/gst/gstvalue.h
index 6faf958355..bc208733a6 100644
--- a/gst/gstvalue.h
+++ b/gst/gstvalue.h
@@ -175,6 +175,16 @@ G_BEGIN_DECLS
*/
#define GST_VALUE_HOLDS_DATE(x) (G_VALUE_HOLDS((x), gst_date_get_type ()))
+/**
+ * GST_VALUE_HOLDS_DATE_TIME:
+ * @x: the #GValue to check
+ *
+ * Checks if the given #GValue contains a #GST_TYPE_DATE_TIME value.
+ *
+ * Since: 0.10.31
+ */
+#define GST_VALUE_HOLDS_DATE_TIME(x) (G_VALUE_HOLDS((x), gst_date_time_get_type ()))
+
/**
* GST_TYPE_FOURCC:
*
@@ -259,6 +269,17 @@ G_BEGIN_DECLS
#define GST_TYPE_DATE gst_date_get_type ()
+/**
+ * GST_TYPE_DATE_TIME:
+ *
+ * a boxed #GValue type for #GstDateTime that represents a date and time.
+ *
+ * Returns: the #GType of GstDateTime
+ * Since: 0.10.31
+ */
+
+#define GST_TYPE_DATE_TIME gst_date_time_get_type ()
+
/**
* GST_VALUE_LESS_THAN:
*
@@ -403,6 +424,7 @@ GType gst_value_list_get_type (void);
GType gst_value_array_get_type (void);
GType gst_date_get_type (void);
+GType gst_date_time_get_type (void);
void gst_value_register (const GstValueTable *table);
void gst_value_init_and_copy (GValue *dest,
diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def
index 79dcf48ed6..c9759cb563 100644
--- a/win32/common/libgstreamer.def
+++ b/win32/common/libgstreamer.def
@@ -235,6 +235,7 @@ EXPORTS
gst_date_time_get_month
gst_date_time_get_second
gst_date_time_get_time_zone_offset
+ gst_date_time_get_type
gst_date_time_get_year
gst_date_time_new
gst_date_time_new_from_unix_epoch