mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	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:
		
							parent
							
								
									7b1c5cd6dd
								
							
						
					
					
						commit
						982758ffed
					
				
					 4 changed files with 11 additions and 30 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
					 | 
				
			||||||
		/* 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);
 | 
						stream_send_request(stream);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
finish:
 | 
					finish:
 | 
				
			||||||
	message_free(impl, msg, false, false);
 | 
						message_free(impl, msg, false, false);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue