mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	module-raop: add ProcessLatency support
Intercept the Output Latency paran and parse it for later. Use the computed latency as the ProcessLatency and expose this as the ProcessLatency param and the updated Input latency. Accept updates to ProcessLatency to modify the latency, which then also updates the Input Latency param. See #4270
This commit is contained in:
		
							parent
							
								
									e15244b1e1
								
							
						
					
					
						commit
						f7110fbc77
					
				
					 1 changed files with 58 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -269,6 +269,9 @@ struct impl {
 | 
			
		|||
	bool mute;
 | 
			
		||||
	float volume;
 | 
			
		||||
 | 
			
		||||
	struct spa_latency_info latency_info;
 | 
			
		||||
	struct spa_process_latency_info process_latency;
 | 
			
		||||
 | 
			
		||||
	struct spa_ringbuffer ring;
 | 
			
		||||
	uint8_t buffer[BUFFER_SIZE];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -856,15 +859,29 @@ static uint32_t msec_to_samples(struct impl *impl, uint32_t msec)
 | 
			
		|||
	return (uint64_t) msec * impl->rate / 1000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void update_latency(struct impl *impl)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t n_params = 0;
 | 
			
		||||
	const struct spa_pod *params[3];
 | 
			
		||||
	uint8_t buffer[1024];
 | 
			
		||||
	struct spa_pod_builder b;
 | 
			
		||||
	struct spa_latency_info latency;
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_init(&b, buffer, sizeof(buffer));
 | 
			
		||||
 | 
			
		||||
	latency = SPA_LATENCY_INFO(PW_DIRECTION_INPUT);
 | 
			
		||||
 | 
			
		||||
	spa_process_latency_info_add(&impl->process_latency, &latency);
 | 
			
		||||
	params[n_params++] = spa_latency_build(&b, SPA_PARAM_Latency, &latency);
 | 
			
		||||
	params[n_params++] = spa_latency_build(&b, SPA_PARAM_Latency, &impl->latency_info);
 | 
			
		||||
	params[n_params++] = spa_process_latency_build(&b, SPA_PARAM_ProcessLatency, &impl->process_latency);
 | 
			
		||||
	rtp_stream_update_params(impl->stream, params, n_params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int rtsp_record_reply(void *data, int status, const struct spa_dict *headers, const struct pw_array *content)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *impl = data;
 | 
			
		||||
	const char *str;
 | 
			
		||||
	uint32_t n_params;
 | 
			
		||||
	const struct spa_pod *params[2];
 | 
			
		||||
	uint8_t buffer[1024];
 | 
			
		||||
	struct spa_pod_builder b;
 | 
			
		||||
	struct spa_latency_info latency;
 | 
			
		||||
	char progress[128];
 | 
			
		||||
	struct timespec timeout, interval;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -891,16 +908,9 @@ static int rtsp_record_reply(void *data, int status, const struct spa_dict *head
 | 
			
		|||
		if (spa_atou32(str, &l, 0))
 | 
			
		||||
			impl->latency = SPA_MAX(l, impl->latency);
 | 
			
		||||
	}
 | 
			
		||||
	impl->process_latency.rate = impl->latency + msec_to_samples(impl, RAOP_LATENCY_MS);
 | 
			
		||||
 | 
			
		||||
	spa_zero(latency);
 | 
			
		||||
	latency.direction = PW_DIRECTION_INPUT;
 | 
			
		||||
	latency.min_rate = latency.max_rate = impl->latency + msec_to_samples(impl, RAOP_LATENCY_MS);
 | 
			
		||||
 | 
			
		||||
	n_params = 0;
 | 
			
		||||
	spa_pod_builder_init(&b, buffer, sizeof(buffer));
 | 
			
		||||
	params[n_params++] = spa_latency_build(&b, SPA_PARAM_Latency, &latency);
 | 
			
		||||
 | 
			
		||||
	rtp_stream_update_params(impl->stream, params, n_params);
 | 
			
		||||
	update_latency(impl);
 | 
			
		||||
 | 
			
		||||
	rtp_stream_set_first(impl->stream);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1662,6 +1672,32 @@ static void stream_props_changed(struct impl *impl, uint32_t id, const struct sp
 | 
			
		|||
	rtp_stream_set_param(impl->stream, id, param);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void param_latency_changed(struct impl *impl, const struct spa_pod *param)
 | 
			
		||||
{
 | 
			
		||||
	struct spa_latency_info latency;
 | 
			
		||||
 | 
			
		||||
	if (param == NULL || spa_latency_parse(param, &latency) < 0)
 | 
			
		||||
		return;
 | 
			
		||||
	if (latency.direction == SPA_DIRECTION_OUTPUT)
 | 
			
		||||
		impl->latency_info = latency;
 | 
			
		||||
 | 
			
		||||
	update_latency(impl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void param_process_latency_changed(struct impl *impl, const struct spa_pod *param)
 | 
			
		||||
{
 | 
			
		||||
	struct spa_process_latency_info info;
 | 
			
		||||
 | 
			
		||||
	if (param == NULL)
 | 
			
		||||
		spa_zero(info);
 | 
			
		||||
	else if (spa_process_latency_parse(param, &info) < 0)
 | 
			
		||||
		return;
 | 
			
		||||
	if (spa_process_latency_info_compare(&impl->process_latency, &info) == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	impl->process_latency = info;
 | 
			
		||||
	update_latency(impl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stream_param_changed(void *data, uint32_t id, const struct spa_pod *param)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *impl = data;
 | 
			
		||||
| 
						 | 
				
			
			@ -1677,6 +1713,12 @@ static void stream_param_changed(void *data, uint32_t id, const struct spa_pod *
 | 
			
		|||
		if (param != NULL)
 | 
			
		||||
			stream_props_changed(impl, id, param);
 | 
			
		||||
		break;
 | 
			
		||||
	case SPA_PARAM_Latency:
 | 
			
		||||
		param_latency_changed(impl, param);
 | 
			
		||||
		break;
 | 
			
		||||
	case SPA_PARAM_ProcessLatency:
 | 
			
		||||
		param_process_latency_changed(impl, param);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1806,6 +1848,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
 | 
			
		|||
	impl->context = context;
 | 
			
		||||
	impl->loop = pw_context_get_main_loop(context);
 | 
			
		||||
 | 
			
		||||
	impl->latency_info = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
 | 
			
		||||
 | 
			
		||||
	ip = pw_properties_get(props, "raop.ip");
 | 
			
		||||
	port = pw_properties_get(props, "raop.port");
 | 
			
		||||
	if (ip == NULL || port == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue