qtdemux: add code to parse creation time earlier than 1970
authorThiago Santos <thiago.sousa.santos@collabora.com>
Mon, 16 Sep 2013 14:20:51 +0000 (11:20 -0300)
committerThiago Santos <ts.santos@partner.samsung.com>
Tue, 24 Sep 2013 22:16:54 +0000 (15:16 -0700)
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

index d2f3b87..79d7451 100644 (file)
@@ -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) {