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
This commit is contained in:
Wim Taymans 2026-04-27 17:38:05 +02:00
parent 3e67b89a1a
commit 30a77456fc

View file

@ -142,6 +142,8 @@ struct module_roc_source_data {
int local_control_port; int local_control_port;
roc_log_level loglevel; roc_log_level loglevel;
bool receiving;
}; };
static void stream_destroy(void *d) static void stream_destroy(void *d)
@ -205,6 +207,50 @@ static const struct pw_core_events core_events = {
.error = on_core_error, .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, static void on_stream_state_changed(void *d, enum pw_stream_state old,
enum pw_stream_state state, const char *error) enum pw_stream_state state, const char *error)
{ {
@ -218,6 +264,12 @@ static void on_stream_state_changed(void *d, enum pw_stream_state old,
case PW_STREAM_STATE_ERROR: case PW_STREAM_STATE_ERROR:
pw_log_error("stream error: %s", error); pw_log_error("stream error: %s", error);
break; break;
case PW_STREAM_STATE_STREAMING:
start_receiving(data);
break;
case PW_STREAM_STATE_PAUSED:
stop_receiving(data);
break;
default: default:
break; break;
} }
@ -356,11 +408,6 @@ static int roc_source_setup(struct module_roc_source_data *data)
return res; 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) { if (repair_proto != 0) {
res = pw_roc_create_endpoint(&data->local_repair_addr, repair_proto, data->local_ip, data->local_repair_port); res = pw_roc_create_endpoint(&data->local_repair_addr, repair_proto, data->local_ip, data->local_repair_port);
@ -369,11 +416,6 @@ static int roc_source_setup(struct module_roc_source_data *data)
return res; 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); res = pw_roc_create_endpoint(&data->local_control_addr, PW_ROC_DEFAULT_CONTROL_PROTO, data->local_ip, data->local_control_port);
@ -382,12 +424,6 @@ static int roc_source_setup(struct module_roc_source_data *data)
return res; 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, data->playback = pw_stream_new(data->core,
"roc-source playback", data->playback_props); "roc-source playback", data->playback_props);
data->playback_props = NULL; data->playback_props = NULL;