summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'media-video/pipewire/files/0.3.64/0001-spa-Fix-audioconvert-overflow-when-scaling.patch')
-rw-r--r--media-video/pipewire/files/0.3.64/0001-spa-Fix-audioconvert-overflow-when-scaling.patch65
1 files changed, 65 insertions, 0 deletions
diff --git a/media-video/pipewire/files/0.3.64/0001-spa-Fix-audioconvert-overflow-when-scaling.patch b/media-video/pipewire/files/0.3.64/0001-spa-Fix-audioconvert-overflow-when-scaling.patch
new file mode 100644
index 000000000000..e24b8153ef6d
--- /dev/null
+++ b/media-video/pipewire/files/0.3.64/0001-spa-Fix-audioconvert-overflow-when-scaling.patch
@@ -0,0 +1,65 @@
+https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/1d9640af5a7906620f214aa0a39c63128c8506a6.
+
+From 1d9640af5a7906620f214aa0a39c63128c8506a6 Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wtaymans@redhat.com>
+Date: Mon, 16 Jan 2023 18:28:31 +0100
+Subject: [PATCH] spa: Fix audioconvert overflow when scaling
+
+Add SPA_SCALE32_UP that scales a uint32 without overflow.
+Use this for scaling the threshold in ALSA.
+Fix the scaling in audioconvert of the buffer size, the scaling was
+wrong and it was also causing an overflow resulting in choppy sound in
+some cases.
+
+See #2680
+--- a/spa/include/spa/utils/defs.h
++++ b/spa/include/spa/utils/defs.h
+@@ -274,6 +274,14 @@ 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_UP(val,num,denom) \
++({ \
++ uint64_t _val = (val); \
++ uint64_t _denom = (denom); \
++ (uint32_t)(((_val) * (num) + (_denom)-1) / (_denom)); \
++})
++
++
+ #define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1))
+ #define SPA_IS_ALIGNED(p,align) (SPA_PTR_ALIGNMENT(p,align) == 0)
+ #define SPA_PTR_ALIGN(p,align,type) ((type*)SPA_ROUND_UP_N((intptr_t)(p), (intptr_t)(align)))
+--- a/spa/plugins/alsa/alsa-pcm.c
++++ b/spa/plugins/alsa/alsa-pcm.c
+@@ -1999,7 +1999,7 @@ static inline void check_position_config(struct state *state)
+ (state->rate_denom != state->position->clock.rate.denom))) {
+ state->duration = state->position->clock.duration;
+ state->rate_denom = state->position->clock.rate.denom;
+- state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
++ state->threshold = SPA_SCALE32_UP(state->duration, state->rate, state->rate_denom);
+ state->max_error = SPA_MAX(256.0f, state->threshold / 2.0f);
+ state->resample = ((uint32_t)state->rate != state->rate_denom) || state->matching;
+ state->alsa_sync = true;
+@@ -2569,7 +2569,7 @@ int spa_alsa_start(struct state *state)
+ setup_matching(state);
+
+ spa_dll_init(&state->dll);
+- state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
++ state->threshold = SPA_SCALE32_UP(state->duration, state->rate, state->rate_denom);
+ state->last_threshold = state->threshold;
+ state->max_error = SPA_MAX(256.0f, state->threshold / 2.0f);
+
+--- a/spa/plugins/audioconvert/audioconvert.c
++++ b/spa/plugins/audioconvert/audioconvert.c
+@@ -1755,7 +1755,7 @@ impl_node_port_enum_params(void *object, int seq,
+ size = this->quantum_limit * 2;
+ /* scale the buffer size when we can. */
+ if (irate != 0 && orate != 0)
+- size = size * (irate + orate - 1) / orate;
++ size = SPA_SCALE32_UP(size, irate, orate);
+ }
+
+ param = spa_pod_builder_add_object(&b,
+--
+2.39.1
+