pulse-server: calculate missing bytes differently

Based on patch from Barnabás Pőcze <pobrn@protonmail.com>

Instead of trying to keep track of the missing bytes ourselves, use the
simple tlength - avail - requested formula to request more bytes from
the client.

Fixes #1981
This commit is contained in:
Wim Taymans 2022-01-10 12:05:29 +01:00
parent 7b1c5cd6dd
commit 982758ffed
4 changed files with 11 additions and 30 deletions

View file

@ -434,7 +434,6 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
attr->prebuf = max_prebuf; attr->prebuf = max_prebuf;
attr->prebuf -= attr->prebuf % frame_size; attr->prebuf -= attr->prebuf % frame_size;
s->missing = attr->tlength;
attr->fragsize = 0; attr->fragsize = 0;
pw_log_info("[%s] maxlength:%u tlength:%u minreq:%u/%u prebuf:%u latency:%u %u", pw_log_info("[%s] maxlength:%u tlength:%u minreq:%u/%u prebuf:%u latency:%u %u",
@ -1098,7 +1097,6 @@ struct process_data {
uint32_t write_inc; uint32_t write_inc;
uint32_t underrun_for; uint32_t underrun_for;
uint32_t playing_for; uint32_t playing_for;
uint32_t missing;
uint32_t minreq; uint32_t minreq;
uint32_t quantum; uint32_t quantum;
unsigned int underrun:1; unsigned int underrun:1;
@ -1142,8 +1140,6 @@ do_process_done(struct spa_loop *loop,
else else
stream_send_started(stream); stream_send_started(stream);
} }
stream->missing += pd->missing;
stream->missing = SPA_MIN(stream->missing, (int64_t)stream->attr.tlength);
stream->playing_for += pd->playing_for; stream->playing_for += pd->playing_for;
if (stream->underrun_for != (uint64_t)-1) if (stream->underrun_for != (uint64_t)-1)
stream->underrun_for += pd->underrun_for; stream->underrun_for += pd->underrun_for;
@ -1254,7 +1250,6 @@ static void stream_process(void *data)
pd.underrun = true; pd.underrun = true;
} }
if ((stream->attr.prebuf == 0 || do_flush) && !stream->corked) { if ((stream->attr.prebuf == 0 || do_flush) && !stream->corked) {
pd.missing = size;
pd.playing_for = size; pd.playing_for = size;
if (avail > 0) { if (avail > 0) {
spa_ringbuffer_read_data(&stream->ring, spa_ringbuffer_read_data(&stream->ring,
@ -1293,7 +1288,6 @@ static void stream_process(void *data)
spa_ringbuffer_read_update(&stream->ring, index); spa_ringbuffer_read_update(&stream->ring, index);
pd.playing_for = size; pd.playing_for = size;
pd.missing = size;
pd.underrun = false; pd.underrun = false;
} }
buf->datas[0].chunk->offset = 0; buf->datas[0].chunk->offset = 0;

View file

@ -167,7 +167,6 @@ static int handle_memblock(struct client *client, struct message *msg)
index += diff; index += diff;
filled += diff; filled += diff;
stream->write_index += diff; stream->write_index += diff;
stream->missing -= diff;
if (filled < 0) { if (filled < 0) {
/* underrun, reported on reader side */ /* underrun, reported on reader side */
@ -188,13 +187,7 @@ static int handle_memblock(struct client *client, struct message *msg)
spa_ringbuffer_write_update(&stream->ring, index); spa_ringbuffer_write_update(&stream->ring, index);
stream->requested -= SPA_MIN(msg->length, stream->requested); stream->requested -= SPA_MIN(msg->length, stream->requested);
if (diff < 0) { stream_send_request(stream);
/* when we seek backwards, ask for the additional missing data
* immediately so that we don't underrun in the next process */
pw_log_info("client %p [%s]: backwards seek of: %" PRIi64,
client, client->name, diff);
stream_send_request(stream);
}
finish: finish:
message_free(impl, msg, false, false); message_free(impl, msg, false, false);

View file

@ -136,9 +136,6 @@ void stream_flush(struct stream *stream)
stream->ring.writeindex = stream->ring.readindex; stream->ring.writeindex = stream->ring.readindex;
stream->write_index = stream->read_index; stream->write_index = stream->read_index;
stream->missing = stream->attr.tlength -
SPA_MIN(stream->requested, stream->attr.tlength);
if (stream->attr.prebuf > 0) if (stream->attr.prebuf > 0)
stream->in_prebuf = true; stream->in_prebuf = true;
@ -153,13 +150,8 @@ void stream_flush(struct stream *stream)
} }
} }
static bool stream_prebuf_active(struct stream *stream) static bool stream_prebuf_active(struct stream *stream, int32_t avail)
{ {
uint32_t index;
int32_t avail;
avail = spa_ringbuffer_get_write_index(&stream->ring, &index);
if (stream->in_prebuf) { if (stream->in_prebuf) {
if (avail >= (int32_t) stream->attr.prebuf) if (avail >= (int32_t) stream->attr.prebuf)
stream->in_prebuf = false; stream->in_prebuf = false;
@ -172,17 +164,21 @@ static bool stream_prebuf_active(struct stream *stream)
uint32_t stream_pop_missing(struct stream *stream) uint32_t stream_pop_missing(struct stream *stream)
{ {
uint32_t missing; int64_t missing, avail;
if (stream->missing <= 0) avail = stream->write_index - stream->read_index;
missing = stream->attr.tlength;
missing -= stream->requested;
missing -= avail;
if (missing <= 0)
return 0; return 0;
if (stream->missing < stream->attr.minreq && !stream_prebuf_active(stream)) if (missing < stream->attr.minreq && !stream_prebuf_active(stream, avail))
return 0; return 0;
missing = stream->missing;
stream->requested += missing; stream->requested += missing;
stream->missing = 0;
return missing; return missing;
} }
@ -314,7 +310,6 @@ int stream_update_minreq(struct stream *stream, uint32_t minreq)
if (new_tlength <= old_tlength) if (new_tlength <= old_tlength)
return 0; return 0;
stream->missing += new_tlength - old_tlength;
stream->attr.tlength = new_tlength; stream->attr.tlength = new_tlength;
if (client->version >= 15) { if (client->version >= 15) {

View file

@ -83,7 +83,6 @@ struct stream {
int64_t delay; int64_t delay;
uint32_t last_quantum; uint32_t last_quantum;
int64_t missing;
int64_t requested; int64_t requested;
struct sample_spec ss; struct sample_spec ss;