diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in index 25c9792d1..72c08029b 100644 --- a/src/daemon/pipewire.conf.in +++ b/src/daemon/pipewire.conf.in @@ -6,6 +6,7 @@ load-module libpipewire-module-spa-monitor v4l2/libspa-v4l2 v4l2-monitor v4l2 load-module libpipewire-module-spa-monitor bluez5/libspa-bluez5 bluez5-monitor bluez5 #load-module libpipewire-module-spa-node videotestsrc/libspa-videotestsrc videotestsrc videotestsrc Spa:POD:Object:Props:patternType=Spa:POD:Object:Props:patternType:snow load-module libpipewire-module-client-node +load-module libpipewire-module-client-device load-module libpipewire-module-access load-module libpipewire-module-audio-dsp load-module libpipewire-module-link-factory diff --git a/src/examples/export-spa-device.c b/src/examples/export-spa-device.c new file mode 100644 index 000000000..4d84157bd --- /dev/null +++ b/src/examples/export-spa-device.c @@ -0,0 +1,143 @@ +/* PipeWire + * + * Copyright © 2019 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#include + +struct data { + struct pw_main_loop *loop; + + struct pw_core *core; + + struct pw_remote *remote; + struct spa_hook remote_listener; + + struct pw_device *device; + const char *library; + const char *factory; + const char *path; +}; + +static int make_device(struct data *data) +{ + struct pw_factory *factory; + struct pw_properties *props; + + factory = pw_core_find_factory(data->core, "spa-device-factory"); + if (factory == NULL) + return -1; + + props = pw_properties_new("spa.library.name", data->library, + "spa.factory.name", data->factory, NULL); + + data->device = pw_factory_create_object(factory, + NULL, + PW_TYPE_INTERFACE_Device, + PW_VERSION_DEVICE_PROXY, + props, SPA_ID_INVALID); + + pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Device, NULL, + pw_device_get_implementation(data->device)); + + return 0; +} + +static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +{ + struct data *data = _data; + + switch (state) { + case PW_REMOTE_STATE_ERROR: + printf("remote error: %s\n", error); + pw_main_loop_quit(data->loop); + break; + + case PW_REMOTE_STATE_CONNECTED: + printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); + if (make_device(data) < 0) { + pw_log_error("can't make device"); + pw_main_loop_quit(data->loop); + } + break; + + default: + printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); + break; + } +} + +static const struct pw_remote_events remote_events = { + PW_VERSION_REMOTE_EVENTS, + .state_changed = on_state_changed, +}; + +static void do_quit(void *data, int signal_number) +{ + struct data *d = data; + pw_main_loop_quit(d->loop); +} + +int main(int argc, char *argv[]) +{ + struct data data = { 0, }; + struct pw_loop *l; + + pw_init(&argc, &argv); + + if (argc < 3) { + fprintf(stderr, "usage: %s \n\n" + "\texample: %s v4l2/libspa-v4l2 v4l2-device\n\n", + argv[0], argv[0]); + return -1; + } + + data.loop = pw_main_loop_new(NULL); + l = pw_main_loop_get_loop(data.loop); + pw_loop_add_signal(l, SIGINT, do_quit, &data); + pw_loop_add_signal(l, SIGTERM, do_quit, &data); + data.core = pw_core_new(l, NULL, 0); + data.remote = pw_remote_new(data.core, NULL, 0); + data.library = argv[1]; + data.factory = argv[2]; + + pw_module_load(data.core, "libpipewire-module-spa-device-factory", NULL, NULL, NULL, NULL); + pw_module_load(data.core, "libpipewire-module-client-device", NULL, NULL, NULL, NULL); + + pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + + pw_remote_connect(data.remote); + + pw_main_loop_run(data.loop); + + pw_core_destroy(data.core); + pw_main_loop_destroy(data.loop); + + return 0; +} diff --git a/src/examples/meson.build b/src/examples/meson.build index 7e841ee20..8dd62c751 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -24,6 +24,13 @@ executable('export-spa', dependencies : [pipewire_dep, mathlib], ) +executable('export-spa-device', + 'export-spa-device.c', + c_args : [ '-D_GNU_SOURCE' ], + install: false, + dependencies : [pipewire_dep, mathlib], +) + executable('media-session', 'media-session.c', c_args : [ '-D_GNU_SOURCE' ],