mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 20:51:13 +00:00
utils: improve gst_util_ceil_log2
According to the following comparison of algorithms, the value for 0 and 1 was giving an incorrect result. https://gist.github.com/ceyusa/6061b33ac109a68bcd222f6919968c9a More information here: https://github.com/rofrol/codeforces/blob/master/ceil_log2.c Use a different algorithm which offers better result and keep the performance. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7429>
This commit is contained in:
parent
65e071c1c8
commit
a6f82ba590
3 changed files with 41 additions and 20 deletions
|
@ -57259,7 +57259,7 @@ element or %NULL if nothing was found</doc>
|
||||||
</parameters>
|
</parameters>
|
||||||
</function>
|
</function>
|
||||||
<function name="util_ceil_log2" c:identifier="gst_util_ceil_log2" version="1.24">
|
<function name="util_ceil_log2" c:identifier="gst_util_ceil_log2" version="1.24">
|
||||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">Return a max num of log2.</doc>
|
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">Returns smallest integral value not less than log2(v).</doc>
|
||||||
<source-position filename="../subprojects/gstreamer/gst/gstutils.h"/>
|
<source-position filename="../subprojects/gstreamer/gst/gstutils.h"/>
|
||||||
<return-value transfer-ownership="none">
|
<return-value transfer-ownership="none">
|
||||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">a computed #guint val.</doc>
|
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstutils.c">a computed #guint val.</doc>
|
||||||
|
|
|
@ -4484,7 +4484,7 @@ gst_bit_storage_uint64 (guint64 in)
|
||||||
* gst_util_ceil_log2:
|
* gst_util_ceil_log2:
|
||||||
* @v: a #guint32 value.
|
* @v: a #guint32 value.
|
||||||
*
|
*
|
||||||
* Return a max num of log2.
|
* Returns smallest integral value not less than log2(v).
|
||||||
*
|
*
|
||||||
* Returns: a computed #guint val.
|
* Returns: a computed #guint val.
|
||||||
*
|
*
|
||||||
|
@ -4493,25 +4493,29 @@ gst_bit_storage_uint64 (guint64 in)
|
||||||
guint
|
guint
|
||||||
gst_util_ceil_log2 (guint32 v)
|
gst_util_ceil_log2 (guint32 v)
|
||||||
{
|
{
|
||||||
/* Compute Ceil(Log2(v)) */
|
static const unsigned int t[6] = {
|
||||||
/* Derived from branchless code for integer log2(v) from:
|
0x00000000ull,
|
||||||
<http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
|
0xFFFF0000ull,
|
||||||
guint r, shift;
|
0x0000FF00ull,
|
||||||
|
0x000000F0ull,
|
||||||
|
0x0000000Cull,
|
||||||
|
0x000000002ull
|
||||||
|
};
|
||||||
|
|
||||||
v--;
|
g_return_val_if_fail (v != 0, -1);
|
||||||
r = (v > 0xFFFF) << 4;
|
|
||||||
v >>= r;
|
int y = (((v & (v - 1)) == 0) ? 0 : 1);
|
||||||
shift = (v > 0xFF) << 3;
|
int j = 32;
|
||||||
v >>= shift;
|
int i;
|
||||||
r |= shift;
|
|
||||||
shift = (v > 0xF) << 2;
|
for (i = 0; i < 6; i++) {
|
||||||
v >>= shift;
|
int k = (((v & t[i]) == 0) ? 0 : j);
|
||||||
r |= shift;
|
y += k;
|
||||||
shift = (v > 0x3) << 1;
|
v >>= k;
|
||||||
v >>= shift;
|
j >>= 1;
|
||||||
r |= shift;
|
}
|
||||||
r |= (v >> 1);
|
|
||||||
return r + 1;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1990,6 +1990,21 @@ GST_START_TEST (test_regression)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
// 10 Values
|
||||||
|
static const int ceil_log2_values[] = {
|
||||||
|
-1, 0, 1, 2, 2, 3, 3, 3, 3, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
GST_START_TEST (test_ceil_log2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < 10; i++) {
|
||||||
|
fail_unless_equals_int (gst_util_ceil_log2 (i), ceil_log2_values[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_mark_as_plugin_api)
|
GST_START_TEST (test_mark_as_plugin_api)
|
||||||
{
|
{
|
||||||
GstPluginAPIFlags api_flags;
|
GstPluginAPIFlags api_flags;
|
||||||
|
@ -2053,6 +2068,8 @@ gst_utils_suite (void)
|
||||||
|
|
||||||
tcase_add_test (tc_chain, test_mark_as_plugin_api);
|
tcase_add_test (tc_chain, test_mark_as_plugin_api);
|
||||||
|
|
||||||
|
tcase_add_test (tc_chain, test_ceil_log2);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue