mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	latency: fix latency combine calculations
0 is a valid min latency so we can't use it as an unset value. Use some large value instead and when nothing was configured, assume it is 0. Fixes #1839
This commit is contained in:
		
							parent
							
								
									401e56699d
								
							
						
					
					
						commit
						97cad7284a
					
				
					 4 changed files with 32 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -1926,11 +1926,14 @@ static void default_latency(struct client *c, enum spa_direction direction,
 | 
			
		|||
	enum spa_direction other;
 | 
			
		||||
	struct port *p;
 | 
			
		||||
 | 
			
		||||
	*latency = SPA_LATENCY_INFO(direction);
 | 
			
		||||
	other = SPA_DIRECTION_REVERSE(direction);
 | 
			
		||||
 | 
			
		||||
	spa_latency_info_combine_start(latency, direction);
 | 
			
		||||
 | 
			
		||||
	spa_list_for_each(p, &c->ports[other], link)
 | 
			
		||||
		spa_latency_info_combine(latency, &p->object->port.latency[direction]);
 | 
			
		||||
 | 
			
		||||
	spa_latency_info_combine_finish(latency);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* called from thread-loop */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,8 @@ extern "C" {
 | 
			
		|||
 * \{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <float.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/pod/builder.h>
 | 
			
		||||
#include <spa/pod/parser.h>
 | 
			
		||||
#include <spa/param/param.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -63,20 +65,39 @@ spa_latency_info_compare(const struct spa_latency_info *a, struct spa_latency_in
 | 
			
		|||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
spa_latency_info_combine_start(struct spa_latency_info *info, enum spa_direction direction)
 | 
			
		||||
{
 | 
			
		||||
	*info = SPA_LATENCY_INFO(direction,
 | 
			
		||||
			.min_quantum = FLT_MAX,
 | 
			
		||||
			.min_rate = UINT32_MAX,
 | 
			
		||||
			.min_ns = UINT64_MAX);
 | 
			
		||||
}
 | 
			
		||||
static inline void
 | 
			
		||||
spa_latency_info_combine_finish(struct spa_latency_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info->min_quantum == FLT_MAX)
 | 
			
		||||
		info->min_quantum = 0;
 | 
			
		||||
	if (info->min_rate == UINT32_MAX)
 | 
			
		||||
		info->min_rate = 0;
 | 
			
		||||
	if (info->min_ns == UINT64_MAX)
 | 
			
		||||
		info->min_ns = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
spa_latency_info_combine(struct spa_latency_info *info, const struct spa_latency_info *other)
 | 
			
		||||
{
 | 
			
		||||
	if (info->direction != other->direction)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	if (info->min_quantum == 0.0f || other->min_quantum < info->min_quantum)
 | 
			
		||||
	if (other->min_quantum < info->min_quantum)
 | 
			
		||||
		info->min_quantum = other->min_quantum;
 | 
			
		||||
	if (other->max_quantum > info->max_quantum)
 | 
			
		||||
		info->max_quantum = other->max_quantum;
 | 
			
		||||
	if (info->min_rate == 0U || other->min_rate < info->min_rate)
 | 
			
		||||
	if (other->min_rate < info->min_rate)
 | 
			
		||||
		info->min_rate = other->min_rate;
 | 
			
		||||
	if (other->max_rate > info->max_rate)
 | 
			
		||||
		info->max_rate = other->max_rate;
 | 
			
		||||
	if (info->min_ns == 0UL || other->min_ns < info->min_ns)
 | 
			
		||||
	if (other->min_ns < info->min_ns)
 | 
			
		||||
		info->min_ns = other->min_ns;
 | 
			
		||||
	if (other->max_ns > info->max_ns)
 | 
			
		||||
		info->max_ns = other->max_ns;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -769,13 +769,13 @@ static int default_latency(struct filter *impl, struct port *port, enum spa_dire
 | 
			
		|||
	struct spa_latency_info info;
 | 
			
		||||
	struct port *p;
 | 
			
		||||
 | 
			
		||||
	info = SPA_LATENCY_INFO(direction);
 | 
			
		||||
 | 
			
		||||
	spa_latency_info_combine_start(&info, direction);
 | 
			
		||||
	spa_list_for_each(p, &impl->port_list, link) {
 | 
			
		||||
		if (p->direction == direction)
 | 
			
		||||
			continue;
 | 
			
		||||
		spa_latency_info_combine(&info, &p->latency[direction]);
 | 
			
		||||
	}
 | 
			
		||||
	spa_latency_info_combine_finish(&info);
 | 
			
		||||
 | 
			
		||||
	spa_process_latency_info_add(&impl->process_latency, &info);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1318,7 +1318,7 @@ int pw_impl_port_recalc_latency(struct pw_impl_port *port)
 | 
			
		|||
	if (port->destroying)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	latency = SPA_LATENCY_INFO(SPA_DIRECTION_REVERSE(port->direction));
 | 
			
		||||
	spa_latency_info_combine_start(&latency, SPA_DIRECTION_REVERSE(port->direction));
 | 
			
		||||
 | 
			
		||||
	if (port->direction == PW_DIRECTION_OUTPUT) {
 | 
			
		||||
		spa_list_for_each(l, &port->links, output_link) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1341,6 +1341,7 @@ int pw_impl_port_recalc_latency(struct pw_impl_port *port)
 | 
			
		|||
					latency.min_ns, latency.max_ns);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	spa_latency_info_combine_finish(&latency);
 | 
			
		||||
 | 
			
		||||
	current = &port->latency[latency.direction];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue