From 49e14405cb513003433bc953eda8767113ac8b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 26 Aug 2024 19:13:11 +0300 Subject: [PATCH] clock: Fix calculation for number of bits needed to store a 64 bit value It was using log2(n) but what actually is needed is log2(n) + 1. Also add a fast-path that uses __builtin_clzll() on gcc/clang. Part-of: --- subprojects/gstreamer/gst/gstutils.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/subprojects/gstreamer/gst/gstutils.c b/subprojects/gstreamer/gst/gstutils.c index 9cce0480a2..e691eea9a5 100644 --- a/subprojects/gstreamer/gst/gstutils.c +++ b/subprojects/gstreamer/gst/gstutils.c @@ -4454,10 +4454,15 @@ gst_util_group_id_next (void) return ret; } -/* Compute log2 of the passed 64-bit number by finding the highest set bit */ +/* Compute the number of bits needed at least to store `in` */ static guint -gst_log2 (GstClockTime in) +gst_bit_storage_uint64 (guint64 in) { +#if defined(__GNUC__) && __GNUC__ >= 4 + return in ? 64 - __builtin_clzll (in) : 1; +#else + /* integer log2(v) from: + */ const guint64 b[] = { 0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000LL }; const guint64 S[] = { 1, 2, 4, 8, 16, 32 }; @@ -4471,7 +4476,8 @@ gst_log2 (GstClockTime in) } } - return count; + return count + 1; // + 1 to get the number of storage bits needed +#endif } /** @@ -4649,7 +4655,7 @@ gst_calculate_linear_regression (const GstClockTime * xy, * That means that each number must require at most (63 - 1) / 2 bits = 31 * bits of storage. */ - max_bits = gst_log2 (MAX (1, MAX (xmax - xmin, ymax - ymin))); + max_bits = gst_bit_storage_uint64 (MAX (1, MAX (xmax - xmin, ymax - ymin))); if (max_bits > 31) pshift = max_bits - 31;