diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index dc1c0a9de..5de186b14 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -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) {