diff --git a/gst-libs/gst/rtsp/gstrtsprange.c b/gst-libs/gst/rtsp/gstrtsprange.c index 35c005606c..9fd9dd498d 100644 --- a/gst-libs/gst/rtsp/gstrtsprange.c +++ b/gst-libs/gst/rtsp/gstrtsprange.c @@ -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; +} diff --git a/gst-libs/gst/rtsp/gstrtsprange.h b/gst-libs/gst/rtsp/gstrtsprange.h index 803d97e355..d3fceecd95 100644 --- a/gst-libs/gst/rtsp/gstrtsprange.h +++ b/gst-libs/gst/rtsp/gstrtsprange.h @@ -44,6 +44,7 @@ #define __GST_RTSP_RANGE_H__ #include +#include #include @@ -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__ */ diff --git a/tests/check/libs/rtsp.c b/tests/check/libs/rtsp.c index a349529232..c4565b7d88 100644 --- a/tests/check/libs/rtsp.c +++ b/tests/check/libs/rtsp.c @@ -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); }