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.
This commit is contained in:
Wim Taymans 2022-09-01 12:56:21 +02:00
parent 9123710971
commit e10305851d

View file

@ -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_ROUND_UP(attr->fragsize, frame_size);
attr->fragsize = SPA_MAX(attr->fragsize, minfrag); 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) { if (s->early_requests) {
latency = attr->fragsize; latency = attr->minreq;
} else if (s->adjust_latency) { } else if (s->adjust_latency) {
latency = attr->fragsize; latency = attr->minreq;
} else { } else {
latency = attr->fragsize; latency = attr->minreq;
} }
/* make sure can queue at least to fragsize without overruns */ /* make sure can queue at least to fragsize without overruns */
if (attr->maxlength < attr->fragsize * 4) if (attr->maxlength < attr->fragsize * 4)
@ -1324,18 +1330,18 @@ do_process_done(struct spa_loop *loop,
stream, client->name, index, avail); stream, client->name, index, avail);
} else { } else {
if ((uint32_t)avail > stream->attr.maxlength) { 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 */ /* overrun, catch up to latest fragment and send it */
pw_log_warn("%p: [%s] overrun recover read:%u avail:%d max:%u skip:%u", pw_log_warn("%p: [%s] overrun recover read:%u avail:%d max:%u skip:%u",
stream, client->name, index, avail, stream->attr.maxlength, skip); stream, client->name, index, avail, stream->attr.maxlength, skip);
index += skip; index += skip;
stream->read_index += skip; stream->read_index += skip;
avail = stream->attr.fragsize; avail = stream->attr.minreq;
} }
pw_log_trace("avail:%d index:%u", avail, index); pw_log_trace("avail:%d index:%u", avail, index);
while ((uint32_t)avail >= stream->attr.fragsize) { while ((uint32_t)avail >= stream->attr.minreq) {
towrite = SPA_MIN((uint32_t)avail, stream->attr.fragsize); towrite = SPA_MIN((uint32_t)avail, stream->attr.minreq);
msg = message_alloc(impl, stream->channel, towrite); msg = message_alloc(impl, stream->channel, towrite);
if (msg == NULL) if (msg == NULL)