From dc02d91c14847e48b6e830ff58f2dd27ecae336d Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 16 Sep 2013 11:20:51 -0300 Subject: [PATCH] qtdemux: add code to parse creation time earlier than 1970 Use g_date_time seconds manipulation to allow to cover the quicktime spec for creation_time. It uses seconds since 1904. Both paths could be done using the generic approach of seconds since 1904 with GDateTime handling, but the first path using seconds from 1970 should be more commonly found and avoids a few objects creation and ref/unref, so keep it there for performance. Additionally, the code for handling seconds since 1970 changed from > to >= because having 0 seconds since 1970 is also a valid case for that path to handle. https://bugzilla.gnome.org/show_bug.cgi?id=707975 --- gst/isomp4/qtdemux.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index d2f3b878e7..79d74515e6 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -9842,7 +9842,8 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) /* Moving qt creation time (secs since 1904) to unix time */ if (creation_time != 0) { - if (creation_time > QTDEMUX_SECONDS_FROM_1904_TO_1970) { + /* Try to use epoch first as it should be faster and more commonly found */ + if (creation_time >= QTDEMUX_SECONDS_FROM_1904_TO_1970) { GTimeVal now; creation_time -= QTDEMUX_SECONDS_FROM_1904_TO_1970; @@ -9851,11 +9852,18 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) if (now.tv_sec + 24 * 3600 < creation_time) { GST_DEBUG_OBJECT (qtdemux, "discarding bogus future creation time"); } else { - datetime = gst_date_time_new_from_unix_epoch_local_time (creation_time); + datetime = gst_date_time_new_from_unix_epoch_utc (creation_time); } } else { - GST_WARNING_OBJECT (qtdemux, "Can't handle datetimes before 1970 yet, " - "please file a bug at http://bugzilla.gnome.org"); + GDateTime *base_dt = g_date_time_new_utc (1904, 1, 1, 0, 0, 0); + GDateTime *dt, *dt_local; + + dt = g_date_time_add_seconds (base_dt, creation_time); + dt_local = g_date_time_to_local (dt); + datetime = gst_date_time_new_from_g_date_time (dt_local); + + g_date_time_unref (base_dt); + g_date_time_unref (dt); } } if (datetime) {