roc: add fec_code option

Add fec_code option.
Fix resample.profile parsing.
This commit is contained in:
Wim Taymans 2022-04-25 16:20:55 +02:00
parent 1e244b4ebd
commit 09ea37cfdf
5 changed files with 152 additions and 78 deletions

View file

@ -116,6 +116,7 @@ static const struct spa_dict_item module_roc_sink_input_info[] = {
{ PW_KEY_MODULE_USAGE, "sink=<name for the sink> " { PW_KEY_MODULE_USAGE, "sink=<name for the sink> "
"sink_input_properties=<properties for the sink_input> " "sink_input_properties=<properties for the sink_input> "
"resampler_profile=<empty>|disable|high|medium|low " "resampler_profile=<empty>|disable|high|medium|low "
"fec_code=<empty>|disable|rs8m|ldpc "
"sess_latency_msec=<target network latency in milliseconds> " "sess_latency_msec=<target network latency in milliseconds> "
"local_ip=<local receiver ip> " "local_ip=<local receiver ip> "
"local_source_port=<local receiver port for source packets> " "local_source_port=<local receiver port for source packets> "
@ -178,6 +179,11 @@ struct module *create_module_roc_sink_input(struct impl *impl, const char *argum
pw_properties_set(props, "resampler_profile", NULL); pw_properties_set(props, "resampler_profile", NULL);
} }
if ((str = pw_properties_get(props, "fec_code")) != NULL) {
pw_properties_set(roc_props, "fec.code", str);
pw_properties_set(props, "fec_code", NULL);
}
module = module_new(impl, sizeof(*d)); module = module_new(impl, sizeof(*d));
if (module == NULL) { if (module == NULL) {
res = -errno; res = -errno;

View file

@ -35,10 +35,6 @@
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
#define PW_LOG_TOPIC_DEFAULT mod_topic #define PW_LOG_TOPIC_DEFAULT mod_topic
#define ROC_DEFAULT_IP "0.0.0.0"
#define ROC_DEFAULT_SOURCE_PORT "10001"
#define ROC_DEFAULT_REPAIR_PORT "10002"
struct module_roc_sink_data { struct module_roc_sink_data {
struct module *module; struct module *module;
@ -119,6 +115,7 @@ static const struct spa_dict_item module_roc_sink_info[] = {
{ PW_KEY_MODULE_DESCRIPTION, "roc sink" }, { PW_KEY_MODULE_DESCRIPTION, "roc sink" },
{ PW_KEY_MODULE_USAGE, "sink_name=<name for the sink> " { PW_KEY_MODULE_USAGE, "sink_name=<name for the sink> "
"sink_properties=<properties for the sink> " "sink_properties=<properties for the sink> "
"fec_code=<empty>|disable|rs8m|ldpc "
"local_ip=<local sender ip> " "local_ip=<local sender ip> "
"remote_ip=<remote receiver ip> " "remote_ip=<remote receiver ip> "
"remote_source_port=<remote receiver port for source packets> " "remote_source_port=<remote receiver port for source packets> "
@ -172,22 +169,20 @@ struct module *create_module_roc_sink(struct impl *impl, const char *argument)
if ((str = pw_properties_get(props, "local_ip")) != NULL) { if ((str = pw_properties_get(props, "local_ip")) != NULL) {
pw_properties_set(roc_props, "local.ip", str); pw_properties_set(roc_props, "local.ip", str);
pw_properties_set(props, "local_ip", NULL); pw_properties_set(props, "local_ip", NULL);
} else {
pw_properties_set(roc_props, "local.ip", ROC_DEFAULT_IP);
} }
if ((str = pw_properties_get(props, "remote_source_port")) != NULL) { if ((str = pw_properties_get(props, "remote_source_port")) != NULL) {
pw_properties_set(roc_props, "remote.source.port", str); pw_properties_set(roc_props, "remote.source.port", str);
pw_properties_set(props, "remote_source_port", NULL); pw_properties_set(props, "remote_source_port", NULL);
} else {
pw_properties_set(roc_props, "remote.source.port", ROC_DEFAULT_SOURCE_PORT);
} }
if ((str = pw_properties_get(props, "remote_repair_port")) != NULL) { if ((str = pw_properties_get(props, "remote_repair_port")) != NULL) {
pw_properties_set(roc_props, "remote.repair.port", str); pw_properties_set(roc_props, "remote.repair.port", str);
pw_properties_set(props, "remote_repair_port", NULL); pw_properties_set(props, "remote_repair_port", NULL);
} else { }
pw_properties_set(roc_props, "remote.repair.port", ROC_DEFAULT_REPAIR_PORT); if ((str = pw_properties_get(props, "fec_code")) != NULL) {
pw_properties_set(roc_props, "fec.code", str);
pw_properties_set(props, "fec_code", NULL);
} }
module = module_new(impl, sizeof(*d)); module = module_new(impl, sizeof(*d));

View file

@ -116,6 +116,7 @@ static const struct spa_dict_item module_roc_source_info[] = {
{ PW_KEY_MODULE_USAGE, "source_name=<name for the source> " { PW_KEY_MODULE_USAGE, "source_name=<name for the source> "
"source_properties=<properties for the source> " "source_properties=<properties for the source> "
"resampler_profile=<empty>|disable|high|medium|low " "resampler_profile=<empty>|disable|high|medium|low "
"fec_code=<empty>|disable|rs8m|ldpc "
"sess_latency_msec=<target network latency in milliseconds> " "sess_latency_msec=<target network latency in milliseconds> "
"local_ip=<local receiver ip> " "local_ip=<local receiver ip> "
"local_source_port=<local receiver port for source packets> " "local_source_port=<local receiver port for source packets> "
@ -183,6 +184,11 @@ struct module *create_module_roc_source(struct impl *impl, const char *argument)
pw_properties_set(props, "resampler_profile", NULL); pw_properties_set(props, "resampler_profile", NULL);
} }
if ((str = pw_properties_get(props, "fec_code")) != NULL) {
pw_properties_set(roc_props, "fec.code", str);
pw_properties_set(props, "fec_code", NULL);
}
module = module_new(impl, sizeof(*d)); module = module_new(impl, sizeof(*d));
if (module == NULL) { if (module == NULL) {
res = -errno; res = -errno;

View file

@ -116,12 +116,28 @@ struct module_roc_sink_data {
roc_context *context; roc_context *context;
roc_sender *sender; roc_sender *sender;
roc_fec_code fec_code;
char *local_ip; char *local_ip;
char *remote_ip; char *remote_ip;
int remote_source_port; int remote_source_port;
int remote_repair_port; int remote_repair_port;
}; };
static int roc_parse_fec_code(roc_fec_code *out, const char *str)
{
if (!str || !*str)
*out = ROC_FEC_DEFAULT;
else if (spa_streq(str, "disable"))
*out = ROC_FEC_DISABLE;
else if (spa_streq(str, "rs8m"))
*out = ROC_FEC_RS8M;
else if (spa_streq(str, "ldpc"))
*out = ROC_FEC_LDPC_STAIRCASE;
else
return -EINVAL;
return 0;
}
static void stream_destroy(void *d) static void stream_destroy(void *d)
{ {
struct module_roc_sink_data *data = d; struct module_roc_sink_data *data = d;
@ -260,6 +276,7 @@ static int roc_sink_setup(struct module_roc_sink_data *data)
uint32_t n_params; uint32_t n_params;
uint8_t buffer[1024]; uint8_t buffer[1024];
int res; int res;
roc_protocol audio_proto, repair_proto;
if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) { if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) {
pw_log_error("Invalid local IP address"); pw_log_error("Invalid local IP address");
@ -291,6 +308,7 @@ static int roc_sink_setup(struct module_roc_sink_data *data)
sender_config.frame_sample_rate = 44100; sender_config.frame_sample_rate = 44100;
sender_config.frame_channels = ROC_CHANNEL_SET_STEREO; sender_config.frame_channels = ROC_CHANNEL_SET_STEREO;
sender_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT; sender_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT;
sender_config.fec_code = data->fec_code;
/* Fixed to be the same as ROC sender config above */ /* Fixed to be the same as ROC sender config above */
info.rate = 44100; info.rate = 44100;
@ -312,17 +330,35 @@ static int roc_sink_setup(struct module_roc_sink_data *data)
return -EINVAL; return -EINVAL;
} }
if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_SOURCE, ROC_PROTO_RTP_RS8M_SOURCE, switch (data->fec_code) {
case ROC_FEC_DEFAULT:
case ROC_FEC_RS8M:
audio_proto = ROC_PROTO_RTP_RS8M_SOURCE;
repair_proto = ROC_PROTO_RS8M_REPAIR;
break;
case ROC_FEC_LDPC_STAIRCASE:
audio_proto = ROC_PROTO_RTP_LDPC_SOURCE;
repair_proto = ROC_PROTO_LDPC_REPAIR;
break;
default:
audio_proto = ROC_PROTO_RTP;
repair_proto = 0;
break;
}
if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_SOURCE, audio_proto,
&data->remote_source_addr) != 0) { &data->remote_source_addr) != 0) {
pw_log_error("can't connect roc sender to remote source address"); pw_log_error("can't connect roc sender to remote source address");
return -EINVAL; return -EINVAL;
} }
if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_REPAIR, ROC_PROTO_RS8M_REPAIR, if (repair_proto != 0) {
if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_REPAIR, repair_proto,
&data->remote_repair_addr) != 0) { &data->remote_repair_addr) != 0) {
pw_log_error("can't connect roc sender to remote repair address"); pw_log_error("can't connect roc sender to remote repair address");
return -EINVAL; return -EINVAL;
} }
}
data->capture = pw_stream_new(data->core, data->capture = pw_stream_new(data->core,
"roc-sink capture", data->capture_props); "roc-sink capture", data->capture_props);
@ -369,8 +405,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
struct module_roc_sink_data *data; struct module_roc_sink_data *data;
struct pw_properties *props = NULL, *capture_props = NULL; struct pw_properties *props = NULL, *capture_props = NULL;
const char *str; const char *str;
char *local_ip = NULL, *remote_ip = NULL; int res = 0;
int res = 0, remote_repair_port, remote_source_port;
PW_LOG_TOPIC_INIT(mod_topic); PW_LOG_TOPIC_INIT(mod_topic);
@ -420,7 +455,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
pw_properties_set(capture_props, PW_KEY_MEDIA_CLASS, "Audio/Sink"); pw_properties_set(capture_props, PW_KEY_MEDIA_CLASS, "Audio/Sink");
if ((str = pw_properties_get(props, "remote.ip")) != NULL) { if ((str = pw_properties_get(props, "remote.ip")) != NULL) {
remote_ip = strdup(str); data->remote_ip = strdup(str);
pw_properties_set(props, "remote.ip", NULL); pw_properties_set(props, "remote.ip", NULL);
} else { } else {
pw_log_error("Remote IP not specified"); pw_log_error("Remote IP not specified");
@ -429,24 +464,34 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
} }
if ((str = pw_properties_get(props, "local.ip")) != NULL) { if ((str = pw_properties_get(props, "local.ip")) != NULL) {
local_ip = strdup(str); data->local_ip = strdup(str);
pw_properties_set(props, "local.ip", NULL); pw_properties_set(props, "local.ip", NULL);
} else { } else {
local_ip = strdup(ROC_DEFAULT_IP); data->local_ip = strdup(ROC_DEFAULT_IP);
} }
if ((str = pw_properties_get(props, "remote.source.port")) != NULL) { if ((str = pw_properties_get(props, "remote.source.port")) != NULL) {
remote_source_port = pw_properties_parse_int(str); data->remote_source_port = pw_properties_parse_int(str);
pw_properties_set(props, "remote.source.port", NULL); pw_properties_set(props, "remote.source.port", NULL);
} else { } else {
remote_source_port = ROC_DEFAULT_SOURCE_PORT; data->remote_source_port = ROC_DEFAULT_SOURCE_PORT;
} }
if ((str = pw_properties_get(props, "remote.repair.port")) != NULL) { if ((str = pw_properties_get(props, "remote.repair.port")) != NULL) {
remote_repair_port = pw_properties_parse_int(str); data->remote_repair_port = pw_properties_parse_int(str);
pw_properties_set(props, "remote.repair.port", NULL); pw_properties_set(props, "remote.repair.port", NULL);
} else { } else {
remote_repair_port = ROC_DEFAULT_REPAIR_PORT; data->remote_repair_port = ROC_DEFAULT_REPAIR_PORT;
}
if ((str = pw_properties_get(props, "fec.code")) != NULL) {
if (roc_parse_fec_code(&data->fec_code, str)) {
pw_log_error("Invalid fec code %s, using default", str);
data->fec_code = ROC_FEC_DEFAULT;
}
pw_log_info("using fec.code %s %d", str, data->fec_code);
pw_properties_set(props, "fec.code", NULL);
} else {
data->fec_code = ROC_FEC_DEFAULT;
} }
data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core); data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core);
@ -472,12 +517,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
&data->core_listener, &data->core_listener,
&core_events, data); &core_events, data);
data->capture_props = capture_props;
data->local_ip = local_ip;
data->remote_ip = remote_ip;
data->remote_source_port = remote_source_port;
data->remote_repair_port = remote_repair_port;
if ((res = roc_sink_setup(data)) < 0) if ((res = roc_sink_setup(data)) < 0)
goto out; goto out;

View file

@ -121,7 +121,8 @@ struct module_roc_source_data {
roc_context *context; roc_context *context;
roc_receiver *receiver; roc_receiver *receiver;
char *resampler_profile; roc_resampler_profile resampler_profile;
roc_fec_code fec_code;
char *local_ip; char *local_ip;
int local_source_port; int local_source_port;
int local_repair_port; int local_repair_port;
@ -137,25 +138,34 @@ static void stream_destroy(void *d)
static int roc_parse_resampler_profile(roc_resampler_profile *out, const char *str) static int roc_parse_resampler_profile(roc_resampler_profile *out, const char *str)
{ {
if (!str || !*str) { if (!str || !*str)
*out = ROC_RESAMPLER_DEFAULT; *out = ROC_RESAMPLER_DEFAULT;
return 0; else if (spa_streq(str, "disable"))
} else if (spa_streq(str, "disable") == 0) {
*out = ROC_RESAMPLER_DISABLE; *out = ROC_RESAMPLER_DISABLE;
return 0; else if (spa_streq(str, "high"))
} else if (spa_streq(str, "high") == 0) {
*out = ROC_RESAMPLER_HIGH; *out = ROC_RESAMPLER_HIGH;
return 0; else if (spa_streq(str, "medium"))
} else if (spa_streq(str, "medium") == 0) {
*out = ROC_RESAMPLER_MEDIUM; *out = ROC_RESAMPLER_MEDIUM;
return 0; else if (spa_streq(str, "low"))
} else if (spa_streq(str, "low") == 0) {
*out = ROC_RESAMPLER_LOW; *out = ROC_RESAMPLER_LOW;
return 0; else
} else {
pw_log_error("Invalid resampler profile: %s", str);
return -EINVAL; return -EINVAL;
} return 0;
}
static int roc_parse_fec_code(roc_fec_code *out, const char *str)
{
if (!str || !*str)
*out = ROC_FEC_DEFAULT;
else if (spa_streq(str, "disable"))
*out = ROC_FEC_DISABLE;
else if (spa_streq(str, "rs8m"))
*out = ROC_FEC_RS8M;
else if (spa_streq(str, "ldpc"))
*out = ROC_FEC_LDPC_STAIRCASE;
else
return -EINVAL;
return 0;
} }
static void playback_process(void *data) static void playback_process(void *data)
@ -265,7 +275,6 @@ static void impl_destroy(struct module_roc_source_data *data)
roc_context_close(data->context); roc_context_close(data->context);
free(data->local_ip); free(data->local_ip);
free(data->resampler_profile);
free(data); free(data);
} }
@ -291,6 +300,7 @@ static int roc_source_setup(struct module_roc_source_data *data)
uint32_t n_params; uint32_t n_params;
uint8_t buffer[1024]; uint8_t buffer[1024];
int res; int res;
roc_protocol audio_proto, repair_proto;
if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) { if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) {
pw_log_error("Invalid local IP address"); pw_log_error("Invalid local IP address");
@ -309,19 +319,18 @@ static int roc_source_setup(struct module_roc_source_data *data)
return -EINVAL; return -EINVAL;
} }
memset(&context_config, 0, sizeof(context_config)); spa_zero(context_config);
data->context = roc_context_open(&context_config); data->context = roc_context_open(&context_config);
if (!data->context) { if (!data->context) {
pw_log_error("Failed to create roc context"); pw_log_error("Failed to create roc context");
return -EINVAL; return -EINVAL;
} }
memset(&receiver_config, 0, sizeof(receiver_config)); spa_zero(receiver_config);
receiver_config.frame_sample_rate = 44100; receiver_config.frame_sample_rate = 44100;
receiver_config.frame_channels = ROC_CHANNEL_SET_STEREO; receiver_config.frame_channels = ROC_CHANNEL_SET_STEREO;
receiver_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT; receiver_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT;
receiver_config.resampler_profile = data->resampler_profile;
/* Fixed to be the same as ROC receiver config above */ /* Fixed to be the same as ROC receiver config above */
info.rate = 44100; info.rate = 44100;
@ -333,12 +342,6 @@ static int roc_source_setup(struct module_roc_source_data *data)
pw_properties_setf(data->playback_props, PW_KEY_NODE_RATE, "1/%d", info.rate); pw_properties_setf(data->playback_props, PW_KEY_NODE_RATE, "1/%d", info.rate);
if (roc_parse_resampler_profile(&receiver_config.resampler_profile,
data->resampler_profile)) {
pw_log_error("Invalid resampler profile");
return -EINVAL;
}
/* /*
* Note that target latency is in nano seconds. * Note that target latency is in nano seconds.
* *
@ -358,17 +361,34 @@ static int roc_source_setup(struct module_roc_source_data *data)
return -EINVAL; return -EINVAL;
} }
if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_SOURCE, ROC_PROTO_RTP_RS8M_SOURCE, switch (data->fec_code) {
case ROC_FEC_DEFAULT:
case ROC_FEC_RS8M:
audio_proto = ROC_PROTO_RTP_RS8M_SOURCE;
repair_proto = ROC_PROTO_RS8M_REPAIR;
break;
case ROC_FEC_LDPC_STAIRCASE:
audio_proto = ROC_PROTO_RTP_LDPC_SOURCE;
repair_proto = ROC_PROTO_LDPC_REPAIR;
break;
default:
audio_proto = ROC_PROTO_RTP;
repair_proto = 0;
break;
}
if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_SOURCE, audio_proto,
&data->local_source_addr) != 0) { &data->local_source_addr) != 0) {
pw_log_error("can't connect roc receiver to local source address"); pw_log_error("can't connect roc receiver to local source address");
return -EINVAL; return -EINVAL;
} }
if (repair_proto != 0) {
if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_REPAIR, ROC_PROTO_RS8M_REPAIR, if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_REPAIR, repair_proto,
&data->local_repair_addr) != 0) { &data->local_repair_addr) != 0) {
pw_log_error("can't connect roc receiver to local repair address"); pw_log_error("can't connect roc receiver to local repair address");
return -EINVAL; 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);
@ -402,6 +422,7 @@ static const struct spa_dict_item module_roc_source_info[] = {
{ PW_KEY_MODULE_DESCRIPTION, "roc source" }, { PW_KEY_MODULE_DESCRIPTION, "roc source" },
{ PW_KEY_MODULE_USAGE, "source.name=<name for the source> " { PW_KEY_MODULE_USAGE, "source.name=<name for the source> "
"resampler.profile=<empty>|disable|high|medium|low " "resampler.profile=<empty>|disable|high|medium|low "
"fec.code=<empty>|disable|rs8m|ldpc "
"sess.latency.msec=<target network latency in milliseconds> " "sess.latency.msec=<target network latency in milliseconds> "
"local.ip=<local receiver ip> " "local.ip=<local receiver ip> "
"local.source.port=<local receiver port for source packets> " "local.source.port=<local receiver port for source packets> "
@ -417,8 +438,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
struct module_roc_source_data *data; struct module_roc_source_data *data;
struct pw_properties *props = NULL, *playback_props = NULL; struct pw_properties *props = NULL, *playback_props = NULL;
const char *str; const char *str;
char *local_ip = NULL, *resampler_profile = NULL; int res = 0;
int res = 0, local_repair_port, local_source_port, sess_latency_msec;
PW_LOG_TOPIC_INIT(mod_topic); PW_LOG_TOPIC_INIT(mod_topic);
@ -466,36 +486,50 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
pw_properties_set(playback_props, PW_KEY_NODE_NETWORK, "true"); pw_properties_set(playback_props, PW_KEY_NODE_NETWORK, "true");
if ((str = pw_properties_get(props, "local.ip")) != NULL) { if ((str = pw_properties_get(props, "local.ip")) != NULL) {
local_ip = strdup(str); data->local_ip = strdup(str);
pw_properties_set(props, "local.ip", NULL); pw_properties_set(props, "local.ip", NULL);
} else { } else {
local_ip = strdup(ROC_DEFAULT_IP); data->local_ip = strdup(ROC_DEFAULT_IP);
} }
if ((str = pw_properties_get(props, "local.source.port")) != NULL) { if ((str = pw_properties_get(props, "local.source.port")) != NULL) {
local_source_port = pw_properties_parse_int(str); data->local_source_port = pw_properties_parse_int(str);
pw_properties_set(props, "local.source.port", NULL); pw_properties_set(props, "local.source.port", NULL);
} else { } else {
local_source_port = ROC_DEFAULT_SOURCE_PORT; data->local_source_port = ROC_DEFAULT_SOURCE_PORT;
} }
if ((str = pw_properties_get(props, "local.repair.port")) != NULL) { if ((str = pw_properties_get(props, "local.repair.port")) != NULL) {
local_repair_port = pw_properties_parse_int(str); data->local_repair_port = pw_properties_parse_int(str);
pw_properties_set(props, "local.repair.port", NULL); pw_properties_set(props, "local.repair.port", NULL);
} else { } else {
local_repair_port = ROC_DEFAULT_REPAIR_PORT; data->local_repair_port = ROC_DEFAULT_REPAIR_PORT;
} }
if ((str = pw_properties_get(props, "sess.latency.msec")) != NULL) { if ((str = pw_properties_get(props, "sess.latency.msec")) != NULL) {
sess_latency_msec = pw_properties_parse_int(str); data->sess_latency_msec = pw_properties_parse_int(str);
pw_properties_set(props, "sess.latency.msec", NULL); pw_properties_set(props, "sess.latency.msec", NULL);
} else { } else {
sess_latency_msec = ROC_DEFAULT_SESS_LATENCY; data->sess_latency_msec = ROC_DEFAULT_SESS_LATENCY;
} }
if ((str = pw_properties_get(props, "resampler.profile")) != NULL) { if ((str = pw_properties_get(props, "resampler.profile")) != NULL) {
resampler_profile = strdup(str); if (roc_parse_resampler_profile(&data->resampler_profile, str)) {
pw_log_warn("Invalid resampler profile %s, using default", str);
data->resampler_profile = ROC_RESAMPLER_DEFAULT;
}
pw_properties_set(props, "resampler.profile", NULL); pw_properties_set(props, "resampler.profile", NULL);
} else {
data->resampler_profile = ROC_RESAMPLER_DEFAULT;
}
if ((str = pw_properties_get(props, "fec.code")) != NULL) {
if (roc_parse_fec_code(&data->fec_code, str)) {
pw_log_error("Invalid fec code %s, using default", str);
data->fec_code = ROC_FEC_DEFAULT;
}
pw_properties_set(props, "fec.code", NULL);
} else {
data->fec_code = ROC_FEC_DEFAULT;
} }
data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core); data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core);
@ -521,12 +555,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
&data->core_listener, &data->core_listener,
&core_events, data); &core_events, data);
data->local_ip = local_ip;
data->local_source_port = local_source_port;
data->local_repair_port = local_repair_port;
data->sess_latency_msec = sess_latency_msec;
data->resampler_profile = resampler_profile;
if ((res = roc_source_setup(data)) < 0) if ((res = roc_source_setup(data)) < 0)
goto out; goto out;