rtsprange: add method to convert ranges to GstClockTime

Add a method to convert the values of GstRTSPRange to GstClockTime.
Add unit tests for the conversions.

API: gst_rtsp_range_get_times()
This commit is contained in:
Wim Taymans 2012-11-21 15:29:59 +01:00
parent f1669d7d9c
commit fdf904db32
3 changed files with 161 additions and 0 deletions

View file

@ -401,3 +401,108 @@ gst_rtsp_range_free (GstRTSPTimeRange * range)
g_free (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;
}

View file

@ -44,6 +44,7 @@
#define __GST_RTSP_RANGE_H__ #define __GST_RTSP_RANGE_H__
#include <glib.h> #include <glib.h>
#include <gst/gst.h>
#include <gst/rtsp/gstrtspdefs.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); gchar * gst_rtsp_range_to_string (const GstRTSPTimeRange *range);
void gst_rtsp_range_free (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 G_END_DECLS
#endif /* __GST_RTSP_RANGE_H__ */ #endif /* __GST_RTSP_RANGE_H__ */

View file

@ -124,6 +124,7 @@ GST_END_TEST;
GST_START_TEST (test_rtsp_range_npt) GST_START_TEST (test_rtsp_range_npt)
{ {
GstRTSPTimeRange *range; GstRTSPTimeRange *range;
GstClockTime min, max;
fail_unless (gst_rtsp_range_parse ("npt=", &range) == GST_RTSP_EINVAL); 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 (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->unit == GST_RTSP_RANGE_NPT);
fail_unless (range->min.type == GST_RTSP_TIME_END); fail_unless (range->min.type == GST_RTSP_TIME_END);
fail_unless (range->max.type == GST_RTSP_TIME_NOW); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=now-now", &range) == GST_RTSP_OK); 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->min.type == GST_RTSP_TIME_NOW);
fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->max.seconds == 34.12); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=23,89-now", &range) == GST_RTSP_OK); 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.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->min.seconds == 23.89); fail_unless (range->min.seconds == 23.89);
fail_unless (range->max.type == GST_RTSP_TIME_NOW); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=-12.09", &range) == GST_RTSP_OK); 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->min.type == GST_RTSP_TIME_END);
fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->max.seconds == 12.09); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=0-", &range) == GST_RTSP_OK); 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.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->min.seconds == 0.0); fail_unless (range->min.seconds == 0.0);
fail_unless (range->max.type == GST_RTSP_TIME_END); 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); 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.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->min.seconds == 1.123); fail_unless (range->min.seconds == 1.123);
fail_unless (range->max.type == GST_RTSP_TIME_END); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=10,20-20.10", &range) == GST_RTSP_OK); 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->min.seconds == 10.20);
fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->max.seconds == 20.10); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=500-15.001", &range) == GST_RTSP_OK); 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->min.seconds == 500);
fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->max.seconds == 15.001); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("npt=20:34.23-", 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->min.seconds == 72754.23);
fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); fail_unless (range->max.type == GST_RTSP_TIME_SECONDS);
fail_unless (range->max.seconds == 78300.01); 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_rtsp_range_free (range);
} }
@ -220,6 +248,7 @@ GST_END_TEST;
GST_START_TEST (test_rtsp_range_smpte) GST_START_TEST (test_rtsp_range_smpte)
{ {
GstClockTime min, max;
GstRTSPTimeRange *range; GstRTSPTimeRange *range;
fail_unless (gst_rtsp_range_parse ("smpte=", &range) == GST_RTSP_EINVAL); 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->min.seconds == 0.0);
fail_unless (range->min2.frames == 0.0); fail_unless (range->min2.frames == 0.0);
fail_unless (range->max.type == GST_RTSP_TIME_END); 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); gst_rtsp_range_free (range);
fail_unless (gst_rtsp_range_parse ("smpte=10:34:23-20:12:09:20.89", 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.type == GST_RTSP_TIME_FRAMES);
fail_unless (range->max.seconds == 72729.0); fail_unless (range->max.seconds == 72729.0);
fail_unless (range->max2.frames == 20.89); 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); gst_rtsp_range_free (range);
} }