From e10305851dca97b938bc9291311c095a60dc7cd0 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 1 Sep 2022 12:56:21 +0200 Subject: [PATCH] pulse-server: send chunks with half the fragsize PulseAudio configures half of the fragsize as the source latency. It also sends chunks as soon as they become available. This means that we also need to configure the source with half of the fragsize latency and send in chunks of fragsize/2. Keep this in the unused (for record) minreq field. --- .../module-protocol-pulse/pulse-server.c | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index e8dc1960d..e93f5829f 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -668,14 +668,20 @@ static uint32_t fix_record_buffer_attr(struct stream *s, struct buffer_attr *att attr->fragsize = SPA_ROUND_UP(attr->fragsize, frame_size); attr->fragsize = SPA_MAX(attr->fragsize, minfrag); - attr->tlength = attr->minreq = attr->prebuf = 0; + /* pulseaudio configures the source to half of the fragsize. It also + * immediately sends chunks to clients. We use the minreq field to + * keep this info and use it to configure half the fragsize latency */ + attr->minreq = attr->fragsize / 2; + attr->minreq = SPA_ROUND_UP(attr->minreq, frame_size); + + attr->tlength = attr->prebuf = 0; if (s->early_requests) { - latency = attr->fragsize; + latency = attr->minreq; } else if (s->adjust_latency) { - latency = attr->fragsize; + latency = attr->minreq; } else { - latency = attr->fragsize; + latency = attr->minreq; } /* make sure can queue at least to fragsize without overruns */ if (attr->maxlength < attr->fragsize * 4) @@ -1324,18 +1330,18 @@ do_process_done(struct spa_loop *loop, stream, client->name, index, avail); } else { if ((uint32_t)avail > stream->attr.maxlength) { - uint32_t skip = avail - stream->attr.fragsize; + uint32_t skip = avail - stream->attr.minreq; /* overrun, catch up to latest fragment and send it */ pw_log_warn("%p: [%s] overrun recover read:%u avail:%d max:%u skip:%u", stream, client->name, index, avail, stream->attr.maxlength, skip); index += skip; stream->read_index += skip; - avail = stream->attr.fragsize; + avail = stream->attr.minreq; } pw_log_trace("avail:%d index:%u", avail, index); - while ((uint32_t)avail >= stream->attr.fragsize) { - towrite = SPA_MIN((uint32_t)avail, stream->attr.fragsize); + while ((uint32_t)avail >= stream->attr.minreq) { + towrite = SPA_MIN((uint32_t)avail, stream->attr.minreq); msg = message_alloc(impl, stream->channel, towrite); if (msg == NULL)