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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7431>
This commit is contained in:
Sebastian Dröge 2024-08-26 19:13:11 +03:00 committed by Backport Bot
parent ff538e4adf
commit 49e14405cb

View file

@ -4454,10 +4454,15 @@ gst_util_group_id_next (void)
return ret; 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 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:
<http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
const guint64 b[] = const guint64 b[] =
{ 0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000LL }; { 0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000LL };
const guint64 S[] = { 1, 2, 4, 8, 16, 32 }; 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 * That means that each number must require at most (63 - 1) / 2 bits = 31
* bits of storage. * 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) if (max_bits > 31)
pshift = max_bits - 31; pshift = max_bits - 31;