From c889edf172a9c573129d3e16652ec59c2bf2356f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 27 Apr 2026 17:38:05 +0200 Subject: [PATCH] roc-source: start/stop receiving in streaming/pause Only start receiving packets when we are streaming. Otherwise the ROC source will start receiving and queueing packets and consume a lot of memory while we don't read the packets from the queue. Likewise, stop receiving packets when we pause. Fixes #5250 --- src/modules/module-roc-source.c | 68 +++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/src/modules/module-roc-source.c b/src/modules/module-roc-source.c index a46189e5d..79a5bbc01 100644 --- a/src/modules/module-roc-source.c +++ b/src/modules/module-roc-source.c @@ -140,6 +140,8 @@ struct module_roc_source_data { roc_endpoint *local_control_addr; int local_control_port; + + bool receiving; }; static void stream_destroy(void *d) @@ -203,6 +205,50 @@ static const struct pw_core_events core_events = { .error = on_core_error, }; + +static int start_receiving(struct module_roc_source_data *data) +{ + if (data->receiver == NULL || data->receiving) + return 0; + + if (data->local_source_addr != NULL) { + if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_SOURCE, + data->local_source_addr) != 0) { + pw_log_error("can't connect roc receiver to local source address"); + return -EINVAL; + } + } + if (data->local_repair_addr != NULL) { + if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_REPAIR, + data->local_repair_addr) != 0) { + pw_log_error("can't connect roc receiver to local repair address"); + return -EINVAL; + } + } + if (data->local_control_addr != NULL) { + if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_CONTROL, + data->local_control_addr) != 0) { + pw_log_error("can't connect roc receiver to local control address"); + return -EINVAL; + } + } + data->receiving = true; + return 0; +} + +static int stop_receiving(struct module_roc_source_data *data) +{ + if (data->receiver == NULL || !data->receiving) + return 0; + + if (roc_receiver_unlink(data->receiver, ROC_SLOT_DEFAULT) != 0) + pw_log_warn("can't unlink roc receiver"); + + data->receiving = false; + + return 0; +} + static void on_stream_state_changed(void *d, enum pw_stream_state old, enum pw_stream_state state, const char *error) { @@ -216,6 +262,12 @@ static void on_stream_state_changed(void *d, enum pw_stream_state old, case PW_STREAM_STATE_ERROR: pw_log_error("stream error: %s", error); break; + case PW_STREAM_STATE_STREAMING: + start_receiving(data); + break; + case PW_STREAM_STATE_PAUSED: + stop_receiving(data); + break; default: break; } @@ -354,11 +406,6 @@ static int roc_source_setup(struct module_roc_source_data *data) return res; } - if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_SOURCE, - data->local_source_addr) != 0) { - pw_log_error("can't connect roc receiver to local source address"); - return -EINVAL; - } if (repair_proto != 0) { res = pw_roc_create_endpoint(&data->local_repair_addr, repair_proto, data->local_ip, data->local_repair_port); @@ -367,11 +414,6 @@ static int roc_source_setup(struct module_roc_source_data *data) return res; } - if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_REPAIR, - data->local_repair_addr) != 0) { - pw_log_error("can't connect roc receiver to local repair address"); - return -EINVAL; - } } res = pw_roc_create_endpoint(&data->local_control_addr, PW_ROC_DEFAULT_CONTROL_PROTO, data->local_ip, data->local_control_port); @@ -380,12 +422,6 @@ static int roc_source_setup(struct module_roc_source_data *data) return res; } - if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_CONTROL, - data->local_control_addr) != 0) { - pw_log_error("can't connect roc receiver to local control address"); - return -EINVAL; - } - data->playback = pw_stream_new(data->core, "roc-source playback", data->playback_props); data->playback_props = NULL;