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;
+}
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);
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);
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);
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);
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);
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);
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);
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);
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-",
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);
}
GST_START_TEST (test_rtsp_range_smpte)
{
+ GstClockTime min, max;
GstRTSPTimeRange *range;
fail_unless (gst_rtsp_range_parse ("smpte=", &range) == GST_RTSP_EINVAL);
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",
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);
}