From fa15af376fcda1e88ca38d60c75e48e8ca845b19 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 24 Jan 2025 16:21:59 +0100 Subject: [PATCH] context: avoid some scaling overflows Make a macro to scale without overflows and use this in the context. --- spa/include/spa/utils/defs.h | 7 +++++++ src/pipewire/context.c | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/spa/include/spa/utils/defs.h b/spa/include/spa/utils/defs.h index 3c2a8dd49..1c1a73abf 100644 --- a/spa/include/spa/utils/defs.h +++ b/spa/include/spa/utils/defs.h @@ -292,6 +292,13 @@ struct spa_fraction { #define SPA_ROUND_DOWN_N(num,align) ((num) & ~SPA_ROUND_MASK(num, align)) #define SPA_ROUND_UP_N(num,align) ((((num)-1) | SPA_ROUND_MASK(num, align))+1) +#define SPA_SCALE32(val,num,denom) \ +({ \ + uint64_t _val = (val); \ + uint64_t _denom = (denom); \ + (uint32_t)(((_val) * (num)) / (_denom)); \ +}) + #define SPA_SCALE32_UP(val,num,denom) \ ({ \ uint64_t _val = (val); \ diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 5c6eeb196..86d80d6e5 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -1799,15 +1799,15 @@ again: if (node_rate_quantum != 0 && current_rate != node_rate_quantum) { /* the quantum values are scaled with the current rate */ - node_def_quantum = node_def_quantum * current_rate / node_rate_quantum; - node_min_quantum = node_min_quantum * current_rate / node_rate_quantum; - node_max_quantum = node_max_quantum * current_rate / node_rate_quantum; + node_def_quantum = SPA_SCALE32(node_def_quantum, current_rate, node_rate_quantum); + node_min_quantum = SPA_SCALE32(node_min_quantum, current_rate, node_rate_quantum); + node_max_quantum = SPA_SCALE32(node_max_quantum, current_rate, node_rate_quantum); } /* calculate desired quantum. Don't limit to the max_latency when we are * going to force a quantum or rate and reconfigure the nodes. */ if (max_latency.denom != 0 && !force_quantum && !force_rate) { - uint32_t tmp = ((uint64_t)max_latency.num * current_rate / max_latency.denom); + uint32_t tmp = SPA_SCALE32(max_latency.num, current_rate, max_latency.denom); if (tmp < node_max_quantum) node_max_quantum = tmp; } @@ -1824,7 +1824,7 @@ again: else { target_quantum = node_def_quantum; if (latency.denom != 0) - target_quantum = (latency.num * current_rate / latency.denom); + target_quantum = SPA_SCALE32(latency.num, current_rate, latency.denom); target_quantum = SPA_CLAMP(target_quantum, node_min_quantum, node_max_quantum); target_quantum = SPA_CLAMP(target_quantum, floor_quantum, ceil_quantum);