diff --git a/Makefile.in b/Makefile.in index 522c0a295..2b081a1b8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ run: all PIPEWIRE_CONFIG_DIR=@BUILD_ROOT@/src/daemon/ \ ACP_PATHS_DIR=@SOURCE_ROOT@/spa/plugins/alsa/mixer/paths \ ACP_PROFILES_DIR=@SOURCE_ROOT@/spa/plugins/alsa/mixer/profile-sets \ - $(DBG) @BUILD_ROOT@/src/daemon/pipewire + $(DBG) @BUILD_ROOT@/src/daemon/pipewire -c pipewire-uninstalled.conf gdb: $(MAKE) run DBG=gdb diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index e7c467032..350fb4358 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -2424,6 +2424,9 @@ jack_client_t * jack_client_open (const char *client_name, client->context.l, pw_properties_copy(client->props), 0); + if (client->context.context == NULL) + goto no_props; + client->allow_mlock = client->context.context->defaults.mem_allow_mlock; client->warn_mlock = client->context.context->defaults.mem_warn_mlock; diff --git a/src/daemon/client-rt.conf.in b/src/daemon/client-rt.conf.in index 05f9f6344..70728d184 100644 --- a/src/daemon/client-rt.conf.in +++ b/src/daemon/client-rt.conf.in @@ -1,6 +1,6 @@ -# Daemon config file for PipeWire RT clients version @VERSION@ # +# Real-time Client config file for PipeWire version @VERSION@ # -properties = { +context.properties = { ## Configure properties in the system. #mem.warn-mlock = false #mem.allow-mlock = true @@ -8,7 +8,7 @@ properties = { #log.level = 2 } -spa-libs = { +context.spa-libs = { ## = # # Used to find spa factory names. It maps an spa factory name @@ -19,7 +19,7 @@ spa-libs = { support.* = support/libspa-support } -modules = { +context.modules = { ## = { [args = { = ... }] # [flags = [ [ifexists] [nofail] ]} # diff --git a/src/daemon/client.conf.in b/src/daemon/client.conf.in index 6ce408369..e1568a3df 100644 --- a/src/daemon/client.conf.in +++ b/src/daemon/client.conf.in @@ -1,6 +1,5 @@ -# Daemon config file for PipeWire clients version @VERSION@ # - -properties = { +# Client config file for PipeWire version @VERSION@ # +context.properties = { ## Configure properties in the system. #mem.warn-mlock = false #mem.allow-mlock = true @@ -8,7 +7,7 @@ properties = { #log.level = 2 } -spa-libs = { +context.spa-libs = { ## = # # Used to find spa factory names. It maps an spa factory name @@ -19,7 +18,7 @@ spa-libs = { support.* = support/libspa-support } -modules = { +context.modules = { ## = { [args = { = ... }] # [flags = [ [ifexists] [nofail] ]} # diff --git a/src/daemon/jack.conf.in b/src/daemon/jack.conf.in index d40ff142c..8356efac8 100644 --- a/src/daemon/jack.conf.in +++ b/src/daemon/jack.conf.in @@ -1,6 +1,6 @@ -# Daemon config file for PipeWire JACK clients version @VERSION@ # +# JACK client config file for PipeWire version @VERSION@ # -properties = { +context.properties = { ## Configure properties in the system. #mem.warn-mlock = false #mem.allow-mlock = true @@ -8,7 +8,7 @@ properties = { #log.level = 2 } -spa-libs = { +context.spa-libs = { ## = # # Used to find spa factory names. It maps an spa factory name @@ -18,7 +18,7 @@ spa-libs = { support.* = support/libspa-support } -modules = { +context.modules = { ## = { [args = { = ... }] # [flags = [ [ifexists] [nofail] ]} # diff --git a/src/daemon/main.c b/src/daemon/main.c index 8fd58f40a..579345901 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -24,56 +24,39 @@ #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include - -#include +#include #include "config.h" -#define NAME "daemon" - -#define DEFAULT_CONFIG_FILE "pipewire.conf" - -struct data { - struct pw_context *context; - struct pw_main_loop *loop; - - const char *daemon_name; -}; +static const char *config_name = "pipewire.conf"; static void do_quit(void *data, int signal_number) { - struct data *d = data; - pw_main_loop_quit(d->loop); + struct pw_main_loop *loop = data; + pw_main_loop_quit(loop); } -static void show_help(struct data *d, const char *name) +static void show_help(const char *name) { fprintf(stdout, "%s [options]\n" " -h, --help Show this help\n" " --version Show version\n" - " -n, --name Daemon name (Default %s)\n", + " -c, --config Load config (Default %s)\n", name, - d->daemon_name); + config_name); } int main(int argc, char *argv[]) { - struct data d; + struct pw_context *context; + struct pw_main_loop *loop; struct pw_properties *properties; static const struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, - { "name", required_argument, NULL, 'n' }, + { "config", required_argument, NULL, 'c' }, { NULL, 0, NULL, 0} }; @@ -82,19 +65,14 @@ int main(int argc, char *argv[]) if (setenv("PIPEWIRE_INTERNAL", "1", 1) < 0) fprintf(stderr, "can't set PIPEWIRE_INTERNAL env: %m"); - spa_zero(d); pw_init(&argc, &argv); - d.daemon_name = getenv("PIPEWIRE_CORE"); - if (d.daemon_name == NULL) - d.daemon_name = PW_DEFAULT_REMOTE; - - while ((c = getopt_long(argc, argv, "hVn:", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hVc:", long_options, NULL)) != -1) { switch (c) { - case 'h' : - show_help(&d, argv[0]); + case 'h': + show_help(argv[0]); return 0; - case 'V' : + case 'V': fprintf(stdout, "%s\n" "Compiled with libpipewire %s\n" "Linked with libpipewire %s\n", @@ -102,9 +80,8 @@ int main(int argc, char *argv[]) pw_get_headers_version(), pw_get_library_version()); return 0; - case 'n' : - d.daemon_name = optarg; - fprintf(stdout, "set name %s\n", d.daemon_name); + case 'c': + config_name = optarg; break; default: return -1; @@ -112,31 +89,30 @@ int main(int argc, char *argv[]) } properties = pw_properties_new( - PW_KEY_CORE_NAME, d.daemon_name, - PW_KEY_CONFIG_NAME, "pipewire-uninstalled.conf", - PW_KEY_CORE_DAEMON, "true", NULL); + PW_KEY_CONFIG_NAME, config_name, + NULL); - d.loop = pw_main_loop_new(&properties->dict); - if (d.loop == NULL) { + loop = pw_main_loop_new(&properties->dict); + if (loop == NULL) { pw_log_error("failed to create main-loop: %m"); return -1; } - pw_loop_add_signal(pw_main_loop_get_loop(d.loop), SIGINT, do_quit, &d); - pw_loop_add_signal(pw_main_loop_get_loop(d.loop), SIGTERM, do_quit, &d); + pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGINT, do_quit, loop); + pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGTERM, do_quit, loop); - d.context = pw_context_new(pw_main_loop_get_loop(d.loop), properties, 0); - if (d.context == NULL) { + context = pw_context_new(pw_main_loop_get_loop(loop), properties, 0); + if (context == NULL) { pw_log_error("failed to create context: %m"); return -1; } pw_log_info("start main loop"); - pw_main_loop_run(d.loop); + pw_main_loop_run(loop); pw_log_info("leave main loop"); - pw_context_destroy(d.context); - pw_main_loop_destroy(d.loop); + pw_context_destroy(context); + pw_main_loop_destroy(loop); pw_deinit(); return 0; diff --git a/src/daemon/media-session.d/media-session.conf b/src/daemon/media-session.d/media-session.conf index 324d612b7..ae1053112 100644 --- a/src/daemon/media-session.d/media-session.conf +++ b/src/daemon/media-session.d/media-session.conf @@ -1,6 +1,5 @@ # Media session config file # - -properties = { +context.properties = { # Properties to configure the session and some # modules. #mem.mlock-all = false @@ -8,7 +7,7 @@ properties = { #dbus = true } -spa-libs = { +context.spa-libs = { # Mapping from factory name to library. api.bluez5.* = bluez5/libspa-bluez5 api.alsa.* = alsa/libspa-alsa @@ -16,7 +15,7 @@ spa-libs = { api.libcamera.* = libcamera/libspa-libcamera } -modules = { +context.modules = { ## = { [args = { = ... }] # [flags = [ [ifexists] [nofail] ]} # diff --git a/src/daemon/meson.build b/src/daemon/meson.build index 85e3efe87..c445c588c 100644 --- a/src/daemon/meson.build +++ b/src/daemon/meson.build @@ -11,12 +11,15 @@ pipewire_c_args = [ conf_config = configuration_data() conf_config.set('VERSION', '"@0@"'.format(pipewire_version)) conf_config.set('media_session_path', join_paths(pipewire_bindir, 'pipewire-media-session')) +conf_config.set('pipewire_path', join_paths(pipewire_bindir, 'pipewire')) conf_config.set('pipewire_pulse_path', join_paths(pipewire_bindir, 'pipewire-pulse')) conf_install_dir = join_paths(get_option('sysconfdir'), 'pipewire') conf_config_uninstalled = conf_config conf_config_uninstalled.set('media_session_path', join_paths(meson.build_root(), 'src', 'examples', 'pipewire-media-session')) +conf_config_uninstalled.set('pipewire_path', + join_paths(meson.build_root(), 'src', 'daemon', 'pipewire')) conf_config_uninstalled.set('pipewire_pulse_path', join_paths(meson.build_root(), 'src', 'daemon', 'pipewire-pulse')) diff --git a/src/daemon/pipewire-pulse.c b/src/daemon/pipewire-pulse.c index 95d576db8..18601c71e 100644 --- a/src/daemon/pipewire-pulse.c +++ b/src/daemon/pipewire-pulse.c @@ -27,11 +27,11 @@ #include -#include +#include #include "config.h" -static const char *address; +static const char *config_name = "pipewire-pulse.conf"; static void do_quit(void *data, int signal_number) { @@ -45,11 +45,9 @@ static void show_help(const char *name) "Start a pulseaudio compatible daemon.\n\n" " -h, --help Show this help\n" " --version Show version\n" - " -a --address comma separated list of addresses (Default %s)\n" - " unix:\n" - " tcp:[][:]\n", + " -c, --config Load config (Default %s)\n", name, - address); + config_name); } int main(int argc, char *argv[]) @@ -57,20 +55,17 @@ int main(int argc, char *argv[]) struct pw_context *context; struct pw_main_loop *loop; struct pw_properties *properties; - char *args; static const struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, - { "address", required_argument, NULL, 'a' }, + { "config", required_argument, NULL, 'c' }, { NULL, 0, NULL, 0} }; int c; pw_init(&argc, &argv); - address = "unix:native"; - - while ((c = getopt_long(argc, argv, "hVa:", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hVc:", long_options, NULL)) != -1) { switch (c) { case 'h': show_help(argv[0]); @@ -83,9 +78,8 @@ int main(int argc, char *argv[]) pw_get_headers_version(), pw_get_library_version()); return 0; - case 'a': - address = optarg; - fprintf(stdout, "set address %s\n", address); + case 'c': + config_name = optarg; break; default: return -1; @@ -93,7 +87,7 @@ int main(int argc, char *argv[]) } properties = pw_properties_new( - PW_KEY_CONFIG_NAME, "pipewire-pulse.conf", + PW_KEY_CONFIG_NAME, config_name, NULL); loop = pw_main_loop_new(&properties->dict); @@ -111,19 +105,10 @@ int main(int argc, char *argv[]) return -1; } - args = spa_aprintf("server.address=\"%s\"", address); - if (pw_context_load_module(context, - "libpipewire-module-protocol-pulse", - args, NULL) == NULL) { - pw_log_error("failed to create pulse module: %m"); - return -1; - } - pw_log_info("start main loop"); pw_main_loop_run(loop); pw_log_info("leave main loop"); - free(args); pw_context_destroy(context); pw_main_loop_destroy(loop); pw_deinit(); diff --git a/src/daemon/pipewire-pulse.conf.in b/src/daemon/pipewire-pulse.conf.in index 19475ad29..f28687b7d 100644 --- a/src/daemon/pipewire-pulse.conf.in +++ b/src/daemon/pipewire-pulse.conf.in @@ -1,6 +1,5 @@ -# Daemon config file for PipeWire pulse version @VERSION@ # - -properties = { +# PulseAudio config file for PipeWire version @VERSION@ # +context.properties = { ## Configure properties in the system. #mem.warn-mlock = false #mem.allow-mlock = true @@ -8,49 +7,30 @@ properties = { #log.level = 2 } -spa-libs = { - ## = - # - # Used to find spa factory names. It maps an spa factory name - # regular expression to a library name that should contain - # that factory. - # +context.spa-libs = { audio.convert* = audioconvert/libspa-audioconvert support.* = support/libspa-support } -modules = { - ## = { [args = { = ... }] - # [flags = [ [ifexists] [nofail] ]} - # - # Loads a module with the given parameters. - # If ifexists is given, the module is ignored when it is not found. - # If nofail is given, module initialization failures are ignored. - # - # Uses RTKit to boost the data thread priority. +context.modules = { libpipewire-module-rtkit = { args = { - nice.level = -14 + #nice.level = -11 #rt.prio = 20 #rt.time.soft = 200000 #rt.time.hard = 200000 } flags = [ ifexists nofail ] } - - # The native communication protocol. libpipewire-module-protocol-native = null - - # Allows creating nodes that run in the context of the - # client. Is used by all clients that want to provide - # data to PipeWire. libpipewire-module-client-node = null - - # Makes a factory for wrapping nodes in an adapter with a - # converter and resampler. libpipewire-module-adapter = null - - # Allows applications to create metadata objects. It creates - # a factory for Metadata objects. libpipewire-module-metadata = null + libpipewire-module-protocol-pulse = { + args = { + server.address = [ + "unix:native" + # "tcp:4713" + } + } } diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in index cf3c06402..29294d168 100644 --- a/src/daemon/pipewire.conf.in +++ b/src/daemon/pipewire.conf.in @@ -1,6 +1,5 @@ # Daemon config file for PipeWire version @VERSION@ # - -properties = { +context.properties = { ## Configure properties in the system. #library.name.system = support/libspa-support #context.data-loop.library.name.system = support/libspa-support @@ -11,6 +10,9 @@ properties = { #mem.mlock-all = false #log.level = 2 + core.daemon = true # listening for socket connections + core.name = pipewire-0 # core name and socket name + ## Properties for the DSP configuration. #default.clock.rate = 48000 #default.clock.quantum = 1024 @@ -22,7 +24,7 @@ properties = { #default.video.rate.denom = 1 } -spa-libs = { +context.spa-libs = { # = # # Used to find spa factory names. It maps an spa factory name @@ -41,7 +43,7 @@ spa-libs = { #audiotestsrc = audiotestsrc/libspa-audiotestsrc } -modules = { +context.modules = { # = { # [ args = { = ... } ] # [ flags = [ [ ifexists ] [ nofail ] ] @@ -130,7 +132,7 @@ modules = { libpipewire-module-session-manager = null } -objects = { +context.objects = { # = { # [ args = { = ... } ] # [ flags = [ [ nofail ] ] @@ -168,7 +170,7 @@ objects = { #} } -exec = { +context.exec = { # = { [ args = "" ] } # # Execute the given program with arguments. @@ -183,5 +185,5 @@ exec = { # It can be interesting to start another daemon here that listens # on another address with the -a option (eg. -a tcp:4713). # - #"@pipewire_pulse_path@" = { "#args" = "-a tcp:4713" } + #"@pipewire_path@" = { args = "-c pipewire-pulse.conf" } } diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index 74622ba11..505380ebf 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -5736,8 +5736,9 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context, { struct impl *impl; const char *str; - int i, n_addr; - char **addr, *free_str = NULL; + char *free_str = NULL; + struct spa_json it[2]; + char value[512]; impl = calloc(1, sizeof(struct impl) + user_data_size); if (impl == NULL) @@ -5747,7 +5748,7 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context, if (props != NULL) str = pw_properties_get(props, "server.address"); if (str == NULL) { - str = free_str = spa_aprintf("%s-%s", + str = free_str = spa_aprintf("[ \"%s-%s\" ]", PW_PROTOCOL_PULSE_DEFAULT_SERVER, get_server_name(context)); } @@ -5775,16 +5776,15 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context, pw_context_add_listener(context, &impl->context_listener, &context_events, impl); - addr = pw_split_strv(str, ",", INT_MAX, &n_addr); - for (i = 0; i < n_addr; i++) { - if (addr[i] == NULL) - continue; - if (create_server(impl, addr[i]) == NULL) { - pw_log_warn(NAME" %p: can't create server for %s: %m", - impl, addr[i]); + spa_json_init(&it[0], str, strlen(str)); + if (spa_json_enter_array(&it[0], &it[1]) > 0) { + while (spa_json_get_string(&it[1], value, sizeof(value)-1) > 0) { + if (create_server(impl, value) == NULL) { + pw_log_warn(NAME" %p: can't create server for %s: %m", + impl, value); + } } } - pw_free_strv(addr); free(free_str); dbus_request_name(context, "org.pulseaudio.Server"); diff --git a/src/pipewire/conf.c b/src/pipewire/conf.c index d9dd9d671..dc88e80dc 100644 --- a/src/pipewire/conf.c +++ b/src/pipewire/conf.c @@ -535,13 +535,13 @@ int pw_context_parse_conf_section(struct pw_context *context, if ((str = pw_properties_get(conf, section)) == NULL) return -ENOENT; - if (strcmp(section, "spa-libs") == 0) + if (strcmp(section, "context.spa-libs") == 0) res = parse_spa_libs(context, str); - else if (strcmp(section, "modules") == 0) + else if (strcmp(section, "context.modules") == 0) res = parse_modules(context, str); - else if (strcmp(section, "objects") == 0) + else if (strcmp(section, "context.objects") == 0) res = parse_objects(context, str); - else if (strcmp(section, "exec") == 0) + else if (strcmp(section, "context.exec") == 0) res = parse_exec(context, str); else res = -EINVAL; diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 09626c096..1f3580519 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -219,8 +219,11 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, this, conf_name, spa_strerror(res)); goto error_free; } else { - pw_log_warn(NAME" %p: can't load config %s: %s. Using client.conf fallback", - this, conf_name, spa_strerror(res)); + pw_log_warn(NAME" %p: can't load config %s%s%s: %s. Using client.conf fallback", + this, + conf_prefix ? conf_prefix : "", + conf_prefix ? "/" : "", + conf_name, spa_strerror(res)); } conf_prefix = NULL; if ((res = pw_conf_load_conf(NULL, "client.conf", conf)) < 0) { @@ -231,7 +234,7 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, } this->conf = conf; - if ((str = pw_properties_get(conf, "properties")) != NULL) + if ((str = pw_properties_get(conf, "context.properties")) != NULL) pw_properties_update_string(properties, str, strlen(str)); if ((str = pw_properties_get(properties, "mem.mlock-all")) != NULL && @@ -329,10 +332,10 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, this->sc_pagesize = sysconf(_SC_PAGESIZE); - pw_context_parse_conf_section(this, conf, "spa-libs"); - pw_context_parse_conf_section(this, conf, "modules"); - pw_context_parse_conf_section(this, conf, "objects"); - pw_context_parse_conf_section(this, conf, "exec"); + pw_context_parse_conf_section(this, conf, "context.spa-libs"); + pw_context_parse_conf_section(this, conf, "context.modules"); + pw_context_parse_conf_section(this, conf, "context.objects"); + pw_context_parse_conf_section(this, conf, "context.exec"); pw_log_debug(NAME" %p: created", this); diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index 9bf4ed7ad..1732e8ea1 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -65,7 +65,6 @@ extern "C" { /* context */ #define PW_KEY_CONTEXT_PROFILE_MODULES "context.profile.modules" /**< a context profile for modules, deprecated */ -#define PW_KEY_CONTEXT_MODULES_ARGS "context.modules.args" /**< arguments for context modules */ #define PW_KEY_USER_NAME "context.user-name" /**< The user name that runs pipewire */ #define PW_KEY_HOST_NAME "context.host-name" /**< The host name of the machine */ diff --git a/src/tools/pw-dump.c b/src/tools/pw-dump.c index 1ccedb6bb..355f4d64b 100644 --- a/src/tools/pw-dump.c +++ b/src/tools/pw-dump.c @@ -530,7 +530,6 @@ static void core_dump(struct object *o) put_value(d, "host-name", i->host_name); put_value(d, "version", i->version); put_value(d, "name", i->name); - put_value(d, "name", i->name); put_flags(d, "change-mask", i->change_mask, fl); put_dict(d, "props", i->props); put_end(d, "}", 0);