From 02ab738c317533f40ea49030f38170eec7e49dda Mon Sep 17 00:00:00 2001
From: Wim Taymans <wtaymans@redhat.com>
Date: Fri, 4 Feb 2022 11:59:57 +0100
Subject: [PATCH 2/2] pulse-server: make sure we don't exceed maxlength
Make sure the various buffer attributes don't exceed maxlength.
Add some SPA_ROUND_UP and SPA_ROUND_DOWN macros.
Fixes #2100
---
spa/include/spa/utils/defs.h | 3 +++
.../module-protocol-pulse/pulse-server.c | 25 +++++++++----------
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/spa/include/spa/utils/defs.h b/spa/include/spa/utils/defs.h
index f37216e73..369dd22a9 100644
--- a/spa/include/spa/utils/defs.h
+++ b/spa/include/spa/utils/defs.h
@@ -228,6 +228,9 @@ struct spa_fraction {
#define SPA_RESTRICT
#endif
+#define SPA_ROUND_DOWN(num,value) ((num) - ((num) % (value)))
+#define SPA_ROUND_UP(num,value) ((((num) + (value) - 1) / (value)) * (value))
+
#define SPA_ROUND_DOWN_N(num,align) ((num) & ~((align) - 1))
#define SPA_ROUND_UP_N(num,align) SPA_ROUND_DOWN_N((num) + ((align) - 1),align)
diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c
index eedb23901..8f6bc1850 100644
--- a/src/modules/module-protocol-pulse/pulse-server.c
+++ b/src/modules/module-protocol-pulse/pulse-server.c
@@ -374,15 +374,14 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
if (attr->maxlength == (uint32_t) -1 || attr->maxlength > MAXLENGTH)
attr->maxlength = MAXLENGTH;
- attr->maxlength -= attr->maxlength % frame_size;
- attr->maxlength = SPA_MAX(attr->maxlength, frame_size);
+ attr->maxlength = SPA_ROUND_UP(attr->maxlength, frame_size);
+
+ minreq = SPA_MIN(minreq, attr->maxlength);
if (attr->tlength == (uint32_t) -1)
attr->tlength = frac_to_bytes_round_up(s->default_tlength, &s->ss);
- if (attr->tlength > attr->maxlength)
- attr->tlength = attr->maxlength;
- attr->tlength -= attr->tlength % frame_size;
- attr->tlength = SPA_MAX(attr->tlength, frame_size);
+ attr->tlength = SPA_MIN(attr->tlength, attr->maxlength);
+ attr->tlength = SPA_ROUND_UP(attr->tlength, frame_size);
attr->tlength = SPA_MAX(attr->tlength, minreq);
if (attr->minreq == (uint32_t) -1) {
@@ -390,13 +389,13 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
/* With low-latency, tlength/4 gives a decent default in all of traditional,
* adjust latency and early request modes. */
uint32_t m = attr->tlength / 4;
- m -= m % frame_size;
+ m = SPA_ROUND_DOWN(m, frame_size);
attr->minreq = SPA_MIN(process, m);
}
attr->minreq = SPA_MAX(attr->minreq, minreq);
if (attr->tlength < attr->minreq+frame_size)
- attr->tlength = attr->minreq + frame_size;
+ attr->tlength = SPA_MIN(attr->minreq + frame_size, attr->maxlength);
if (s->early_requests) {
latency = attr->minreq;
@@ -406,7 +405,7 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
else
latency = attr->minreq;
- latency -= latency % frame_size;
+ latency = SPA_ROUND_DOWN(latency, frame_size);
if (attr->tlength >= latency)
attr->tlength -= latency;
@@ -418,20 +417,20 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
}
if (attr->tlength < latency + 2 * attr->minreq)
- attr->tlength = latency + 2 * attr->minreq;
+ attr->tlength = SPA_MIN(latency + 2 * attr->minreq, attr->maxlength);
- attr->minreq -= attr->minreq % frame_size;
+ attr->minreq = SPA_ROUND_DOWN(attr->minreq, frame_size);
if (attr->minreq <= 0) {
attr->minreq = frame_size;
attr->tlength += frame_size*2;
}
if (attr->tlength <= attr->minreq)
- attr->tlength = attr->minreq*2 + frame_size;
+ attr->tlength = SPA_MIN(attr->minreq*2 + frame_size, attr->maxlength);
max_prebuf = attr->tlength + frame_size - attr->minreq;
if (attr->prebuf == (uint32_t) -1 || attr->prebuf > max_prebuf)
attr->prebuf = max_prebuf;
- attr->prebuf -= attr->prebuf % frame_size;
+ attr->prebuf = SPA_ROUND_DOWN(attr->prebuf, frame_size);
attr->fragsize = 0;
--
2.34.1