modules: improve simple-protocol arguments

Use the format parsing code to also parse the channel_map.
Improve serialization of the properties.

See #2068
This commit is contained in:
Wim Taymans 2022-01-27 16:30:08 +01:00
parent 0ba5aebf0b
commit ee007eaf6c
2 changed files with 29 additions and 29 deletions

View file

@ -36,9 +36,12 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
struct module_simple_protocol_tcp_data { struct module_simple_protocol_tcp_data {
struct module *module; struct module *module;
struct pw_properties *module_props;
struct pw_impl_module *mod; struct pw_impl_module *mod;
struct spa_hook mod_listener; struct spa_hook mod_listener;
struct pw_properties *module_props;
struct spa_audio_info_raw info;
}; };
static void module_destroy(void *data) static void module_destroy(void *data)
@ -61,29 +64,26 @@ static int module_simple_protocol_tcp_load(struct client *client, struct module
struct module_simple_protocol_tcp_data *data = module->user_data; struct module_simple_protocol_tcp_data *data = module->user_data;
struct impl *impl = client->impl; struct impl *impl = client->impl;
char *args; char *args;
const char *str;
size_t size; size_t size;
uint32_t i;
FILE *f; FILE *f;
f = open_memstream(&args, &size); f = open_memstream(&args, &size);
if ((str = pw_properties_get(data->module_props, "audio.format")) != NULL) fprintf(f, "{");
fprintf(f, "audio.format=%s ", str); if (data->info.rate != 0)
if ((str = pw_properties_get(data->module_props, "audio.rate")) != NULL) fprintf(f, " \"audio.rate\": %u,", data->info.rate);
fprintf(f, "audio.rate=%s ", str); if (data->info.channels != 0) {
if ((str = pw_properties_get(data->module_props, "audio.channels")) != NULL) fprintf(f, " \"audio.channels\": %u,", data->info.channels);
fprintf(f, "audio.channels=%s ", str); if (!(data->info.flags & SPA_AUDIO_FLAG_UNPOSITIONED)) {
if ((str = pw_properties_get(data->module_props, "server.address")) != NULL) fprintf(f, " \"audio.position\": [ ");
fprintf(f, "server.address=%s ", str); for (i = 0; i < data->info.channels; i++)
if ((str = pw_properties_get(data->module_props, "capture")) != NULL) fprintf(f, "%s\"%s\"", i == 0 ? "" : ",",
fprintf(f, "capture=%s ", str); channel_id2name(data->info.position[i]));
if ((str = pw_properties_get(data->module_props, "playback")) != NULL) fprintf(f, " ],");
fprintf(f, "playback=%s ", str); }
if ((str = pw_properties_get(data->module_props, "capture.node")) != NULL) }
fprintf(f, "capture.node=\"%s\" ", str); pw_properties_serialize_dict(f, &data->module_props->dict, 0);
if ((str = pw_properties_get(data->module_props, "playback.node")) != NULL) fprintf(f, "}");
fprintf(f, "playback.node=\"%s\" ", str);
if ((str = pw_properties_get(data->module_props, PW_KEY_STREAM_CAPTURE_SINK)) != NULL)
fprintf(f, PW_KEY_STREAM_CAPTURE_SINK"=\"%s\" ", str);
fclose(f); fclose(f);
data->mod = pw_context_load_module(impl->context, data->mod = pw_context_load_module(impl->context,
@ -125,6 +125,7 @@ static const struct spa_dict_item module_simple_protocol_tcp_info[] = {
{ PW_KEY_MODULE_USAGE, "rate=<sample rate> " { PW_KEY_MODULE_USAGE, "rate=<sample rate> "
"format=<sample format> " "format=<sample format> "
"channels=<number of channels> " "channels=<number of channels> "
"channel_map=<number of channels> "
"sink=<sink to connect to> " "sink=<sink to connect to> "
"source=<source to connect to> " "source=<source to connect to> "
"playback=<enable playback?> " "playback=<enable playback?> "
@ -140,6 +141,7 @@ struct module *create_module_simple_protocol_tcp(struct impl *impl, const char *
struct module_simple_protocol_tcp_data *d; struct module_simple_protocol_tcp_data *d;
struct pw_properties *props = NULL, *module_props = NULL; struct pw_properties *props = NULL, *module_props = NULL;
const char *str, *port, *listen; const char *str, *port, *listen;
struct spa_audio_info_raw info = { 0 };
int res; int res;
PW_LOG_TOPIC_INIT(mod_topic); PW_LOG_TOPIC_INIT(mod_topic);
@ -158,17 +160,14 @@ struct module *create_module_simple_protocol_tcp(struct impl *impl, const char *
goto out; goto out;
} }
if ((str = pw_properties_get(props, "rate")) != NULL) {
pw_properties_set(module_props, "audio.rate", str);
pw_properties_set(props, "rate", NULL);
}
if ((str = pw_properties_get(props, "format")) != NULL) { if ((str = pw_properties_get(props, "format")) != NULL) {
pw_properties_set(module_props, "audio.format", format_id2name(format_paname2id(str, strlen(str)))); pw_properties_set(module_props, "audio.format",
format_id2name(format_paname2id(str, strlen(str))));
pw_properties_set(props, "format", NULL); pw_properties_set(props, "format", NULL);
} }
if ((str = pw_properties_get(props, "channels")) != NULL) { if (module_args_to_audioinfo(impl, props, &info) < 0) {
pw_properties_set(module_props, "audio.channels", str); res = -EINVAL;
pw_properties_set(props, "channels", NULL); goto out;
} }
if ((str = pw_properties_get(props, "playback")) != NULL) { if ((str = pw_properties_get(props, "playback")) != NULL) {
pw_properties_set(module_props, "playback", str); pw_properties_set(module_props, "playback", str);
@ -213,6 +212,7 @@ struct module *create_module_simple_protocol_tcp(struct impl *impl, const char *
d = module->user_data; d = module->user_data;
d->module = module; d->module = module;
d->module_props = module_props; d->module_props = module_props;
d->info = info;
return module; return module;
out: out:

View file

@ -70,7 +70,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
#define MODULE_USAGE "[ capture=<bool> ] " \ #define MODULE_USAGE "[ capture=<bool> ] " \
"[ playback=<bool> ] " \ "[ playback=<bool> ] " \
"[ capture.node=<source-target> ] " \ "[ capture.node=<source-target> [ stream.capture.sink=true ]] " \
"[ playback.node=<sink-target> ] " \ "[ playback.node=<sink-target> ] " \
"[ audio.rate=<sample-rate, default:"DEFAULT_RATE"> ] " \ "[ audio.rate=<sample-rate, default:"DEFAULT_RATE"> ] " \
"[ audio.format=<format, default:"DEFAULT_FORMAT"> ] " \ "[ audio.format=<format, default:"DEFAULT_FORMAT"> ] " \