diff --git a/src/modules/module-protocol-pulse/module.c b/src/modules/module-protocol-pulse/module.c index 3b0cf0ea5..308c69659 100644 --- a/src/modules/module-protocol-pulse/module.c +++ b/src/modules/module-protocol-pulse/module.c @@ -170,15 +170,15 @@ void module_args_add_props(struct pw_properties *props, const char *str) } } -static bool find_key(const char * const keys[], const char *key) +static bool find_key(const struct module_args args[], const char *key) { - for (int i = 0; keys[i] != NULL; i++) - if (spa_streq(keys[i], key)) + for (int i = 0; args[i].key != NULL; i++) + if (spa_streq(args[i].key, key)) return true; return false; } -static int module_args_check(struct pw_properties *props, const char * const valid_args[]) +static int module_args_check(struct pw_properties *props, const struct module_args valid_args[]) { if (valid_args != NULL) { const struct spa_dict_item *it; @@ -188,6 +188,13 @@ static int module_args_check(struct pw_properties *props, const char * const val return -EINVAL; } } + + for (int i = 0; valid_args[i].key != NULL; i++) + if (SPA_FLAG_IS_SET(valid_args[i].flags, MODULE_ARG_MANDATORY) && + pw_properties_get(props, valid_args[i].key) == NULL) { + pw_log_warn("missing mandatory module argument '%s'", valid_args[i].key); + return -EINVAL; + } } return 0; } diff --git a/src/modules/module-protocol-pulse/module.h b/src/modules/module-protocol-pulse/module.h index 6bae8d9a5..9f36402cf 100644 --- a/src/modules/module-protocol-pulse/module.h +++ b/src/modules/module-protocol-pulse/module.h @@ -17,6 +17,13 @@ struct client; struct message; struct extension; +struct module_args { + const char *key; + const char *description; +#define MODULE_ARG_MANDATORY (1u<<0) + uint32_t flags; +}; + struct module_info { const char *name; @@ -27,7 +34,7 @@ struct module_info { int (*unload) (struct module *module); const struct extension *extension; - const char* const *valid_args; + const struct module_args *valid_args; const struct spa_dict *properties; size_t data_size; }; diff --git a/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c b/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c index c831ba92e..6b0ae0bf7 100644 --- a/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c +++ b/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c @@ -42,6 +42,24 @@ static const char *const pulse_module_options = "input_ladspaport_map= " "output_ladspaport_map= "; +static const struct module_args valid_args[] = { + { "sink_name", "name for the sink", }, + { "sink_properties", "properties for the sink", }, + { "sink_input_properties", "properties for the sink input", }, + { "master", "name of sink to filter", }, + { "sink_master", "name of sink to filter", }, + { "format", "sample format", }, + { "rate", "sample rate", }, + { "channels", "number of channels", }, + { "channel_map", "channel map", }, + { "plugin", "LADSPA plugin name", MODULE_ARG_MANDATORY }, + { "label", "LADSPA plugin label", MODULE_ARG_MANDATORY }, + { "control", "comma separated list of input control values", }, + { "input_ladspaport_map", "comma separated list of input LADSPA port names", }, + { "output_ladspaport_map", "comma separated list of output LADSPA port names", }, + { NULL, } +}; + #define NAME "ladspa-sink" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -196,7 +214,7 @@ static int module_ladspa_sink_prepare(struct module * const module) capture_props = pw_properties_new(NULL, NULL); playback_props = pw_properties_new(NULL, NULL); if (!capture_props || !playback_props) { - res = -EINVAL; + res = -ENOMEM; goto out; } @@ -226,6 +244,7 @@ static int module_ladspa_sink_prepare(struct module * const module) (str = pw_properties_get(props, "sink_master")) != NULL) { pw_properties_set(playback_props, PW_KEY_TARGET_OBJECT, str); pw_properties_set(props, "master", NULL); + pw_properties_set(props, "sink_master", NULL); } if (module_args_to_audioinfo_keys(module->impl, props, @@ -255,6 +274,7 @@ out: DEFINE_MODULE_INFO(module_ladspa_sink) = { .name = "module-ladspa-sink", + .valid_args = valid_args, .prepare = module_ladspa_sink_prepare, .load = module_ladspa_sink_load, .unload = module_ladspa_sink_unload, diff --git a/src/modules/module-protocol-pulse/modules/module-ladspa-source.c b/src/modules/module-protocol-pulse/modules/module-ladspa-source.c index 393a0124a..80284f267 100644 --- a/src/modules/module-protocol-pulse/modules/module-ladspa-source.c +++ b/src/modules/module-protocol-pulse/modules/module-ladspa-source.c @@ -42,6 +42,24 @@ static const char *const pulse_module_options = "input_ladspaport_map= " "output_ladspaport_map= "; +static const struct module_args valid_args[] = { + { "source_name", "name for the source", }, + { "source_properties", "properties for the source", }, + { "source_output_properties", "properties for the source output", }, + { "master", "name of source to filter", }, + { "source_master", "name of source to filter", }, + { "format", "sample format", }, + { "rate", "sample rate", }, + { "channels", "number of channels", }, + { "channel_map", "channel map", }, + { "plugin", "LADSPA plugin name", MODULE_ARG_MANDATORY }, + { "label", "LADSPA plugin label", MODULE_ARG_MANDATORY }, + { "control", "comma separated list of input control values", }, + { "input_ladspaport_map", "comma separated list of input LADSPA port names", }, + { "output_ladspaport_map", "comma separated list of output LADSPA port names", }, + { NULL, } +}; + #define NAME "ladspa-source" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -263,6 +281,7 @@ out: DEFINE_MODULE_INFO(module_ladspa_source) = { .name = "module-ladspa-source", + .valid_args = valid_args, .prepare = module_ladspa_source_prepare, .load = module_ladspa_source_load, .unload = module_ladspa_source_unload, diff --git a/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c b/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c index 76487425e..11af62a89 100644 --- a/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c +++ b/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c @@ -37,6 +37,19 @@ static const char *const pulse_module_options = "local_control_port= " ; +static const struct module_args valid_args[] = { + { "sink", "name for the sink", }, + { "sink_input_properties", "properties for the sink_input", }, + { "resampler_profile", "empty|high|medium|low", }, + { "fec_code", "empty|disable|rs8m|ldpc", }, + { "sess_latency_msec", "target network latency in milliseconds", }, + { "local_ip", "local receiver ip", }, + { "local_source_port", "local receiver port for source packets", }, + { "local_repair_port", "local receiver port for repair packets", }, + { "local_control_port", "local receiver port for control packets", }, + { NULL, }, +}; + #define NAME "roc-sink-input" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -199,19 +212,6 @@ out: return res; } -static const char* const valid_args[] = { - "sink", - "sink_input_properties", - "resampler_profile", - "fec_code", - "sess_latency_msec", - "local_ip", - "local_source_port", - "local_repair_port", - "local_control_port", - NULL -}; - DEFINE_MODULE_INFO(module_roc_sink_input) = { .name = "module-roc-sink-input", .valid_args = valid_args, diff --git a/src/modules/module-protocol-pulse/modules/module-roc-sink.c b/src/modules/module-protocol-pulse/modules/module-roc-sink.c index bdddadda2..7aaea3209 100644 --- a/src/modules/module-protocol-pulse/modules/module-roc-sink.c +++ b/src/modules/module-protocol-pulse/modules/module-roc-sink.c @@ -35,6 +35,17 @@ static const char *const pulse_module_options = "remote_control_port= " ; +static const struct module_args valid_args[] = { + { "sink_name", "name for the sink", }, + { "sink_properties", "properties for the sink", }, + { "fec_code", "empty|disable|rs8m|ldpc", }, + { "remote_ip", "remote receiver ip", }, + { "remote_source_port", "remote receiver port for source packets", }, + { "remote_repair_port", "remote receiver port for repair packets", }, + { "remote_control_port", "remote receiver port for control packets", }, + { NULL, }, +}; + #define NAME "roc-sink" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -117,16 +128,6 @@ static int module_roc_sink_unload(struct module *module) return 0; } -static const char* const valid_args[] = { - "sink_name", - "sink_properties", - "fec_code", - "remote_ip", - "remote_source_port", - "remote_repair_port", - "remote_control_port", - NULL -}; static const struct spa_dict_item module_roc_sink_info[] = { { PW_KEY_MODULE_AUTHOR, "Sanchayan Maity " }, { PW_KEY_MODULE_DESCRIPTION, "roc sink" }, diff --git a/src/modules/module-protocol-pulse/modules/module-roc-source.c b/src/modules/module-protocol-pulse/modules/module-roc-source.c index 4607ffbd6..36ec415a0 100644 --- a/src/modules/module-protocol-pulse/modules/module-roc-source.c +++ b/src/modules/module-protocol-pulse/modules/module-roc-source.c @@ -37,6 +37,19 @@ static const char *const pulse_module_options = "local_control_port= " ; +static const struct module_args valid_args[] = { + { "source_name", "name for the source", }, + { "source_properties", "properties for the source", }, + { "resampler_profile", "empty|high|medium|low", }, + { "fec_code", "empty|disable|rs8m|ldpc", }, + { "sess_latency_msec", "target network latency in milliseconds", }, + { "local_ip", "local receiver ip", }, + { "local_source_port", "local receiver port for source packets", }, + { "local_repair_port", "local receiver port for repair packets", }, + { "local_control_port", "local receiver port for control packets", }, + { NULL, }, +}; + #define NAME "roc-source" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -119,19 +132,6 @@ static int module_roc_source_unload(struct module *module) return 0; } -static const char* const valid_args[] = { - "source_name", - "source_properties", - "resampler_profile", - "fec_code", - "sess_latency_msec", - "local_ip", - "local_source_port", - "local_repair_port", - "local_control_port", - NULL -}; - static const struct spa_dict_item module_roc_source_info[] = { { PW_KEY_MODULE_AUTHOR, "Sanchayan Maity " }, { PW_KEY_MODULE_DESCRIPTION, "roc source" }, diff --git a/src/modules/module-protocol-pulse/modules/module-rtp-recv.c b/src/modules/module-protocol-pulse/modules/module-rtp-recv.c index 44b0ac13e..34a0d1348 100644 --- a/src/modules/module-protocol-pulse/modules/module-rtp-recv.c +++ b/src/modules/module-protocol-pulse/modules/module-rtp-recv.c @@ -30,6 +30,14 @@ static const char *const pulse_module_options = "latency_msec= " "stream_properties= "; +static const struct module_args valid_args[] = { + { "sink", "name of the sink", }, + { "sap_address", "multicast address to listen on", }, + { "latency_msec", "latency in ms", }, + { "stream_properties", "properties for the stream", }, + { NULL, } +}; + #define NAME "rtp-recv" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -168,14 +176,6 @@ out: return res; } -static const char* const valid_args[] = { - "sink", - "sap_address", - "latency_msec", - "stream_properties", - NULL -}; - DEFINE_MODULE_INFO(module_rtp_recv) = { .name = "module-rtp-recv", .valid_args = valid_args, diff --git a/src/modules/module-protocol-pulse/modules/module-rtp-send.c b/src/modules/module-protocol-pulse/modules/module-rtp-send.c index 7d7c2c9cb..863ad4ac5 100644 --- a/src/modules/module-protocol-pulse/modules/module-rtp-send.c +++ b/src/modules/module-protocol-pulse/modules/module-rtp-send.c @@ -40,6 +40,24 @@ static const char *const pulse_module_options = "stream_properties= " "enable_opus="; +static const struct module_args valid_args[] = { + { "source", "name of the source", }, + { "format", "sample format", }, + { "channels", "number of channels", }, + { "rate", "sample rate", }, + { "destination_ip", "destination IP address", }, + { "source_ip", "source IP address", }, + { "port", "port number", }, + { "mtu", "maximum transfer unit", }, + { "loop", "loopback to local host", }, + { "ttl", "ttl value", }, + { "inhibit_auto_suspend", "always|never|only_with_non_monitor_sources", }, + { "stream_name", "name of the stream", }, + { "stream_properties", "properties for the stream", }, + { "enable_opus", "enable OPUS codec", }, + { NULL, }, +}; + #define NAME "rtp-send" PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); @@ -266,24 +284,6 @@ out: return res; } -static const char* const valid_args[] = { - "source", - "format", - "channels", - "rate", - "destination_ip", - "source_ip", - "port", - "mtu", - "loop", - "ttl", - "inhibit_auto_suspend", - "stream_name", - "stream_properties", - "enable_opus", - NULL -}; - DEFINE_MODULE_INFO(module_rtp_send) = { .name = "module-rtp-send", .valid_args = valid_args,