mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-08 18:39:54 +00:00
check/gst/gstutils.c: Added test for scaling.
Original commit message from CVS: * check/gst/gstutils.c: (GST_START_TEST), (gst_utils_suite): Added test for scaling. * gst/gstclock.h: Small doc fix. * gst/gstutils.c: (gst_util_uint64_scale_int): Implemented high precision scaling code.
This commit is contained in:
parent
9cd1643368
commit
fbf5f16d69
5 changed files with 130 additions and 4 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2005-11-24 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* check/gst/gstutils.c: (GST_START_TEST), (gst_utils_suite):
|
||||
Added test for scaling.
|
||||
|
||||
* gst/gstclock.h:
|
||||
Small doc fix.
|
||||
|
||||
* gst/gstutils.c: (gst_util_uint64_scale_int):
|
||||
Implemented high precision scaling code.
|
||||
|
||||
2005-11-24 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* gst/gstinfo.h:
|
||||
|
|
|
@ -167,6 +167,37 @@ GST_START_TEST (test_buffer_probe_once)
|
|||
g_assert (n_data_probes_once == 1); /* let's hit it and quit!!! */
|
||||
} GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_math_scale)
|
||||
{
|
||||
fail_if (gst_util_uint64_scale_int (1, 1, 1) != 1);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (10, 10, 1) != 100);
|
||||
fail_if (gst_util_uint64_scale_int (10, 10, 2) != 50);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (0, 10, 2) != 0);
|
||||
fail_if (gst_util_uint64_scale_int (0, 0, 2) != 0);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 5, 1) != G_MAXUINT32 * 5LL);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 10, 2) != G_MAXUINT32 * 5LL);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 1, 5) != G_MAXUINT32 / 5LL);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 2, 10) != G_MAXUINT32 / 5LL);
|
||||
|
||||
/* not quite overflow */
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, 10,
|
||||
10) != G_MAXUINT64 - 1);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, G_MAXINT32,
|
||||
G_MAXINT32) != G_MAXUINT64 - 1);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 100, G_MAXINT32,
|
||||
G_MAXINT32) != G_MAXUINT64 - 100);
|
||||
|
||||
/* overflow */
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, 10, 1) != G_MAXUINT64);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, G_MAXINT32,
|
||||
1) != G_MAXUINT64);
|
||||
|
||||
} GST_END_TEST;
|
||||
|
||||
Suite *
|
||||
gst_utils_suite (void)
|
||||
{
|
||||
|
@ -176,6 +207,7 @@ gst_utils_suite (void)
|
|||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_buffer_probe_n_times);
|
||||
tcase_add_test (tc_chain, test_buffer_probe_once);
|
||||
tcase_add_test (tc_chain, test_math_scale);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef gint64 GstClockTimeDiff;
|
|||
/**
|
||||
* GstClockID:
|
||||
*
|
||||
* A datatype to hold the handle to an outstanding async clock callback.
|
||||
* A datatype to hold the handle to an outstanding sync or async clock callback.
|
||||
*/
|
||||
typedef gpointer GstClockID;
|
||||
|
||||
|
|
|
@ -340,6 +340,22 @@ gst_gdouble_to_guint64 (gdouble value)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* convenience struct for getting high an low uint32 parts of
|
||||
* a guint64 */
|
||||
typedef union
|
||||
{
|
||||
guint64 ll;
|
||||
struct
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
guint32 high, low;
|
||||
#else
|
||||
guint32 low, high;
|
||||
#endif
|
||||
} l;
|
||||
} GstUInt64;
|
||||
|
||||
/**
|
||||
* gst_util_uint64_scale:
|
||||
* @val: the number to scale
|
||||
|
@ -360,19 +376,54 @@ gst_util_uint64_scale (guint64 val, guint64 num, guint64 denom)
|
|||
|
||||
/**
|
||||
* gst_util_uint64_scale_int:
|
||||
* @val: GstClockTime to scale.
|
||||
* @val: guint64 (such as a #GstClockTime) to scale.
|
||||
* @num: numerator of the scale factor.
|
||||
* @denom: denominator of the scale factor.
|
||||
*
|
||||
* Scale a clocktime by a factor expressed as a fraction (num/denom), avoiding
|
||||
* Scale a guint64 by a factor expressed as a fraction (num/denom), avoiding
|
||||
* overflows and loss of precision.
|
||||
*
|
||||
* @num and @denom must be positive integers. @denom cannot be 0.
|
||||
*
|
||||
* Returns: @val * @num / @denom, avoiding overflow and loss of precision
|
||||
*/
|
||||
guint64
|
||||
gst_util_uint64_scale_int (guint64 val, gint num, gint denom)
|
||||
{
|
||||
return val * num / denom;
|
||||
GstUInt64 result;
|
||||
|
||||
g_return_val_if_fail (denom > 0, G_MAXUINT64);
|
||||
g_return_val_if_fail (num >= 0, G_MAXUINT64);
|
||||
|
||||
if (val <= G_MAXUINT32) {
|
||||
/* simple case */
|
||||
result.ll = val * num / denom;
|
||||
} else {
|
||||
GstUInt64 gval, low, high, temp;
|
||||
|
||||
/* do 96 bits mult/div */
|
||||
gval.ll = val;
|
||||
low.ll = ((guint64) gval.l.low) * num;
|
||||
high.ll = ((guint64) gval.l.high) * num + (low.l.high);
|
||||
result.ll = (high.ll / denom);
|
||||
temp.l.high = (high.ll % denom);
|
||||
temp.l.low = (low.l.low);
|
||||
temp.ll /= denom;
|
||||
|
||||
/* avoid overflow */
|
||||
if (result.ll + temp.l.high > G_MAXUINT32)
|
||||
goto overflow;
|
||||
|
||||
result.l.high = result.l.low;
|
||||
result.l.low = 0;
|
||||
result.ll += temp.ll;
|
||||
}
|
||||
return result.ll;
|
||||
|
||||
overflow:
|
||||
{
|
||||
return G_MAXUINT64;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------
|
||||
|
|
|
@ -167,6 +167,37 @@ GST_START_TEST (test_buffer_probe_once)
|
|||
g_assert (n_data_probes_once == 1); /* let's hit it and quit!!! */
|
||||
} GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_math_scale)
|
||||
{
|
||||
fail_if (gst_util_uint64_scale_int (1, 1, 1) != 1);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (10, 10, 1) != 100);
|
||||
fail_if (gst_util_uint64_scale_int (10, 10, 2) != 50);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (0, 10, 2) != 0);
|
||||
fail_if (gst_util_uint64_scale_int (0, 0, 2) != 0);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 5, 1) != G_MAXUINT32 * 5LL);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 10, 2) != G_MAXUINT32 * 5LL);
|
||||
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 1, 5) != G_MAXUINT32 / 5LL);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 2, 10) != G_MAXUINT32 / 5LL);
|
||||
|
||||
/* not quite overflow */
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, 10,
|
||||
10) != G_MAXUINT64 - 1);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, G_MAXINT32,
|
||||
G_MAXINT32) != G_MAXUINT64 - 1);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 100, G_MAXINT32,
|
||||
G_MAXINT32) != G_MAXUINT64 - 100);
|
||||
|
||||
/* overflow */
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, 10, 1) != G_MAXUINT64);
|
||||
fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, G_MAXINT32,
|
||||
1) != G_MAXUINT64);
|
||||
|
||||
} GST_END_TEST;
|
||||
|
||||
Suite *
|
||||
gst_utils_suite (void)
|
||||
{
|
||||
|
@ -176,6 +207,7 @@ gst_utils_suite (void)
|
|||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_buffer_probe_n_times);
|
||||
tcase_add_test (tc_chain, test_buffer_probe_once);
|
||||
tcase_add_test (tc_chain, test_math_scale);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue