mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
gstreamer: gst-utils: add gst_util_simplify_fraction
We add the gst_util_simplify_fraction function to be able to convert fractions such as 333333/10000000 to 1/30. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1304>
This commit is contained in:
parent
395e0c3925
commit
1528ab2e7a
3 changed files with 101 additions and 0 deletions
|
@ -53907,6 +53907,35 @@ if the conversion worked or not.</doc>
|
|||
</parameter>
|
||||
</parameters>
|
||||
</function>
|
||||
<function name="util_simplify_fraction" c:identifier="gst_util_simplify_fraction" version="1.24">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">Calculates the simpler representation of @a and @b.
|
||||
|
||||
Simplify a fraction using a simple continued fraction decomposition.
|
||||
The idea here is to convert fractions such as 333333/10000000 to 1/30
|
||||
using 32 bit arithmetic only. The algorithm is not perfect and relies
|
||||
upon two arbitrary parameters to remove non-significative terms from
|
||||
the simple continued fraction decomposition. Using 8 and 333 for
|
||||
n_terms and threshold respectively seems to give nice results.</doc>
|
||||
<source-position filename="../subprojects/gstreamer/gst/gstutils.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<type name="none" c:type="void"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<parameter name="numerator" transfer-ownership="none">
|
||||
<type name="gint" c:type="gint*"/>
|
||||
</parameter>
|
||||
<parameter name="denominator" transfer-ownership="none">
|
||||
<type name="gint" c:type="gint*"/>
|
||||
</parameter>
|
||||
<parameter name="n_terms" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">non-significative terms (typical value: 8)</doc>
|
||||
<type name="guint" c:type="guint"/>
|
||||
</parameter>
|
||||
<parameter name="threshold" transfer-ownership="none">
|
||||
<type name="guint" c:type="guint"/>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</function>
|
||||
<function name="util_uint64_scale" c:identifier="gst_util_uint64_scale">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">Scale @val by the rational number @num / @denom, avoiding overflows and
|
||||
underflows and without loss of precision.
|
||||
|
|
|
@ -3669,6 +3669,74 @@ gst_util_greatest_common_divisor_int64 (gint64 a, gint64 b)
|
|||
return ABS (a);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_util_simplify_fraction:
|
||||
* @a: First value as #gint
|
||||
* @b: Second value as #gint
|
||||
* @n_terms: non-significative terms (typical value: 8)
|
||||
* @threashold: threshold (typical value: 333)
|
||||
*
|
||||
* Calculates the simpler representation of @a and @b.
|
||||
*
|
||||
* Simplify a fraction using a simple continued fraction decomposition.
|
||||
* The idea here is to convert fractions such as 333333/10000000 to 1/30
|
||||
* using 32 bit arithmetic only. The algorithm is not perfect and relies
|
||||
* upon two arbitrary parameters to remove non-significative terms from
|
||||
* the simple continued fraction decomposition. Using 8 and 333 for
|
||||
* n_terms and threshold respectively seems to give nice results.
|
||||
*
|
||||
* Returns: simple representation of @a and @b
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
void
|
||||
gst_util_simplify_fraction (gint * numerator, gint * denominator,
|
||||
guint n_terms, guint threshold)
|
||||
{
|
||||
guint *an;
|
||||
guint x, y, r;
|
||||
guint i, n;
|
||||
|
||||
an = g_malloc_n (n_terms, sizeof (*an));
|
||||
if (an == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Convert the fraction to a simple continued fraction. See
|
||||
* https://en.wikipedia.org/wiki/Continued_fraction
|
||||
* Stop if the current term is bigger than or equal to the given
|
||||
* threshold.
|
||||
*/
|
||||
x = *numerator;
|
||||
y = *denominator;
|
||||
|
||||
for (n = 0; n < n_terms && y != 0; ++n) {
|
||||
an[n] = x / y;
|
||||
if (an[n] >= threshold) {
|
||||
if (n < 2)
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
|
||||
r = x - an[n] * y;
|
||||
x = y;
|
||||
y = r;
|
||||
}
|
||||
|
||||
/* Expand the simple continued fraction back to an integer fraction. */
|
||||
x = 0;
|
||||
y = 1;
|
||||
|
||||
for (i = n; i > 0; --i) {
|
||||
r = y;
|
||||
y = an[i - 1] * y + x;
|
||||
x = r;
|
||||
}
|
||||
|
||||
*numerator = y;
|
||||
*denominator = x;
|
||||
g_free (an);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_util_fraction_to_double:
|
||||
|
|
|
@ -1208,6 +1208,10 @@ gint gst_util_greatest_common_divisor (gint a, gint b);
|
|||
GST_API
|
||||
gint64 gst_util_greatest_common_divisor_int64 (gint64 a, gint64 b);
|
||||
|
||||
GST_API
|
||||
void gst_util_simplify_fraction (gint *numerator, gint *denominator,
|
||||
guint n_terms, guint threshold);
|
||||
|
||||
GST_API
|
||||
void gst_util_fraction_to_double (gint src_n, gint src_d, gdouble *dest);
|
||||
|
||||
|
|
Loading…
Reference in a new issue