rtsprange: add method to convert ranges to GstClockTime
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 21 Nov 2012 14:29:59 +0000 (15:29 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 21 Nov 2012 14:35:46 +0000 (15:35 +0100)
Add a method to convert the values of GstRTSPRange to GstClockTime.
Add unit tests for the conversions.

API: gst_rtsp_range_get_times()

gst-libs/gst/rtsp/gstrtsprange.c
gst-libs/gst/rtsp/gstrtsprange.h
tests/check/libs/rtsp.c

index 35c0056..9fd9dd4 100644 (file)
@@ -401,3 +401,108 @@ gst_rtsp_range_free (GstRTSPTimeRange * range)
 
   g_free (range);
 }
+
+static GstClockTime
+get_seconds (const GstRTSPTime * t)
+{
+  gint num, denom;
+  /* don't do direct multiply with GST_SECOND to avoid rounding
+   * errors */
+  gst_util_double_to_fraction (t->seconds, &num, &denom);
+  return gst_util_uint64_scale_int (GST_SECOND, num, denom);
+}
+
+static GstClockTime
+get_frames (const GstRTSPTime2 * t, GstRTSPRangeUnit unit)
+{
+  gint num, denom;
+
+  gst_util_double_to_fraction (t->frames, &num, &denom);
+
+  switch (unit) {
+    case GST_RTSP_RANGE_SMPTE_25:
+      denom *= 25;
+      break;
+    case GST_RTSP_RANGE_SMPTE:
+    case GST_RTSP_RANGE_SMPTE_30_DROP:
+    default:
+      num *= 1001;
+      denom *= 30003;
+      break;
+  }
+  return gst_util_uint64_scale_int (GST_SECOND, num, denom);
+}
+
+static GstClockTime
+get_time (GstRTSPRangeUnit unit, const GstRTSPTime * t1,
+    const GstRTSPTime2 * t2)
+{
+  GstClockTime res;
+
+  switch (t1->type) {
+    case GST_RTSP_TIME_SECONDS:
+    {
+      res = get_seconds (t1);
+      break;
+    }
+    case GST_RTSP_TIME_UTC:
+    {
+      GDateTime *dt, *bt;
+      GTimeSpan span;
+
+      /* make time base, we use 1900 */
+      bt = g_date_time_new_utc (1900, 1, 1, 0, 0, 0.0);
+      /* convert to GDateTime without the seconds */
+      dt = g_date_time_new_utc (t2->year, t2->month, t2->day, 0, 0, 0.0);
+      /* get amount of microseconds */
+      span = g_date_time_difference (bt, dt);
+      g_date_time_unref (bt);
+      g_date_time_unref (dt);
+      /* add seconds */
+      res = get_seconds (t1) + (span * 1000);
+      break;
+    }
+    case GST_RTSP_TIME_FRAMES:
+      res = get_seconds (t1);
+      res += get_frames (t2, unit);
+      break;
+    default:
+    case GST_RTSP_TIME_NOW:
+    case GST_RTSP_TIME_END:
+      res = GST_CLOCK_TIME_NONE;
+      break;
+  }
+  return res;
+}
+
+/**
+ * gst_rtsp_range_get_times:
+ * @range: a #GstRTSPTimeRange
+ * @min: result minimum #GstClockTime
+ * @max: result maximum #GstClockTime
+ *
+ * Retrieve the minimum and maximum values from @range converted to
+ * #GstClockTime in @min and @max.
+ *
+ * A value of %GST_CLOCK_TIME_NONE will be used to signal #GST_RTSP_TIME_NOW
+ * and #GST_RTSP_TIME_END for @min and @max respectively.
+ *
+ * UTC times will be converted to nanoseconds since 1900.
+ *
+ * Returns: %TRUE on success.
+ *
+ * Since: 1.1.1
+ */
+gboolean
+gst_rtsp_range_get_times (const GstRTSPTimeRange * range,
+    GstClockTime * min, GstClockTime * max)
+{
+  g_return_val_if_fail (range != NULL, FALSE);
+
+  if (min)
+    *min = get_time (range->unit, &range->min, &range->min2);
+  if (max)
+    *max = get_time (range->unit, &range->max, &range->max2);
+
+  return TRUE;
+}
index 803d97e..d3fceec 100644 (file)
@@ -44,6 +44,7 @@
 #define __GST_RTSP_RANGE_H__
 
 #include <glib.h>
+#include <gst/gst.h>
 
 #include <gst/rtsp/gstrtspdefs.h>
 
@@ -145,6 +146,9 @@ GstRTSPResult   gst_rtsp_range_parse        (const gchar *rangestr, GstRTSPTimeR
 gchar *         gst_rtsp_range_to_string    (const GstRTSPTimeRange *range);
 void            gst_rtsp_range_free         (GstRTSPTimeRange *range);
 
+gboolean        gst_rtsp_range_get_times     (const GstRTSPTimeRange *range,
+                                              GstClockTime *min, GstClockTime *max);
+
 G_END_DECLS
 
 #endif /* __GST_RTSP_RANGE_H__ */
index a349529..c4565b7 100644 (file)
@@ -124,6 +124,7 @@ GST_END_TEST;
 GST_START_TEST (test_rtsp_range_npt)
 {
   GstRTSPTimeRange *range;
+  GstClockTime min, max;
 
   fail_unless (gst_rtsp_range_parse ("npt=", &range) == GST_RTSP_EINVAL);
   fail_unless (gst_rtsp_range_parse ("npt=0", &range) == GST_RTSP_EINVAL);
@@ -134,6 +135,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->unit == GST_RTSP_RANGE_NPT);
   fail_unless (range->min.type == GST_RTSP_TIME_END);
   fail_unless (range->max.type == GST_RTSP_TIME_NOW);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == GST_CLOCK_TIME_NONE);
+  fail_unless (max == GST_CLOCK_TIME_NONE);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=now-now", &range) == GST_RTSP_OK);
@@ -153,6 +157,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.type == GST_RTSP_TIME_NOW);
   fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->max.seconds == 34.12);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == GST_CLOCK_TIME_NONE);
+  fail_unless (max == 34120000000);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=23,89-now", &range) == GST_RTSP_OK);
@@ -160,6 +167,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->min.seconds == 23.89);
   fail_unless (range->max.type == GST_RTSP_TIME_NOW);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 23890000000);
+  fail_unless (max == GST_CLOCK_TIME_NONE);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=-12.09", &range) == GST_RTSP_OK);
@@ -167,6 +177,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.type == GST_RTSP_TIME_END);
   fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->max.seconds == 12.09);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == GST_CLOCK_TIME_NONE);
+  fail_unless (max == 12090000000);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=0-", &range) == GST_RTSP_OK);
@@ -174,6 +187,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->min.seconds == 0.0);
   fail_unless (range->max.type == GST_RTSP_TIME_END);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 0);
+  fail_unless (max == GST_CLOCK_TIME_NONE);
   gst_rtsp_range_free (range);
 
 
@@ -182,6 +198,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->min.seconds == 1.123);
   fail_unless (range->max.type == GST_RTSP_TIME_END);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 1123000000);
+  fail_unless (max == GST_CLOCK_TIME_NONE);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=10,20-20.10", &range) == GST_RTSP_OK);
@@ -190,6 +209,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.seconds == 10.20);
   fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->max.seconds == 20.10);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 10200000000);
+  fail_unless (max == 20100000000);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=500-15.001", &range) == GST_RTSP_OK);
@@ -198,6 +220,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.seconds == 500);
   fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->max.seconds == 15.001);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 500000000000);
+  fail_unless (max == 15001000000);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("npt=20:34.23-",
@@ -213,6 +238,9 @@ GST_START_TEST (test_rtsp_range_npt)
   fail_unless (range->min.seconds == 72754.23);
   fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
   fail_unless (range->max.seconds == 78300.01);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 72754230000000);
+  fail_unless (max == 78300010000000);
   gst_rtsp_range_free (range);
 }
 
@@ -220,6 +248,7 @@ GST_END_TEST;
 
 GST_START_TEST (test_rtsp_range_smpte)
 {
+  GstClockTime min, max;
   GstRTSPTimeRange *range;
 
   fail_unless (gst_rtsp_range_parse ("smpte=", &range) == GST_RTSP_EINVAL);
@@ -237,6 +266,9 @@ GST_START_TEST (test_rtsp_range_smpte)
   fail_unless (range->min.seconds == 0.0);
   fail_unless (range->min2.frames == 0.0);
   fail_unless (range->max.type == GST_RTSP_TIME_END);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 0);
+  fail_unless (max == GST_CLOCK_TIME_NONE);
   gst_rtsp_range_free (range);
 
   fail_unless (gst_rtsp_range_parse ("smpte=10:34:23-20:12:09:20.89",
@@ -248,6 +280,26 @@ GST_START_TEST (test_rtsp_range_smpte)
   fail_unless (range->max.type == GST_RTSP_TIME_FRAMES);
   fail_unless (range->max.seconds == 72729.0);
   fail_unless (range->max2.frames == 20.89);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 38063000000000);
+  /* 20.89 * GST_SECOND * 1001 / 30003 */
+  fail_unless (max == 72729000000000 + 696959970);
+  gst_rtsp_range_free (range);
+
+  fail_unless (gst_rtsp_range_parse ("smpte-25=10:34:23-20:12:09:20.89",
+          &range) == GST_RTSP_OK);
+  fail_unless (range->unit == GST_RTSP_RANGE_SMPTE_25);
+  fail_unless (range->min.type == GST_RTSP_TIME_FRAMES);
+  fail_unless (range->min.seconds == 38063.0);
+  fail_unless (range->min2.frames == 0.0);
+  fail_unless (range->max.type == GST_RTSP_TIME_FRAMES);
+  fail_unless (range->max.seconds == 72729.0);
+  fail_unless (range->max2.frames == 20.89);
+  fail_unless (gst_rtsp_range_get_times (range, &min, &max));
+  fail_unless (min == 38063000000000);
+  GST_DEBUG ("%" GST_TIME_FORMAT, GST_TIME_ARGS (max));
+  /* 20.89 * GST_SECOND * 1 / 25 */
+  fail_unless (max == 72729000000000 + 835600000);
   gst_rtsp_range_free (range);
 }