mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	pulse: tweak buffer attributes some more
Seems to work well with vlc and firefox other apps now. paplay without ADJUST_LATENCY reports wrong latency still.
This commit is contained in:
		
							parent
							
								
									d2d722efb3
								
							
						
					
					
						commit
						a79d1fc866
					
				
					 1 changed files with 39 additions and 20 deletions
				
			
		| 
						 | 
					@ -33,7 +33,7 @@
 | 
				
			||||||
#include "core-format.h"
 | 
					#include "core-format.h"
 | 
				
			||||||
#include "internal.h"
 | 
					#include "internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MIN_SAMPLES     8u
 | 
					#define MIN_SAMPLES     24u
 | 
				
			||||||
#define MIN_BUFFERS     8u
 | 
					#define MIN_BUFFERS     8u
 | 
				
			||||||
#define MAX_BUFFERS     64u
 | 
					#define MAX_BUFFERS     64u
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,11 +144,11 @@ static const struct spa_pod *get_buffers_param(pa_stream *s, pa_buffer_attr *att
 | 
				
			||||||
	blocks = 1;
 | 
						blocks = 1;
 | 
				
			||||||
	stride = pa_frame_size(&s->sample_spec);
 | 
						stride = pa_frame_size(&s->sample_spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	maxsize = attr->tlength * MAX_BUFFERS;
 | 
						maxsize = attr->tlength;
 | 
				
			||||||
	size = attr->tlength;
 | 
						size = attr->minreq;
 | 
				
			||||||
	buffers = SPA_CLAMP(maxsize / size, MIN_BUFFERS, MAX_BUFFERS);
 | 
						buffers = SPA_CLAMP(maxsize / size, MIN_BUFFERS, MAX_BUFFERS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug("stream %p: stride %d maxsize %d size %u buffers %d", s, stride, maxsize,
 | 
						pw_log_info("stream %p: stride %d maxsize %d size %u buffers %d", s, stride, maxsize,
 | 
				
			||||||
			size, buffers);
 | 
								size, buffers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	param = spa_pod_builder_add_object(b,
 | 
						param = spa_pod_builder_add_object(b,
 | 
				
			||||||
| 
						 | 
					@ -222,19 +222,15 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
 | 
				
			||||||
		attr->tlength = (uint32_t) pa_usec_to_bytes(2*PA_USEC_PER_SEC, &s->sample_spec);
 | 
							attr->tlength = (uint32_t) pa_usec_to_bytes(2*PA_USEC_PER_SEC, &s->sample_spec);
 | 
				
			||||||
	attr->tlength = SPA_MIN(attr->tlength, attr->maxlength);
 | 
						attr->tlength = SPA_MIN(attr->tlength, attr->maxlength);
 | 
				
			||||||
	attr->tlength -= attr->tlength % stride;
 | 
						attr->tlength -= attr->tlength % stride;
 | 
				
			||||||
	attr->tlength = SPA_MAX(attr->tlength, MIN_SAMPLES * stride * MIN_BUFFERS);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (attr->minreq == (uint32_t) -1)
 | 
						if (attr->minreq == (uint32_t) -1)
 | 
				
			||||||
		attr->minreq = pa_usec_to_bytes(25*PA_USEC_PER_MSEC, &s->sample_spec);
 | 
							attr->minreq = pa_usec_to_bytes(20*PA_USEC_PER_MSEC, &s->sample_spec);
 | 
				
			||||||
	attr->minreq = SPA_MIN(attr->minreq, attr->tlength / MIN_BUFFERS);
 | 
						attr->minreq = SPA_MIN(attr->minreq, attr->tlength / 4);
 | 
				
			||||||
 | 
						attr->minreq = SPA_MAX(attr->minreq, MIN_SAMPLES * stride);
 | 
				
			||||||
	attr->minreq -= attr->minreq % stride;
 | 
						attr->minreq -= attr->minreq % stride;
 | 
				
			||||||
	attr->minreq = SPA_MAX(attr->minreq, stride);
 | 
						attr->minreq = SPA_MAX(attr->minreq, stride);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (attr->fragsize == (uint32_t) -1)
 | 
						attr->tlength = SPA_MAX(attr->tlength, attr->minreq * 4);
 | 
				
			||||||
		attr->fragsize = pa_usec_to_bytes(25*PA_USEC_PER_MSEC, &s->sample_spec);
 | 
					 | 
				
			||||||
	attr->fragsize = SPA_MIN(attr->fragsize, attr->tlength / MIN_BUFFERS);
 | 
					 | 
				
			||||||
	attr->fragsize -= attr->fragsize % stride;
 | 
					 | 
				
			||||||
	attr->fragsize = SPA_MAX(attr->fragsize, stride);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (attr->prebuf == (uint32_t) -1)
 | 
						if (attr->prebuf == (uint32_t) -1)
 | 
				
			||||||
		attr->prebuf = attr->tlength - attr->minreq;
 | 
							attr->prebuf = attr->tlength - attr->minreq;
 | 
				
			||||||
| 
						 | 
					@ -242,6 +238,13 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
 | 
				
			||||||
	attr->prebuf -= attr->prebuf % stride;
 | 
						attr->prebuf -= attr->prebuf % stride;
 | 
				
			||||||
	attr->prebuf = SPA_MAX(attr->prebuf, stride);
 | 
						attr->prebuf = SPA_MAX(attr->prebuf, stride);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (attr->fragsize == (uint32_t) -1)
 | 
				
			||||||
 | 
							attr->fragsize = pa_usec_to_bytes(20*PA_USEC_PER_MSEC, &s->sample_spec);
 | 
				
			||||||
 | 
						attr->fragsize = SPA_MIN(attr->fragsize, attr->tlength / 4);
 | 
				
			||||||
 | 
						attr->fragsize -= attr->fragsize % stride;
 | 
				
			||||||
 | 
						attr->fragsize = SPA_MAX(attr->fragsize, MIN_SAMPLES * stride);
 | 
				
			||||||
 | 
						attr->fragsize = SPA_MAX(attr->fragsize, stride);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dump_buffer_attr(s, attr);
 | 
						dump_buffer_attr(s, attr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -451,6 +454,15 @@ static inline uint32_t queued_size(const pa_stream *s, uint64_t elapsed)
 | 
				
			||||||
	queued -= SPA_MIN(queued, elapsed);
 | 
						queued -= SPA_MIN(queued, elapsed);
 | 
				
			||||||
	return queued;
 | 
						return queued;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					static inline uint32_t target_queue(const pa_stream *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return s->buffer_attr.tlength;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t wanted_size(const pa_stream *s, uint32_t queued, uint32_t target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return target - SPA_MIN(queued, target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline uint32_t writable_size(const pa_stream *s, uint64_t queued)
 | 
					static inline uint32_t writable_size(const pa_stream *s, uint64_t queued)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -459,7 +471,7 @@ static inline uint32_t writable_size(const pa_stream *s, uint64_t queued)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline uint32_t required_size(const pa_stream *s)
 | 
					static inline uint32_t required_size(const pa_stream *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return s->buffer_attr.tlength;
 | 
						return s->buffer_attr.minreq;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void stream_process(void *data)
 | 
					static void stream_process(void *data)
 | 
				
			||||||
| 
						 | 
					@ -470,16 +482,22 @@ static void stream_process(void *data)
 | 
				
			||||||
	update_timing_info(s);
 | 
						update_timing_info(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (s->direction == PA_STREAM_PLAYBACK) {
 | 
						if (s->direction == PA_STREAM_PLAYBACK) {
 | 
				
			||||||
		uint64_t queued, writable, required;
 | 
							uint32_t queued, target, wanted, required;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		queue_output(s);
 | 
							queue_output(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		queued = queued_size(s, 0);
 | 
							queued = queued_size(s, 0);
 | 
				
			||||||
		writable = writable_size(s, queued);
 | 
							target = target_queue(s);
 | 
				
			||||||
 | 
							wanted = wanted_size(s, queued, target);
 | 
				
			||||||
		required = required_size(s);
 | 
							required = required_size(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (s->write_callback && s->state == PA_STREAM_READY && queued < required && writable >= required)
 | 
							pw_log_trace("stream %p, queued:%u target:%u wanted:%u required:%u",
 | 
				
			||||||
			s->write_callback(s, required, s->write_userdata);
 | 
									s, queued, target, wanted, required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (s->write_callback && s->state == PA_STREAM_READY &&
 | 
				
			||||||
 | 
									queued < wanted &&
 | 
				
			||||||
 | 
									wanted >= required)
 | 
				
			||||||
 | 
								s->write_callback(s, wanted, s->write_userdata);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		pull_input(s);
 | 
							pull_input(s);
 | 
				
			||||||
| 
						 | 
					@ -986,7 +1004,7 @@ static int create_stream(pa_stream_direction_t direction,
 | 
				
			||||||
	if (monitor)
 | 
						if (monitor)
 | 
				
			||||||
		sprintf(latency, "%u/%u", s->buffer_attr.fragsize / stride, s->sample_spec.rate);
 | 
							sprintf(latency, "%u/%u", s->buffer_attr.fragsize / stride, s->sample_spec.rate);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		sprintf(latency, "%u/%u", s->buffer_attr.tlength / 2 / stride, s->sample_spec.rate);
 | 
							sprintf(latency, "%u/%u", s->buffer_attr.minreq * 2 / stride, s->sample_spec.rate);
 | 
				
			||||||
	n_items = 0;
 | 
						n_items = 0;
 | 
				
			||||||
	items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
 | 
						items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
 | 
				
			||||||
	items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_TYPE, "Audio");
 | 
						items[n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_TYPE, "Audio");
 | 
				
			||||||
| 
						 | 
					@ -1293,8 +1311,9 @@ size_t pa_stream_writable_size(PA_CONST pa_stream *s)
 | 
				
			||||||
	writable = writable_size(s, queued);
 | 
						writable = writable_size(s, queued);
 | 
				
			||||||
	required = required_size(s);
 | 
						required = required_size(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug("stream %p: %"PRIu64" minreq:%u maxblock:%zu", s,
 | 
						pw_log_debug("stream %p: writable:%"PRIu64" queued:%"PRIu64" required:%"PRIu64, s,
 | 
				
			||||||
			writable, s->buffer_attr.minreq, s->maxblock);
 | 
								writable, queued, required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (writable < required)
 | 
						if (writable < required)
 | 
				
			||||||
		writable = 0;
 | 
							writable = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue