From b7aae374bf50e45ea3af39f19eb87f8ef03a9a5e Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 30 Apr 2026 15:18:56 +0200 Subject: [PATCH] pulse-server: keep allocate buffer size around For playback and capture streams we allocate MAXLENGTH (4M) buffers but for upload streams we must allow space for the total upload stream, which can be up to the max allowed sample size (16M). Keep the allocated size for the stream around in a variable so that we can use it when writing/reading to/from the ringbuffer. This could later also be extended to use the attr.maxlength variable to size the buffer (but it's usually 4M anyway). This is more complicated because we need to grow the buffer size when new attributes are set, which is probably more complicated than useful. --- .../module-protocol-pulse/pulse-server.c | 27 ++++++++++--------- .../module-protocol-pulse/sample-play.c | 3 +-- src/modules/module-protocol-pulse/server.c | 10 +++---- src/modules/module-protocol-pulse/stream.c | 3 +-- src/modules/module-protocol-pulse/stream.h | 1 + 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index eea6693c3..38493f9bd 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -572,7 +572,8 @@ static int reply_create_playback_stream(struct stream *stream, struct pw_manager const char *peer_name; uint64_t lat_usec; - stream->buffer = calloc(1, MAXLENGTH); + stream->bufsize = MAXLENGTH; + stream->buffer = calloc(1, stream->bufsize); if (stream->buffer == NULL) return -errno; @@ -731,7 +732,8 @@ static int reply_create_record_stream(struct stream *stream, struct pw_manager_o uint32_t peer_index; uint64_t lat_usec; - stream->buffer = calloc(1, MAXLENGTH); + stream->bufsize = MAXLENGTH; + stream->buffer = calloc(1, stream->bufsize); if (stream->buffer == NULL) return -errno; @@ -1399,8 +1401,8 @@ do_process_done(struct spa_loop *loop, return -errno; spa_ringbuffer_read_data(&stream->ring, - stream->buffer, MAXLENGTH, - index % MAXLENGTH, + stream->buffer, stream->bufsize, + index % stream->bufsize, msg->data, towrite); client_queue_message(client, msg); @@ -1472,8 +1474,8 @@ static void stream_process(void *data) if (avail > 0) { avail = SPA_MIN((uint32_t)avail, size); spa_ringbuffer_read_data(&stream->ring, - stream->buffer, MAXLENGTH, - index % MAXLENGTH, + stream->buffer, stream->bufsize, + index % stream->bufsize, p, avail); empty = false; } @@ -1502,8 +1504,8 @@ static void stream_process(void *data) size = SPA_MIN(size, minreq); spa_ringbuffer_read_data(&stream->ring, - stream->buffer, MAXLENGTH, - index % MAXLENGTH, + stream->buffer, stream->bufsize, + index % stream->bufsize, p, size); index += size; @@ -1539,10 +1541,10 @@ static void stream_process(void *data) } spa_ringbuffer_write_data(&stream->ring, - stream->buffer, MAXLENGTH, - index % MAXLENGTH, + stream->buffer, stream->bufsize, + index % stream->bufsize, SPA_PTROFF(p, offs, void), - SPA_MIN(size, MAXLENGTH)); + SPA_MIN(size, stream->bufsize)); index += size; pd.write_inc = size; @@ -2361,7 +2363,8 @@ static int do_create_upload_stream(struct client *client, uint32_t command, uint stream->props = props; - stream->buffer = calloc(1, MAXLENGTH); + stream->bufsize = stream->attr.maxlength; + stream->buffer = calloc(1, stream->bufsize); if (stream->buffer == NULL) goto error_errno; diff --git a/src/modules/module-protocol-pulse/sample-play.c b/src/modules/module-protocol-pulse/sample-play.c index 719604654..09b0e75cc 100644 --- a/src/modules/module-protocol-pulse/sample-play.c +++ b/src/modules/module-protocol-pulse/sample-play.c @@ -100,8 +100,7 @@ static void sample_play_stream_process(void *data) if (b->requested) size = SPA_MIN(size, b->requested * p->stride); - spa_ringbuffer_read_data(NULL, s->buffer, MAXLENGTH, - p->offset % MAXLENGTH, d, size); + memcpy(d, s->buffer + p->offset, size); p->offset += size; diff --git a/src/modules/module-protocol-pulse/server.c b/src/modules/module-protocol-pulse/server.c index 45b62d0ca..7038c95fc 100644 --- a/src/modules/module-protocol-pulse/server.c +++ b/src/modules/module-protocol-pulse/server.c @@ -103,7 +103,7 @@ finish: static void stream_clear_data(struct stream *stream, uint32_t offset, uint32_t len) { - uint32_t l0 = SPA_MIN(len, MAXLENGTH - offset), l1 = len - l0; + uint32_t l0 = SPA_MIN(len, stream->bufsize - offset), l1 = len - l0; sample_spec_silence(&stream->ss, SPA_PTROFF(stream->buffer, offset, void), l0); if (SPA_UNLIKELY(l1 > 0)) sample_spec_silence(&stream->ss, stream->buffer, l1); @@ -162,7 +162,7 @@ static int handle_memblock(struct client *client, struct message *msg) * play back old data. FIXME, if the write pointer goes backwards and * forwards, this might clear valid data. We should probably keep track of * the highest write pointer and only clear when we go past that one. */ - stream_clear_data(stream, index % MAXLENGTH, SPA_MIN(diff, MAXLENGTH)); + stream_clear_data(stream, index % stream->bufsize, SPA_MIN(diff, stream->bufsize)); } index += diff; @@ -181,10 +181,10 @@ static int handle_memblock(struct client *client, struct message *msg) /* always write data to ringbuffer, we expect the other side * to recover */ spa_ringbuffer_write_data(&stream->ring, - stream->buffer, MAXLENGTH, - index % MAXLENGTH, + stream->buffer, stream->bufsize, + index % stream->bufsize, msg->data, - SPA_MIN(msg->length, MAXLENGTH)); + SPA_MIN(msg->length, stream->bufsize)); index += msg->length; spa_ringbuffer_write_update(&stream->ring, index); diff --git a/src/modules/module-protocol-pulse/stream.c b/src/modules/module-protocol-pulse/stream.c index 0c4d55855..80253dfe7 100644 --- a/src/modules/module-protocol-pulse/stream.c +++ b/src/modules/module-protocol-pulse/stream.c @@ -163,8 +163,7 @@ void stream_free(struct stream *stream) pw_work_queue_cancel(impl->work_queue, stream, SPA_ID_INVALID); - if (stream->buffer) - free(stream->buffer); + free(stream->buffer); pw_properties_free(stream->props); diff --git a/src/modules/module-protocol-pulse/stream.h b/src/modules/module-protocol-pulse/stream.h index 022f0ee74..8dad93369 100644 --- a/src/modules/module-protocol-pulse/stream.h +++ b/src/modules/module-protocol-pulse/stream.h @@ -55,6 +55,7 @@ struct stream { struct spa_io_position *position; struct spa_ringbuffer ring; void *buffer; + uint32_t bufsize; int64_t read_index; int64_t write_index;