mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	alsa: improve target delay in ALSA
Don't just limit the max delay of samples we keep in the ALSA ringbuffer to the buffer_size but to half of it. Make this into a max_delay variable. If we have a buffer size of 8192 samples and a headroom of 8192 samples, when capturing, we would wait for the ringbuffer to contain at least 8192 samples, which would always xrun. When we limit the size to half, we can still read the data without xruns. Fixes #2972
This commit is contained in:
		
							parent
							
								
									8030a9f360
								
							
						
					
					
						commit
						a7322d5043
					
				
					 2 changed files with 4 additions and 2 deletions
				
			
		| 
						 | 
					@ -1597,6 +1597,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
 | 
				
			||||||
	if (is_batch)
 | 
						if (is_batch)
 | 
				
			||||||
		state->headroom += period_size;
 | 
							state->headroom += period_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						state->max_delay = state->buffer_frames / 2;
 | 
				
			||||||
	if (spa_strstartswith(state->props.device, "a52") ||
 | 
						if (spa_strstartswith(state->props.device, "a52") ||
 | 
				
			||||||
	    spa_strstartswith(state->props.device, "dca"))
 | 
						    spa_strstartswith(state->props.device, "dca"))
 | 
				
			||||||
		state->min_delay = SPA_MIN(2048u, state->buffer_frames);
 | 
							state->min_delay = SPA_MIN(2048u, state->buffer_frames);
 | 
				
			||||||
| 
						 | 
					@ -1608,7 +1609,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	state->latency[state->port_direction].min_rate =
 | 
						state->latency[state->port_direction].min_rate =
 | 
				
			||||||
		state->latency[state->port_direction].max_rate =
 | 
							state->latency[state->port_direction].max_rate =
 | 
				
			||||||
			SPA_MAX(state->min_delay, state->headroom);
 | 
								SPA_MAX(state->min_delay, SPA_MIN(state->max_delay, state->headroom));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_info(state->log, "%s (%s): format:%s access:%s-%s rate:%d channels:%d "
 | 
						spa_log_info(state->log, "%s (%s): format:%s access:%s-%s rate:%d channels:%d "
 | 
				
			||||||
			"buffer frames %lu, period frames %lu, periods %u, frame_size %zd "
 | 
								"buffer frames %lu, period frames %lu, periods %u, frame_size %zd "
 | 
				
			||||||
| 
						 | 
					@ -1882,7 +1883,7 @@ static int get_status(struct state *state, uint64_t current_time,
 | 
				
			||||||
		if (state->matching)
 | 
							if (state->matching)
 | 
				
			||||||
			*target += 32;
 | 
								*target += 32;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*target = SPA_CLAMP(*target, state->min_delay, state->buffer_frames);
 | 
						*target = SPA_CLAMP(*target, state->min_delay, state->max_delay);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,6 +178,7 @@ struct state {
 | 
				
			||||||
	uint32_t headroom;
 | 
						uint32_t headroom;
 | 
				
			||||||
	uint32_t start_delay;
 | 
						uint32_t start_delay;
 | 
				
			||||||
	uint32_t min_delay;
 | 
						uint32_t min_delay;
 | 
				
			||||||
 | 
						uint32_t max_delay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t duration;
 | 
						uint32_t duration;
 | 
				
			||||||
	unsigned int alsa_started:1;
 | 
						unsigned int alsa_started:1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue