mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 03:01:03 +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>
|
||||
</function>
|
||||
<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"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<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:
|
||||
* @v: a #guint32 value.
|
||||
*
|
||||
* Return a max num of log2.
|
||||
* Returns smallest integral value not less than log2(v).
|
||||
*
|
||||
* Returns: a computed #guint val.
|
||||
*
|
||||
|
@ -4493,25 +4493,29 @@ gst_bit_storage_uint64 (guint64 in)
|
|||
guint
|
||||
gst_util_ceil_log2 (guint32 v)
|
||||
{
|
||||
/* Compute Ceil(Log2(v)) */
|
||||
/* Derived from branchless code for integer log2(v) from:
|
||||
<http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
|
||||
guint r, shift;
|
||||
static const unsigned int t[6] = {
|
||||
0x00000000ull,
|
||||
0xFFFF0000ull,
|
||||
0x0000FF00ull,
|
||||
0x000000F0ull,
|
||||
0x0000000Cull,
|
||||
0x000000002ull
|
||||
};
|
||||
|
||||
v--;
|
||||
r = (v > 0xFFFF) << 4;
|
||||
v >>= r;
|
||||
shift = (v > 0xFF) << 3;
|
||||
v >>= shift;
|
||||
r |= shift;
|
||||
shift = (v > 0xF) << 2;
|
||||
v >>= shift;
|
||||
r |= shift;
|
||||
shift = (v > 0x3) << 1;
|
||||
v >>= shift;
|
||||
r |= shift;
|
||||
r |= (v >> 1);
|
||||
return r + 1;
|
||||
g_return_val_if_fail (v != 0, -1);
|
||||
|
||||
int y = (((v & (v - 1)) == 0) ? 0 : 1);
|
||||
int j = 32;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
int k = (((v & t[i]) == 0) ? 0 : j);
|
||||
y += k;
|
||||
v >>= k;
|
||||
j >>= 1;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1990,6 +1990,21 @@ GST_START_TEST (test_regression)
|
|||
|
||||
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)
|
||||
{
|
||||
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_ceil_log2);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue