matroskademux: Better calculation of framerate
authorDavid Schleef <ds@schleef.org>
Fri, 15 Apr 2011 06:24:56 +0000 (23:24 -0700)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Fri, 15 Apr 2011 11:27:57 +0000 (12:27 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=647833

gst/matroska/matroska-demux.c

index 0ebe5fc..ec0d2b0 100644 (file)
@@ -6317,6 +6317,31 @@ gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
   return TRUE;
 }
 
+static void
+gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
+{
+  static const int common_den[] = { 1, 2, 3, 4, 1001 };
+  int n, d;
+  int i;
+  guint64 a;
+
+  for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
+    d = common_den[i];
+    n = floor (0.5 + (d * 1e9) / duration);
+    a = gst_util_uint64_scale_int (1000000000, d, n);
+    if (duration >= a - 1 && duration <= a + 1) {
+      goto out;
+    }
+  }
+
+  gst_util_double_to_fraction (1e9 / duration, &n, &d);
+
+out:
+  /* set results */
+  *dest_n = n;
+  *dest_d = d;
+}
+
 static GstCaps *
 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
     videocontext, const gchar * codec_id, guint8 * data, guint size,
@@ -6612,21 +6637,15 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
         g_value_unset (&fps_double);
         g_value_unset (&fps_fraction);
       } else if (context->default_duration > 0) {
-        GValue fps_double = { 0, };
-        GValue fps_fraction = { 0, };
+        int fps_n, fps_d;
 
-        g_value_init (&fps_double, G_TYPE_DOUBLE);
-        g_value_init (&fps_fraction, GST_TYPE_FRACTION);
-        g_value_set_double (&fps_double, (gdouble) GST_SECOND /
-            gst_guint64_to_gdouble (context->default_duration));
-        g_value_transform (&fps_double, &fps_fraction);
+        gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
 
-        GST_DEBUG ("using default duration %" G_GUINT64_FORMAT,
-            context->default_duration);
+        GST_INFO ("using default duration %" G_GUINT64_FORMAT
+            " framerate %d/%d", context->default_duration, fps_n, fps_d);
 
-        gst_structure_set_value (structure, "framerate", &fps_fraction);
-        g_value_unset (&fps_double);
-        g_value_unset (&fps_fraction);
+        gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
+            fps_n, fps_d, NULL);
       } else {
         /* sort of a hack to get most codecs to support,
          * even if the default_duration is missing */