From 8a959ea7a15db69c82b8f42ba7d70aa0f065b073 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 6 Dec 2019 11:48:40 +0100 Subject: [PATCH] core_proxy: prepare to rename pw_remote -> pw_core_proxy The pw_remote object is really a wrapper around the pw_core_proxy. The events it emits are also available in the core proxy and are generally awkward to use. With some clever new pw_core_proxy_* methods and a pw_core_connect to create the core_proxy, we can convert all code away from pw_remote. This is a first step in this conversion, using the pw_remote behind the scenes. It leaks into some places because it really needs to become its own struct in a next step. --- pipewire-alsa/alsa-plugins/pcm_pipewire.c | 78 ++--- pipewire-jack/src/pipewire-jack.c | 97 ++----- pipewire-pulseaudio/src/context.c | 114 ++++---- pipewire-pulseaudio/src/internal.h | 4 +- pipewire-pulseaudio/src/stream.c | 11 +- src/examples/bluez-session.c | 64 ++--- src/examples/export-sink.c | 72 ++--- src/examples/export-source.c | 44 ++- src/examples/export-spa-device.c | 51 ++-- src/examples/export-spa.c | 52 ++-- src/examples/media-session/media-session.c | 125 +++----- src/examples/video-src.c | 104 +++---- src/gst/gstpipewiredeviceprovider.c | 151 ++++------ src/gst/gstpipewiredeviceprovider.h | 4 +- src/gst/gstpipewiresink.c | 77 +---- src/gst/gstpipewiresink.h | 3 +- src/gst/gstpipewiresrc.c | 71 +---- src/gst/gstpipewiresrc.h | 3 +- src/modules/module-client-device.c | 4 +- .../module-client-device/proxy-device.c | 2 +- src/modules/module-client-node/remote-node.c | 35 ++- src/modules/module-protocol-native.c | 42 +-- src/modules/module-protocol-native/defs.h | 2 + .../module-protocol-native/local-socket.c | 10 +- .../portal-screencast.c | 1 + src/pipewire/filter.c | 202 +++++++------ src/pipewire/filter.h | 4 +- src/pipewire/private.h | 12 +- src/pipewire/protocol.h | 7 +- src/pipewire/remote.c | 104 ++++++- src/pipewire/remote.h | 35 +++ src/pipewire/stream.c | 268 +++++++++--------- src/pipewire/stream.h | 4 +- src/tests/test-stream.c | 10 +- src/tools/pipewire-cli.c | 106 ++++--- src/tools/pipewire-dot.c | 62 ++-- src/tools/pipewire-monitor.c | 69 ++--- 37 files changed, 919 insertions(+), 1185 deletions(-) diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index 9e4a5f489..7cd15c85c 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -70,8 +70,8 @@ typedef struct { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; uint32_t flags; struct pw_stream *stream; @@ -410,7 +410,7 @@ static int snd_pcm_pipewire_prepare(snd_pcm_ioplug_t *io) "Playback" : "Capture"); pw_properties_set(props, PW_KEY_MEDIA_ROLE, "Music"); - pw->stream = pw_stream_new(pw->remote, pw->node_name, props); + pw->stream = pw_stream_new(pw->core_proxy, pw->node_name, props); if (pw->stream == NULL) goto error; @@ -750,66 +750,26 @@ static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw) return 0; } -static void on_remote_state_changed(void *data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { snd_pcm_pipewire_t *pw = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error(NAME" %p: error %s", pw, error); - /* fallthrough */ - case PW_REMOTE_STATE_UNCONNECTED: + pw_log_error(NAME" %p: error id:%u seq:%d res:%d (%s): %s", pw, + id, seq, res, spa_strerror(res), message); + + if (id == 0) { pw->error = true; if (pw->fd != -1) pcm_poll_unblock_check(&pw->io); - /* fallthrough */ - case PW_REMOTE_STATE_CONNECTED: - pw_thread_loop_signal(pw->main_loop, false); - break; - default: - break; - } + } + pw_thread_loop_signal(pw->main_loop, false); } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, +static const struct pw_core_proxy_events core_proxy_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; -static int remote_connect_sync(snd_pcm_pipewire_t *pw) -{ - const char *error = NULL; - enum pw_remote_state state; - int res; - - pw_thread_loop_lock(pw->main_loop); - - if ((res = pw_remote_connect(pw->remote)) < 0) { - error = spa_strerror(res); - goto error; - } - - while (true) { - state = pw_remote_get_state(pw->remote, &error); - if (state == PW_REMOTE_STATE_ERROR) - goto error; - - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - pw_thread_loop_wait(pw->main_loop); - } - exit: - pw_thread_loop_unlock(pw->main_loop); - - return res; - - error: - SNDERR("PipeWire: Unable to connect: %s\n", error); - goto exit; -} - static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, const char *node_name, const char *playback_node, @@ -863,14 +823,18 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, else pw_properties_set(props, PW_KEY_APP_NAME, "ALSA plug-in"); - pw->remote = pw_remote_new(pw->core, props, 0); - pw_remote_add_listener(pw->remote, &pw->remote_listener, &remote_events, pw); - if ((err = pw_thread_loop_start(pw->main_loop)) < 0) goto error; - if ((err = remote_connect_sync(pw)) < 0) + pw_thread_loop_lock(pw->main_loop); + pw->core_proxy = pw_core_connect(pw->core, props, 0); + if (pw->core_proxy == NULL) { + err = -errno; + pw_thread_loop_unlock(pw->main_loop); goto error; + } + pw_core_proxy_add_listener(pw->core_proxy, &pw->core_listener, &core_proxy_events, pw); + pw_thread_loop_unlock(pw->main_loop); pw->fd = spa_system_eventfd_create(pw->loop->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 23e00f182..3d2741991 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -230,11 +230,9 @@ struct client { struct pw_data_loop *loop; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; struct spa_hook core_listener; + struct pw_mempool *pool; int last_sync; bool error; @@ -536,35 +534,6 @@ jack_get_version_string(void) return "0.0.0.0"; } -static void on_state_changed(void *data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) -{ - struct client *client = data; - - pw_log_debug(NAME" %p: state %s", client, pw_remote_state_as_string(state)); - switch (state) { - case PW_REMOTE_STATE_ERROR: - client->error = true; - /* fallthrough*/ - case PW_REMOTE_STATE_UNCONNECTED: - /* don't call shutdown when we do client_close, only - * on unexpected errors */ - if (client->shutdown_callback && !client->destroyed) - client->shutdown_callback(client->shutdown_arg); - /* fallthrough*/ - case PW_REMOTE_STATE_CONNECTED: - pw_thread_loop_signal(client->context.loop, false); - break; - default: - break; - } -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, -}; - static void on_sync_reply(void *data, uint32_t id, int seq) { struct client *client = data; @@ -574,9 +543,26 @@ static void on_sync_reply(void *data, uint32_t id, int seq) pw_thread_loop_signal(client->context.loop, false); } + +static void on_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + struct client *client = data; + + pw_log_error(NAME" %p: error id:%u seq:%d res:%d (%s): %s", client, + id, seq, res, spa_strerror(res), message); + + if (id == 0) { + client->error = true; + if (client->shutdown_callback && !client->destroyed) + client->shutdown_callback(client->shutdown_arg); + } + pw_thread_loop_signal(client->context.loop, false); +} + static const struct pw_core_proxy_events core_events = { - PW_VERSION_CORE_EVENTS, + PW_VERSION_CORE_PROXY_EVENTS, .done = on_sync_reply, + .error = on_error, }; static int do_sync(struct client *client) @@ -1108,7 +1094,7 @@ static int client_node_transport(void *object, clean_transport(c); - c->mem = pw_mempool_map_id(c->remote->pool, mem_id, + c->mem = pw_mempool_map_id(c->pool, mem_id, PW_MEMMAP_FLAG_READWRITE, offset, size, NULL); if (c->mem == NULL) { pw_log_debug(NAME" %p: can't map activation: %m", c); @@ -1160,7 +1146,7 @@ static int client_node_set_io(void *object, void *ptr; uint32_t tag[5] = { c->node_id, id, }; - if ((mm = pw_mempool_find_tag(c->remote->pool, tag, sizeof(tag))) != NULL) + if ((mm = pw_mempool_find_tag(c->pool, tag, sizeof(tag))) != NULL) pw_memmap_free(mm); if (mem_id == SPA_ID_INVALID) { @@ -1168,7 +1154,7 @@ static int client_node_set_io(void *object, size = 0; } else { - mm = pw_mempool_map_id(c->remote->pool, mem_id, + mm = pw_mempool_map_id(c->pool, mem_id, PW_MEMMAP_FLAG_READWRITE, offset, size, tag); if (mm == NULL) { pw_log_warn(NAME" %p: can't map memory id %u", c, mem_id); @@ -1549,7 +1535,7 @@ static int client_node_port_use_buffers(void *object, struct spa_buffer *buf; struct pw_memmap *mm; - mm = pw_mempool_map_id(c->remote->pool, buffers[i].mem_id, + mm = pw_mempool_map_id(c->pool, buffers[i].mem_id, fl, buffers[i].offset, buffers[i].size, NULL); if (mm == NULL) { pw_log_warn(NAME" %p: can't map memory id %u: %m", c, buffers[i].mem_id); @@ -1589,7 +1575,7 @@ static int client_node_port_use_buffers(void *object, struct pw_memblock *bm; struct pw_memmap *bmm; - bm = pw_mempool_find_id(c->remote->pool, mem_id); + bm = pw_mempool_find_id(c->pool, mem_id); if (bm == NULL) { pw_log_error(NAME" %p: unknown buffer mem %u", c, mem_id); res = -ENODEV; @@ -1667,7 +1653,7 @@ static int client_node_port_set_io(void *object, goto exit; } - if ((mm = pw_mempool_find_tag(c->remote->pool, tag, sizeof(tag))) != NULL) + if ((mm = pw_mempool_find_tag(c->pool, tag, sizeof(tag))) != NULL) pw_memmap_free(mm); if (mem_id == SPA_ID_INVALID) { @@ -1675,7 +1661,7 @@ static int client_node_port_set_io(void *object, size = 0; } else { - mm = pw_mempool_map_id(c->remote->pool, mem_id, + mm = pw_mempool_map_id(c->pool, mem_id, PW_MEMMAP_FLAG_READWRITE, offset, size, tag); if (mm == NULL) { pw_log_warn(NAME" %p: can't map memory id %u", c, mem_id); @@ -1727,7 +1713,7 @@ static int client_node_set_activation(void *object, size = 0; } else { - mm = pw_mempool_map_id(c->remote->pool, mem_id, + mm = pw_mempool_map_id(c->pool, mem_id, PW_MEMMAP_FLAG_READWRITE, offset, size, NULL); if (mm == NULL) { pw_log_warn(NAME" %p: can't map memory id %u", c, mem_id); @@ -2094,7 +2080,6 @@ jack_client_t * jack_client_open (const char *client_name, jack_status_t *status, ...) { struct client *client; - bool busy = true; struct spa_dict props; struct spa_dict_item items[6]; const struct spa_support *support; @@ -2156,37 +2141,18 @@ jack_client_t * jack_client_open (const char *client_name, pw_thread_loop_start(client->context.loop); pw_thread_loop_lock(client->context.loop); - client->remote = pw_remote_new(client->context.core, + + client->core_proxy = pw_core_connect(client->context.core, pw_properties_new( PW_KEY_CLIENT_NAME, client_name, PW_KEY_CLIENT_API, "jack", NULL), 0); - - pw_remote_add_listener(client->remote, &client->remote_listener, &remote_events, client); - - if (pw_remote_connect(client->remote) < 0) + if (client->core_proxy == NULL) goto server_failed; - while (busy) { - const char *error = NULL; + client->pool = pw_core_proxy_get_mempool(client->core_proxy); - switch (pw_remote_get_state(client->remote, &error)) { - case PW_REMOTE_STATE_ERROR: - goto server_failed; - - case PW_REMOTE_STATE_CONNECTED: - busy = false; - break; - - default: - break; - } - if (busy) - pw_thread_loop_wait(client->context.loop); - - } - client->core_proxy = pw_remote_get_core_proxy(client->remote); pw_core_proxy_add_listener(client->core_proxy, &client->core_listener, &core_events, client); @@ -2196,7 +2162,6 @@ jack_client_t * jack_client_open (const char *client_name, &client->registry_listener, ®istry_events, client); - props = SPA_DICT_INIT(items, 0); items[props.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_NAME, client_name); items[props.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_TYPE, "Audio"); diff --git a/pipewire-pulseaudio/src/context.c b/pipewire-pulseaudio/src/context.c index 9784141d4..c1895e0df 100644 --- a/pipewire-pulseaudio/src/context.c +++ b/pipewire-pulseaudio/src/context.c @@ -19,6 +19,7 @@ #include +#include #include #include @@ -808,7 +809,32 @@ static void complete_operations(pa_context *c, int seq) static void core_info(void *data, const struct pw_core_info *info) { pa_context *c = data; + bool first = c->core_info == NULL; + + pw_log_debug("context %p: info", c); + + if (first) { + pa_context_set_state(c, PA_CONTEXT_AUTHORIZING); + pa_context_set_state(c, PA_CONTEXT_SETTING_NAME); + } + c->core_info = pw_core_info_update(c->core_info, info); + + if (first) + pa_context_set_state(c, PA_CONTEXT_READY); +} + +static void core_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + pa_context *c = data; + + pw_log_error("context %p: error id:%u seq:%d res:%d (%s): %s", c, + id, seq, res, spa_strerror(res), message); + + if (id == 0) { + if (!c->disconnect) + context_fail(c, PA_ERR_CONNECTIONTERMINATED); + } } static void core_done(void *data, uint32_t id, int seq) @@ -819,50 +845,10 @@ static void core_done(void *data, uint32_t id, int seq) } static const struct pw_core_proxy_events core_events = { - PW_VERSION_CORE_EVENTS, + PW_VERSION_CORE_PROXY_EVENTS, .info = core_info, - .done = core_done -}; - -static void remote_state_changed(void *data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) -{ - pa_context *c = data; - - switch(state) { - case PW_REMOTE_STATE_ERROR: - if (c->core_proxy) { - spa_hook_remove(&c->core_listener); - c->core_proxy = NULL; - } - context_fail(c, PA_ERR_CONNECTIONTERMINATED); - break; - case PW_REMOTE_STATE_UNCONNECTED: - if (c->core_proxy) { - spa_hook_remove(&c->core_listener); - c->core_proxy = NULL; - } - if (!c->disconnect) - context_fail(c, PA_ERR_CONNECTIONTERMINATED); - break; - case PW_REMOTE_STATE_CONNECTING: - pa_context_set_state(c, PA_CONTEXT_CONNECTING); - break; - case PW_REMOTE_STATE_CONNECTED: - pa_context_set_state(c, PA_CONTEXT_AUTHORIZING); - pa_context_set_state(c, PA_CONTEXT_SETTING_NAME); - - c->core_proxy = pw_remote_get_core_proxy(c->remote); - pw_core_proxy_add_listener(c->core_proxy, &c->core_listener, &core_events, c); - - pa_context_set_state(c, PA_CONTEXT_READY); - break; - } -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = remote_state_changed, + .done = core_done, + .error = core_error }; struct success_data { @@ -916,7 +902,6 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * { struct pw_core *core; struct pw_loop *loop; - struct pw_remote *r; struct pw_properties *props; pa_context *c; @@ -930,19 +915,14 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * pw_properties_update(props, &p->props->dict); loop = mainloop->userdata; - core = pw_core_new(loop, NULL, 0); - - r = pw_remote_new(core, props, sizeof(struct pa_context)); - if (r == NULL) + core = pw_core_new(loop, NULL, sizeof(struct pa_context)); + if (core == NULL) return NULL; - c = pw_remote_get_user_data(r); + c = pw_core_get_user_data(core); + c->props = props; c->loop = loop; c->core = core; - c->remote = r; - - pw_remote_add_listener(r, &c->remote_listener, &remote_events, c); - c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new(); c->refcount = 1; c->client_index = PA_INVALID_INDEX; @@ -974,6 +954,7 @@ static void context_free(pa_context *c) context_unlink(c); + pw_properties_free(c->props); if (c->proplist) pa_proplist_free(c->proplist); if (c->core_info) @@ -1060,7 +1041,7 @@ pa_context_state_t pa_context_get_state(PA_CONST pa_context *c) SPA_EXPORT int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api) { - int res; + int res = 0; pa_assert(c); pa_assert(c->refcount >= 1); @@ -1073,7 +1054,14 @@ int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t fla c->no_fail = !!(flags & PA_CONTEXT_NOFAIL); - res = pw_remote_connect(c->remote); + pa_context_set_state(c, PA_CONTEXT_CONNECTING); + + c->core_proxy = pw_core_connect(c->core, pw_properties_copy(c->props), 0); + if (c->core_proxy == NULL) { + context_fail(c, PA_ERR_CONNECTIONREFUSED); + res = -1; + } + pw_core_proxy_add_listener(c->core_proxy, &c->core_listener, &core_events, c); pa_context_unref(c); @@ -1087,8 +1075,10 @@ void pa_context_disconnect(pa_context *c) pa_assert(c->refcount >= 1); c->disconnect = true; - pw_remote_disconnect(c->remote); - + if (c->core_proxy) { + pw_core_proxy_disconnect(c->core_proxy); + c->core_proxy = NULL; + } if (PA_CONTEXT_IS_GOOD(c->state)) pa_context_set_state(c, PA_CONTEXT_TERMINATED); } @@ -1191,6 +1181,7 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su struct spa_dict_item items[1]; pa_operation *o; struct success_data *d; + int changed; pa_assert(c); pa_assert(c->refcount >= 1); @@ -1200,7 +1191,14 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su items[0] = SPA_DICT_ITEM_INIT(PA_PROP_APPLICATION_NAME, name); dict = SPA_DICT_INIT(items, 1); - pw_remote_update_properties(c->remote, &dict); + changed = pw_properties_update(c->props, &dict); + + if (changed) { + struct pw_client_proxy *client_proxy; + + client_proxy = pw_core_proxy_get_client_proxy(c->core_proxy); + pw_client_proxy_update_properties(client_proxy, &c->props->dict); + } o = pa_operation_new(c, NULL, on_success, sizeof(struct success_data)); d = o->userdata; diff --git a/pipewire-pulseaudio/src/internal.h b/pipewire-pulseaudio/src/internal.h index c9feb26a4..5fb4f9ab9 100644 --- a/pipewire-pulseaudio/src/internal.h +++ b/pipewire-pulseaudio/src/internal.h @@ -283,8 +283,8 @@ struct pa_context { struct pw_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + + struct pw_properties *props; struct pw_core_proxy *core_proxy; struct spa_hook core_listener; diff --git a/pipewire-pulseaudio/src/stream.c b/pipewire-pulseaudio/src/stream.c index f5207fc56..a3e26450c 100644 --- a/pipewire-pulseaudio/src/stream.c +++ b/pipewire-pulseaudio/src/stream.c @@ -554,13 +554,10 @@ static pa_stream* stream_new(pa_context *c, const char *name, NULL); pw_properties_update(props, &s->proplist->props->dict); - s->stream = pw_stream_new(c->remote, name, props); s->refcount = 1; s->context = c; spa_list_init(&s->pending); - pw_stream_add_listener(s->stream, &s->stream_listener, &stream_events, s); - s->endpoint_id = SPA_ID_INVALID; s->direction = PA_STREAM_NODIRECTION; s->state = PA_STREAM_UNCONNECTED; @@ -858,12 +855,20 @@ static int create_stream(pa_stream_direction_t direction, struct spa_dict_item items[5]; char latency[64]; bool monitor; + const char *name; + pa_context *c = s->context; spa_assert(s); spa_assert(s->refcount >= 1); pw_log_debug("stream %p: connect %s %08x", s, dev, flags); + name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME); + + s->stream = pw_stream_new(c->core_proxy, + name, pw_properties_copy(c->props)); + pw_stream_add_listener(s->stream, &s->stream_listener, &stream_events, s); + s->direction = direction; s->timing_info_valid = false; s->disconnecting = false; diff --git a/src/examples/bluez-session.c b/src/examples/bluez-session.c index cee7c4c22..97de28bae 100644 --- a/src/examples/bluez-session.c +++ b/src/examples/bluez-session.c @@ -75,8 +75,8 @@ struct impl { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct spa_handle *handle; struct spa_device *device; @@ -140,7 +140,7 @@ static struct node *create_node(struct object *obj, uint32_t id, node->id = id; node->handle = handle; node->node = iface; - node->proxy = pw_remote_export(impl->remote, + node->proxy = pw_core_proxy_export(impl->core_proxy, info->type, pw_properties_new_dict(info->props), node->node, 0); if (node->proxy == NULL) goto clean_node; @@ -248,7 +248,7 @@ static struct object *create_object(struct impl *impl, uint32_t id, obj->id = id; obj->handle = handle; obj->device = iface; - obj->proxy = pw_remote_export(impl->remote, + obj->proxy = pw_core_proxy_export(impl->core_proxy, info->type, pw_properties_new_dict(info->props), obj->device, 0); if (obj->proxy == NULL) goto clean_object; @@ -338,50 +338,32 @@ static int start_monitor(struct impl *impl) return res; } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct impl *impl = _data; - int res; + struct impl *impl = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error(NAME" %p: remote error: %s", impl, error); + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + + if (id == 0) { pw_main_loop_quit(impl->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - pw_log_info(NAME" %p: connected", impl); - if ((res = start_monitor(impl)) < 0) { - pw_log_debug("error starting monitor: %s", spa_strerror(res)); - pw_main_loop_quit(impl->loop); - } - break; - - case PW_REMOTE_STATE_UNCONNECTED: - pw_log_info(NAME" %p: disconnected", impl); - pw_main_loop_quit(impl->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 const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; int main(int argc, char *argv[]) { struct impl impl = { 0, }; + int res; pw_init(&argc, &argv); impl.loop = pw_main_loop_new(NULL); impl.core = pw_core_new(pw_main_loop_get_loop(impl.loop), NULL, 0); - impl.remote = pw_remote_new(impl.core, NULL, 0); pw_core_add_spa_lib(impl.core, "api.bluez5.*", "bluez5/libspa-bluez5"); @@ -389,12 +371,20 @@ int main(int argc, char *argv[]) spa_list_init(&impl.device_list); - pw_remote_add_listener(impl.remote, - &impl.remote_listener, - &remote_events, &impl); - - if (pw_remote_connect(impl.remote) < 0) + impl.core_proxy = pw_core_connect(impl.core, NULL, 0); + if (impl.core_proxy == NULL) { + pw_log_error(NAME" %p: can't connect %m", &impl); return -1; + } + + pw_core_proxy_add_listener(impl.core_proxy, + &impl.core_listener, + &core_events, &impl); + + if ((res = start_monitor(&impl)) < 0) { + pw_log_error(NAME" %p: error starting monitor: %s", &impl, spa_strerror(res)); + return -1; + } pw_main_loop_run(impl.loop); diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c index d2e626d67..7cd8c6b97 100644 --- a/src/examples/export-sink.c +++ b/src/examples/export-sink.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -70,8 +71,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct spa_node impl_node; struct spa_hook_list hooks; @@ -473,47 +474,41 @@ static void make_node(struct data *data) SPA_TYPE_INTERFACE_Node, SPA_VERSION_NODE, &impl_node, data); - pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); + pw_core_proxy_export(data->core_proxy, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void set_permissions(struct data *data) { - struct data *data = _data; + struct pw_permission permissions[2]; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; + /* an example, set specific permissions on one object, this is the + * core object. */ + permissions[0].id = 0; + permissions[0].permissions = PW_PERM_R | PW_PERM_X; + /* remove WX from all other objects */ + permissions[1].id = SPA_ID_INVALID; + permissions[1].permissions = PW_PERM_R; - case PW_REMOTE_STATE_CONNECTED: - { - struct pw_permission permissions[2]; + pw_client_proxy_update_permissions( + pw_core_proxy_get_client_proxy(data->core_proxy), + 2, permissions); +} - /* an example, set specific permissions on one object, this is the - * core object. */ - permissions[0].id = 0; - permissions[0].permissions = PW_PERM_R | PW_PERM_X; - /* remove WX from all other objects */ - permissions[1].id = SPA_ID_INVALID; - permissions[1].permissions = PW_PERM_R; +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + struct data *d = data; - pw_client_proxy_update_permissions( - pw_remote_get_client_proxy(data->remote), - 2, permissions); + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - make_node(data); - break; - } - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + if (id == 0) { + pw_main_loop_quit(d->loop); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; int main(int argc, char *argv[]) @@ -524,7 +519,6 @@ int main(int argc, char *argv[]) data.loop = pw_main_loop_new(NULL); data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); data.path = argc > 1 ? argv[1] : NULL; spa_hook_list_init(&data.hooks); @@ -554,10 +548,16 @@ int main(int argc, char *argv[]) return -1; } - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); - - if (pw_remote_connect(data.remote) < 0) + data.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) { + printf("can't connect: %m\n"); return -1; + } + pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data); + + set_permissions(&data); + + make_node(&data); pw_main_loop_run(data.loop); diff --git a/src/examples/export-source.c b/src/examples/export-source.c index e4c426b09..ad19a8046 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -55,8 +56,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; uint64_t info_all; struct spa_port_info info; @@ -481,33 +482,24 @@ static void make_node(struct data *data) SPA_TYPE_INTERFACE_Node, SPA_VERSION_NODE, &impl_node, data); - pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); + pw_core_proxy_export(data->core_proxy, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); } -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; + struct data *d = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - case PW_REMOTE_STATE_CONNECTED: - make_node(data); - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + if (id == 0) { + pw_main_loop_quit(d->loop); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; int main(int argc, char *argv[]) @@ -518,7 +510,6 @@ int main(int argc, char *argv[]) data.loop = pw_main_loop_new(NULL); data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); data.path = argc > 1 ? argv[1] : NULL; data.info_all = SPA_PORT_CHANGE_MASK_FLAGS | @@ -540,9 +531,14 @@ int main(int argc, char *argv[]) spa_list_init(&data.empty); spa_hook_list_init(&data.hooks); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + if ((data.core_proxy = pw_core_connect(data.core, NULL, 0)) == NULL) { + printf("can't connect: %m\n"); + return -1; + } - pw_remote_connect(data.remote); + pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data); + + make_node(&data); pw_main_loop_run(data.loop); diff --git a/src/examples/export-spa-device.c b/src/examples/export-spa-device.c index a9571009d..04ee2fdf5 100644 --- a/src/examples/export-spa-device.c +++ b/src/examples/export-spa-device.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -36,8 +37,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct pw_device *device; const char *library; @@ -63,39 +64,27 @@ static int make_device(struct data *data) PW_VERSION_DEVICE_PROXY, props, SPA_ID_INVALID); - pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Device, NULL, + pw_core_proxy_export(data->core_proxy, SPA_TYPE_INTERFACE_Device, NULL, pw_device_get_implementation(data->device), 0); return 0; } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; + struct data *d = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - 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; + if (id == 0) { + pw_main_loop_quit(d->loop); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -123,15 +112,23 @@ int main(int argc, char *argv[]) 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); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + data.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) { + pw_log_error("can't connect %m"); + return -1; + } - pw_remote_connect(data.remote); + pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data); + + if (make_device(&data) < 0) { + pw_log_error("can't make device"); + return -1; + } pw_main_loop_run(data.loop); diff --git a/src/examples/export-spa.c b/src/examples/export-spa.c index 7aef757f6..18881e40b 100644 --- a/src/examples/export-spa.c +++ b/src/examples/export-spa.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -36,8 +37,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct pw_node *node; const char *library; @@ -91,7 +92,7 @@ static int make_node(struct data *data) pw_node_set_active(data->node, true); - data->proxy = pw_remote_export(data->remote, PW_TYPE_INTERFACE_Node, NULL, data->node, 0); + data->proxy = pw_core_proxy_export(data->core_proxy, PW_TYPE_INTERFACE_Node, NULL, data->node, 0); if (data->proxy == NULL) return -errno; @@ -101,33 +102,21 @@ static int make_node(struct data *data) return 0; } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; + struct data *d = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - case PW_REMOTE_STATE_CONNECTED: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - if (make_node(data) < 0) { - pw_log_error("can't make node"); - pw_main_loop_quit(data->loop); - } - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + if (id == 0) { + pw_main_loop_quit(d->loop); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -155,7 +144,6 @@ int main(int argc, char *argv[]) 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]; if (argc > 3) @@ -163,9 +151,19 @@ int main(int argc, char *argv[]) pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + data.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) { + printf("can't connect: %m\n"); + return -1; + } + pw_core_proxy_add_listener(data.core_proxy, + &data.core_listener, + &core_events, &data); - pw_remote_connect(data.remote); + if (make_node(&data) < 0) { + pw_log_error("can't make node"); + return -1; + } pw_main_loop_run(data.loop); diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index a360d2e4c..88dcdab9a 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -91,14 +91,11 @@ struct impl { struct pw_main_loop *loop; struct spa_dbus *dbus; - struct pw_remote *monitor_remote; - struct spa_hook monitor_listener; struct pw_core_proxy *monitor_core; + struct spa_hook monitor_listener; - struct pw_remote *policy_remote; - struct spa_hook policy_listener; struct pw_core_proxy *policy_core; - struct spa_hook core_listener; + struct spa_hook policy_listener; struct pw_registry_proxy *registry_proxy; struct spa_hook registry_listener; @@ -1216,7 +1213,7 @@ struct pw_proxy *sm_media_session_export(struct sm_media_session *sess, void *object, size_t user_data_size) { struct impl *impl = SPA_CONTAINER_OF(sess, struct impl, this); - return pw_remote_export(impl->monitor_remote, type, + return pw_core_proxy_export(impl->monitor_core, type, properties, object, user_data_size); } @@ -1229,7 +1226,7 @@ struct sm_device *sm_media_session_export_device(struct sm_media_session *sess, pw_log_debug(NAME " %p: device %p", impl, object); - proxy = pw_remote_export(impl->monitor_remote, SPA_TYPE_INTERFACE_Device, + proxy = pw_core_proxy_export(impl->monitor_core, SPA_TYPE_INTERFACE_Device, properties, object, sizeof(struct sm_device)); device = (struct sm_device *) create_object(impl, proxy, &properties->dict); @@ -1526,6 +1523,12 @@ static const struct pw_proxy_events client_session_proxy_events = { static int start_session(struct impl *impl) { + impl->monitor_core = pw_core_connect(impl->this.core, NULL, 0); + if (impl->monitor_core == NULL) { + pw_log_error("can't start monitor: %m"); + return -errno; + } + impl->client_session = pw_core_proxy_create_object(impl->monitor_core, "client-session", PW_TYPE_INTERFACE_ClientSession, @@ -1543,11 +1546,6 @@ static int start_session(struct impl *impl) return 0; } -static int start_policy(struct impl *impl) -{ - return sm_policy_ep_start(&impl->this); -} - static void core_done(void *data, uint32_t id, int seq) { struct impl *impl = data; @@ -1567,91 +1565,50 @@ static void core_done(void *data, uint32_t id, int seq) } } -static void on_monitor_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct impl *impl = _data; + struct impl *impl = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error(NAME" %p: remote error: %s", impl, error); + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + + if (id == 0) { pw_main_loop_quit(impl->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - pw_log_info(NAME" %p: connected", impl); - impl->monitor_core = pw_remote_get_core_proxy(impl->monitor_remote); - start_session(impl); - break; - - case PW_REMOTE_STATE_UNCONNECTED: - pw_log_info(NAME" %p: disconnected", impl); - pw_main_loop_quit(impl->loop); - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; } } -static const struct pw_remote_events monitor_remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_monitor_state_changed, -}; static const struct pw_core_proxy_events core_events = { PW_VERSION_CORE_EVENTS, - .done = core_done + .done = core_done, + .error = core_error }; -static void on_policy_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static int start_policy(struct impl *impl) { - struct impl *impl = _data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error(NAME" %p: remote error: %s", impl, error); - pw_main_loop_quit(impl->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - pw_log_info(NAME" %p: connected", impl); - impl->policy_core = pw_remote_get_core_proxy(impl->policy_remote); - pw_core_proxy_add_listener(impl->policy_core, - &impl->core_listener, - &core_events, impl); - impl->registry_proxy = pw_core_proxy_get_registry(impl->policy_core, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(impl->registry_proxy, - &impl->registry_listener, - ®istry_events, impl); - start_policy(impl); - break; - - case PW_REMOTE_STATE_UNCONNECTED: - pw_log_info(NAME" %p: disconnected", impl); - pw_main_loop_quit(impl->loop); - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + impl->policy_core = pw_core_connect(impl->this.core, NULL, 0); + if (impl->policy_core == NULL) { + pw_log_error("can't start policy: %m"); + return -errno; } -} -static const struct pw_remote_events policy_remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_policy_state_changed, -}; + pw_core_proxy_add_listener(impl->policy_core, + &impl->policy_listener, + &core_events, impl); + impl->registry_proxy = pw_core_proxy_get_registry(impl->policy_core, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(impl->registry_proxy, + &impl->registry_listener, + ®istry_events, impl); + + return sm_policy_ep_start(&impl->this); +} int main(int argc, char *argv[]) { struct impl impl = { 0, }; const struct spa_support *support; uint32_t n_support; - int res; pw_init(&argc, &argv); @@ -1663,12 +1620,6 @@ int main(int argc, char *argv[]) pw_core_add_spa_lib(impl.this.core, "api.alsa.*", "alsa/libspa-alsa"); pw_core_add_spa_lib(impl.this.core, "api.v4l2.*", "v4l2/libspa-v4l2"); - impl.monitor_remote = pw_remote_new(impl.this.core, NULL, 0); - pw_remote_add_listener(impl.monitor_remote, &impl.monitor_listener, &monitor_remote_events, &impl); - - impl.policy_remote = pw_remote_new(impl.this.core, NULL, 0); - pw_remote_add_listener(impl.policy_remote, &impl.policy_listener, &policy_remote_events, &impl); - pw_map_init(&impl.globals, 64, 64); spa_list_init(&impl.global_list); pw_map_init(&impl.endpoint_links, 64, 64); @@ -1686,10 +1637,10 @@ int main(int argc, char *argv[]) else pw_log_debug("got dbus connection %p", impl.this.dbus_connection); - if ((res = pw_remote_connect(impl.monitor_remote)) < 0) - return res; - if ((res = pw_remote_connect(impl.policy_remote)) < 0) - return res; + if (start_session(&impl) < 0) + return -1; + if (start_policy(&impl) < 0) + return -1; pw_main_loop_run(impl.loop); diff --git a/src/examples/video-src.c b/src/examples/video-src.c index 35a818544..e491b467b 100644 --- a/src/examples/video-src.c +++ b/src/examples/video-src.c @@ -47,8 +47,7 @@ struct data { struct spa_source *timer; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; struct pw_stream *stream; struct spa_hook stream_listener; @@ -186,6 +185,11 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum printf("stream state: \"%s\"\n", pw_stream_state_as_string(state)); switch (state) { + case PW_STREAM_STATE_ERROR: + case PW_STREAM_STATE_UNCONNECTED: + pw_main_loop_quit(data->loop); + break; + case PW_STREAM_STATE_PAUSED: printf("node id: %d\n", pw_stream_get_node_id(data->stream)); break; @@ -266,81 +270,51 @@ static const struct pw_stream_events stream_events = { .param_changed = on_stream_param_changed, }; -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) -{ - struct data *data = _data; - struct pw_remote *remote = data->remote; - - 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: - { - const struct spa_pod *params[1]; - uint8_t buffer[1024]; - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - - printf("remote state: \"%s\"\n", - pw_remote_state_as_string(state)); - - data->stream = pw_stream_new(remote, "video-src", - pw_properties_new( - PW_KEY_MEDIA_CLASS, "Video/Source", - NULL)); - - params[0] = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, - SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGB), - SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle( - &SPA_RECTANGLE(320, 240), - &SPA_RECTANGLE(1, 1), - &SPA_RECTANGLE(4096, 4096)), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION(25, 1))); - - pw_stream_add_listener(data->stream, - &data->stream_listener, - &stream_events, - data); - - pw_stream_connect(data->stream, - PW_DIRECTION_OUTPUT, - SPA_ID_INVALID, - PW_STREAM_FLAG_DRIVER | - PW_STREAM_FLAG_MAP_BUFFERS, - params, 1); - 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, -}; - int main(int argc, char *argv[]) { struct data data = { 0, }; + const struct spa_pod *params[1]; + uint8_t buffer[1024]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); pw_init(&argc, &argv); data.loop = pw_main_loop_new(NULL); data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); data.timer = pw_loop_add_timer(pw_main_loop_get_loop(data.loop), on_timeout, &data); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + data.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) + return -1; - pw_remote_connect(data.remote); + data.stream = pw_stream_new(data.core_proxy, "video-src", + pw_properties_new( + PW_KEY_MEDIA_CLASS, "Video/Source", + NULL)); + + params[0] = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGB), + SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle( + &SPA_RECTANGLE(320, 240), + &SPA_RECTANGLE(1, 1), + &SPA_RECTANGLE(4096, 4096)), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION(25, 1))); + + pw_stream_add_listener(data.stream, + &data.stream_listener, + &stream_events, + &data); + + pw_stream_connect(data.stream, + PW_DIRECTION_OUTPUT, + SPA_ID_INVALID, + PW_STREAM_FLAG_DRIVER | + PW_STREAM_FLAG_MAP_BUFFERS, + params, 1); pw_main_loop_run(data.loop); diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 8283a805f..83acd6ba2 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -28,6 +28,8 @@ #include +#include + #include #include "gstpipewireformat.h" @@ -167,7 +169,7 @@ struct pending { void *data; }; -struct remote_data { +struct core_data { int seq; GstPipeWireDeviceProvider *self; struct spa_hook core_listener; @@ -200,7 +202,7 @@ struct port_data { struct pending pending; }; -static struct node_data *find_node_data(struct remote_data *rd, uint32_t id) +static struct node_data *find_node_data(struct core_data *rd, uint32_t id) { struct node_data *n; spa_list_for_each(n, &rd->nodes, link) { @@ -343,36 +345,28 @@ on_core_done (void *data, uint32_t id, int seq) } } + +static void +on_core_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + GstPipeWireDeviceProvider *self = data; + + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + + if (id == 0) { + self->error = res; + } + pw_thread_loop_signal(self->main_loop, FALSE); +} + static const struct pw_core_proxy_events core_events = { PW_VERSION_CORE_EVENTS, .info = on_core_info, .done = on_core_done, + .error = on_core_error, }; -static void -on_state_changed (void *data, enum pw_remote_state old, enum pw_remote_state state, const char *error) -{ - struct remote_data *rd = data; - GstPipeWireDeviceProvider *self = rd->self; - - GST_DEBUG ("got remote state %d", state); - - switch (state) { - case PW_REMOTE_STATE_CONNECTING: - case PW_REMOTE_STATE_UNCONNECTED: - break; - case PW_REMOTE_STATE_CONNECTED: - self->core_proxy = pw_remote_get_core_proxy(self->remote); - pw_core_proxy_add_listener(self->core_proxy, &rd->core_listener, &core_events, self); - break; - case PW_REMOTE_STATE_ERROR: - GST_ERROR_OBJECT (self, "remote error: %s", error); - break; - } - if (self->main_loop) - pw_thread_loop_signal (self->main_loop, FALSE); -} - static void port_event_info(void *data, const struct pw_port_info *info) { struct port_data *port_data = data; @@ -456,7 +450,7 @@ static void registry_event_global(void *data, uint32_t id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props) { - struct remote_data *rd = data; + struct core_data *rd = data; GstPipeWireDeviceProvider *self = rd->self; struct node_data *nd; @@ -525,62 +519,34 @@ static const struct pw_registry_proxy_events registry_events = { .global_remove = registry_event_global_remove, }; -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, -}; - - static GList * gst_pipewire_device_provider_probe (GstDeviceProvider * provider) { GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider); struct pw_loop *l = NULL; struct pw_core *c = NULL; - struct pw_remote *r = NULL; - struct remote_data *data; - struct spa_hook listener; + struct core_data *data; GST_DEBUG_OBJECT (self, "starting probe"); if (!(l = pw_loop_new (NULL))) return NULL; - if (!(c = pw_core_new (l, NULL, 0))) + if (!(c = pw_core_new (l, NULL, sizeof(*data)))) return NULL; - if (!(r = pw_remote_new (c, NULL, sizeof(*data)))) - goto failed; - - data = pw_remote_get_user_data(r); + data = pw_core_get_user_data(c); data->self = self; spa_list_init(&data->nodes); spa_list_init(&data->ports); spa_list_init(&self->pending); - pw_remote_add_listener(r, &listener, &remote_events, data); - - if (pw_remote_connect (r) < 0) + self->core_proxy = pw_core_connect (c, NULL, 0); + if (self->core_proxy == NULL) goto failed; - for (;;) { - enum pw_remote_state state; - const char *error = NULL; - - state = pw_remote_get_state(r, &error); - - if (state <= 0) { - GST_ERROR_OBJECT (self, "Failed to connect: %s", error); - goto failed; - } - - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - /* Wait until something happens */ - pw_loop_iterate (l, -1); - } GST_DEBUG_OBJECT (self, "connected"); + pw_core_proxy_add_listener(self->core_proxy, &data->core_listener, &core_events, self); self->end = FALSE; self->list_only = TRUE; @@ -588,18 +554,19 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider) data->registry = pw_core_proxy_get_registry(self->core_proxy, PW_VERSION_REGISTRY_PROXY, 0); pw_registry_proxy_add_listener(data->registry, &data->registry_listener, ®istry_events, data); + pw_core_proxy_sync(self->core_proxy, 0, self->seq++); for (;;) { - if (pw_remote_get_state(r, NULL) <= 0) + if (self->error < 0) break; if (self->end) break; pw_loop_iterate (l, -1); } - pw_remote_disconnect (r); - pw_remote_destroy (r); + GST_DEBUG_OBJECT (self, "disconnect"); + pw_core_proxy_disconnect (self->core_proxy); pw_core_destroy (c); pw_loop_destroy (l); @@ -614,7 +581,7 @@ static gboolean gst_pipewire_device_provider_start (GstDeviceProvider * provider) { GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider); - struct remote_data *data; + struct core_data *data; GST_DEBUG_OBJECT (self, "starting provider"); @@ -627,7 +594,7 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) goto failed_main_loop; } - if (!(self->core = pw_core_new (self->loop, NULL, 0))) { + if (!(self->core = pw_core_new (self->loop, NULL, sizeof(*data)))) { GST_ERROR_OBJECT (self, "Could not create PipeWire core"); goto failed_core; } @@ -639,60 +606,41 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) pw_thread_loop_lock (self->main_loop); - if (!(self->remote = pw_remote_new (self->core, NULL, sizeof(*data)))) { - GST_ERROR_OBJECT (self, "Failed to create remote"); - goto failed_remote; + if ((self->core_proxy = pw_core_connect (self->core, NULL, 0)) == NULL) { + GST_ERROR_OBJECT (self, "Failed to connect"); + goto failed_connect; } - data = pw_remote_get_user_data(self->remote); + + GST_DEBUG_OBJECT (self, "connected"); + + data = pw_core_get_user_data(self->core); data->self = self; spa_list_init(&data->nodes); spa_list_init(&data->ports); - pw_remote_add_listener (self->remote, &self->remote_listener, &remote_events, data); - if (pw_remote_connect (self->remote) < 0) - goto not_running; - - for (;;) { - enum pw_remote_state state; - const char *error = NULL; - - state = pw_remote_get_state(self->remote, &error); - - if (state <= 0) { - GST_WARNING_OBJECT (self, "Failed to connect: %s", error); - goto not_running; - } - - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - /* Wait until something happens */ - pw_thread_loop_wait (self->main_loop); - } - GST_DEBUG_OBJECT (self, "connected"); + pw_core_proxy_add_listener(self->core_proxy, &data->core_listener, &core_events, self); self->registry = pw_core_proxy_get_registry(self->core_proxy, PW_VERSION_REGISTRY_PROXY, 0); - data->registry = self->registry; - pw_registry_proxy_add_listener(self->registry, &data->registry_listener, ®istry_events, data); + pw_core_proxy_sync(self->core_proxy, 0, self->seq++); for (;;) { + if (self->error < 0) + break; if (self->end) break; pw_thread_loop_wait (self->main_loop); } + GST_DEBUG_OBJECT (self, "started"); pw_thread_loop_unlock (self->main_loop); return TRUE; -not_running: - pw_remote_destroy (self->remote); - self->remote = NULL; -failed_remote: +failed_connect: pw_thread_loop_unlock (self->main_loop); failed_start: pw_core_destroy (self->core); @@ -713,10 +661,9 @@ gst_pipewire_device_provider_stop (GstDeviceProvider * provider) GST_DEBUG_OBJECT (self, "stopping provider"); - if (self->remote) { - pw_remote_disconnect (self->remote); - pw_remote_destroy (self->remote); - self->remote = NULL; + if (self->core_proxy) { + pw_core_proxy_disconnect (self->core_proxy); + self->core_proxy = NULL; } if (self->core) { pw_core_destroy (self->core); diff --git a/src/gst/gstpipewiredeviceprovider.h b/src/gst/gstpipewiredeviceprovider.h index 4073df8ee..abe1edbf9 100644 --- a/src/gst/gstpipewiredeviceprovider.h +++ b/src/gst/gstpipewiredeviceprovider.h @@ -88,15 +88,13 @@ struct _GstPipeWireDeviceProvider { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; struct spa_list pending; int seq; struct pw_registry_proxy *registry; + int error; gboolean end; gboolean list_only; GList **devices; diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index fa77fe3a4..2cadb9bbd 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -665,7 +665,7 @@ gst_pipewire_sink_start (GstBaseSink * basesink) } pw_thread_loop_lock (pwsink->main_loop); - pwsink->stream = pw_stream_new (pwsink->remote, pwsink->client_name, props); + pwsink->stream = pw_stream_new (pwsink->core_proxy, pwsink->client_name, props); pwsink->pool->stream = pwsink->stream; pw_stream_add_listener(pwsink->stream, @@ -697,62 +697,22 @@ gst_pipewire_sink_stop (GstBaseSink * basesink) return TRUE; } -static void -on_remote_state_changed (void *data, enum pw_remote_state old, enum pw_remote_state state, const char *error) -{ - GstPipeWireSink *pwsink = data; - - GST_DEBUG ("got remote state %d", state); - - switch (state) { - case PW_REMOTE_STATE_UNCONNECTED: - case PW_REMOTE_STATE_CONNECTING: - case PW_REMOTE_STATE_CONNECTED: - break; - case PW_REMOTE_STATE_ERROR: - GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, - ("remote error: %s", error), (NULL)); - break; - } - pw_thread_loop_signal (pwsink->main_loop, FALSE); -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, -}; - static gboolean gst_pipewire_sink_open (GstPipeWireSink * pwsink) { - const char *error = NULL; - if (pw_thread_loop_start (pwsink->main_loop) < 0) goto mainloop_error; pw_thread_loop_lock (pwsink->main_loop); - pwsink->remote = pw_remote_new (pwsink->core, NULL, 0); - - pw_remote_add_listener (pwsink->remote, - &pwsink->remote_listener, - &remote_events, pwsink); if (pwsink->fd == -1) - pw_remote_connect (pwsink->remote); + pwsink->core_proxy = pw_core_connect (pwsink->core, NULL, 0); else - pw_remote_connect_fd (pwsink->remote, dup(pwsink->fd)); + pwsink->core_proxy = pw_core_connect_fd (pwsink->core, dup(pwsink->fd), NULL, 0); - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state (pwsink->remote, &error); + if (pwsink->core_proxy == NULL) + goto connect_error; - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) - goto connect_error; - - pw_thread_loop_wait (pwsink->main_loop); - } pw_thread_loop_unlock (pwsink->main_loop); return TRUE; @@ -766,6 +726,8 @@ mainloop_error: } connect_error: { + GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, + ("Failed to connect"), (NULL)); pw_thread_loop_unlock (pwsink->main_loop); return FALSE; } @@ -774,26 +736,13 @@ connect_error: static gboolean gst_pipewire_sink_close (GstPipeWireSink * pwsink) { - const char *error = NULL; - pw_thread_loop_lock (pwsink->main_loop); if (pwsink->stream) { pw_stream_disconnect (pwsink->stream); } - if (pwsink->remote) { - pw_remote_disconnect (pwsink->remote); - - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state (pwsink->remote, &error); - - if (state == PW_REMOTE_STATE_UNCONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) - break; - - pw_thread_loop_wait (pwsink->main_loop); - } + if (pwsink->core_proxy) { + pw_core_proxy_disconnect (pwsink->core_proxy); + pwsink->core_proxy = NULL; } pw_thread_loop_unlock (pwsink->main_loop); @@ -803,12 +752,6 @@ gst_pipewire_sink_close (GstPipeWireSink * pwsink) pw_stream_destroy (pwsink->stream); pwsink->stream = NULL; } - - if (pwsink->remote) { - pw_remote_destroy (pwsink->remote); - pwsink->remote = NULL; - } - return TRUE; } diff --git a/src/gst/gstpipewiresink.h b/src/gst/gstpipewiresink.h index 90866aba3..75f6cf3a5 100644 --- a/src/gst/gstpipewiresink.h +++ b/src/gst/gstpipewiresink.h @@ -87,8 +87,7 @@ struct _GstPipeWireSink { struct pw_thread_loop *main_loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; struct pw_stream *stream; struct spa_hook stream_listener; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index cc27445d5..e66a4cf0e 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -504,9 +504,6 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc) if (state == PW_STREAM_STATE_ERROR) goto start_error; - if (pw_remote_get_state(pwsrc->remote, &error) == PW_REMOTE_STATE_ERROR) - goto start_error; - pw_thread_loop_wait (pwsrc->main_loop); } @@ -542,9 +539,6 @@ wait_negotiated (GstPipeWireSrc *this) if (state == PW_STREAM_STATE_ERROR) break; - if (pw_remote_get_state(this->remote, &error) == PW_REMOTE_STATE_ERROR) - break; - if (this->started) break; @@ -638,9 +632,6 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc) if (state == PW_STREAM_STATE_ERROR) goto connect_error; - if (pw_remote_get_state(pwsrc->remote, &error) == PW_REMOTE_STATE_ERROR) - goto connect_error; - pw_thread_loop_wait (pwsrc->main_loop); } pw_thread_loop_unlock (pwsrc->main_loop); @@ -915,26 +906,6 @@ gst_pipewire_src_stop (GstBaseSrc * basesrc) return TRUE; } -static void -on_remote_state_changed (void *data, enum pw_remote_state old, enum pw_remote_state state, const char *error) -{ - GstPipeWireSrc *pwsrc = data; - - GST_DEBUG ("got remote state %s", pw_remote_state_as_string (state)); - - switch (state) { - case PW_REMOTE_STATE_UNCONNECTED: - case PW_REMOTE_STATE_CONNECTING: - case PW_REMOTE_STATE_CONNECTED: - break; - case PW_REMOTE_STATE_ERROR: - GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, - ("remote error: %s", error), (NULL)); - break; - } - pw_thread_loop_signal (pwsrc->main_loop, FALSE); -} - static gboolean copy_properties (GQuark field_id, const GValue *value, @@ -949,11 +920,6 @@ copy_properties (GQuark field_id, return TRUE; } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, -}; - static const struct pw_stream_events stream_events = { PW_VERSION_STREAM_EVENTS, .state_changed = on_state_changed, @@ -967,37 +933,20 @@ static gboolean gst_pipewire_src_open (GstPipeWireSrc * pwsrc) { struct pw_properties *props; - const char *error = NULL; if (pw_thread_loop_start (pwsrc->main_loop) < 0) goto mainloop_failed; pw_thread_loop_lock (pwsrc->main_loop); - if ((pwsrc->remote = pw_remote_new (pwsrc->core, NULL, 0)) == NULL) - goto no_remote; - - pw_remote_add_listener (pwsrc->remote, - &pwsrc->remote_listener, - &remote_events, pwsrc); if (pwsrc->fd == -1) - pw_remote_connect (pwsrc->remote); + pwsrc->core_proxy = pw_core_connect (pwsrc->core, NULL, 0); else - pw_remote_connect_fd (pwsrc->remote, dup(pwsrc->fd)); + pwsrc->core_proxy = pw_core_connect_fd (pwsrc->core, dup(pwsrc->fd), NULL, 0); - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state(pwsrc->remote, &error); - - GST_DEBUG ("waiting for CONNECTED, now %s", pw_remote_state_as_string (state)); - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) + if (pwsrc->core_proxy == NULL) goto connect_error; - pw_thread_loop_wait (pwsrc->main_loop); - } - if (pwsrc->properties) { props = pw_properties_new (NULL, NULL); gst_structure_foreach (pwsrc->properties, copy_properties, props); @@ -1005,7 +954,8 @@ gst_pipewire_src_open (GstPipeWireSrc * pwsrc) props = NULL; } - if ((pwsrc->stream = pw_stream_new (pwsrc->remote, pwsrc->client_name, props)) == NULL) + if ((pwsrc->stream = pw_stream_new (pwsrc->core_proxy, + pwsrc->client_name, props)) == NULL) goto no_stream; @@ -1026,14 +976,9 @@ mainloop_failed: GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("error starting mainloop"), (NULL)); return FALSE; } -no_remote: - { - GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't create remote"), (NULL)); - pw_thread_loop_unlock (pwsrc->main_loop); - return FALSE; - } connect_error: { + GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't connect"), (NULL)); pw_thread_loop_unlock (pwsrc->main_loop); return FALSE; } @@ -1065,8 +1010,8 @@ gst_pipewire_src_close (GstPipeWireSrc * pwsrc) pw_stream_destroy (pwsrc->stream); pwsrc->stream = NULL; - pw_remote_destroy (pwsrc->remote); - pwsrc->remote = NULL; + pw_core_proxy_disconnect (pwsrc->core_proxy); + pwsrc->core_proxy = NULL; } static GstStateChangeReturn diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index 14dc4261e..af61ad9e8 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -75,8 +75,7 @@ struct _GstPipeWireSrc { struct pw_thread_loop *main_loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; struct pw_stream *stream; struct spa_hook stream_listener; diff --git a/src/modules/module-client-device.c b/src/modules/module-client-device.c index abb5c8b8b..442b88cca 100644 --- a/src/modules/module-client-device.c +++ b/src/modules/module-client-device.c @@ -43,7 +43,7 @@ static const struct spa_dict_item module_props[] = { { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; -struct pw_proxy *pw_remote_spa_device_export(struct pw_core_proxy *core_proxy, +struct pw_proxy *pw_core_proxy_spa_device_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size); @@ -188,7 +188,7 @@ int pipewire__module_init(struct pw_module *module, const char *args) pw_protocol_native_ext_client_device_init(core); data->export_spadevice.type = SPA_TYPE_INTERFACE_Device; - data->export_spadevice.func = pw_remote_spa_device_export; + data->export_spadevice.func = pw_core_proxy_spa_device_export; pw_core_register_export_type(core, &data->export_spadevice); pw_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-client-device/proxy-device.c b/src/modules/module-client-device/proxy-device.c index 54260f693..6b4fc7dcc 100644 --- a/src/modules/module-client-device/proxy-device.c +++ b/src/modules/module-client-device/proxy-device.c @@ -52,7 +52,7 @@ static const struct pw_proxy_events proxy_events = { .destroy = device_proxy_destroy, }; -struct pw_proxy *pw_remote_spa_device_export(struct pw_core_proxy *core_proxy, +struct pw_proxy *pw_core_proxy_spa_device_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size) { diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index 7d2910b8d..c1cfcb538 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -68,9 +68,10 @@ struct link { }; struct node_data { - struct pw_remote *remote; struct pw_core *core; + struct pw_mempool *pool; + uint32_t remote_id; int rtwritefd; struct pw_memmap *activation; @@ -133,7 +134,7 @@ static void clean_transport(struct node_data *data) } pw_array_clear(&data->links); - while ((mm = pw_mempool_find_tag(data->remote->pool, tag, sizeof(uint32_t))) != NULL) + while ((mm = pw_mempool_find_tag(data->pool, tag, sizeof(uint32_t))) != NULL) pw_memmap_free(mm); pw_memmap_free(data->activation); @@ -241,7 +242,7 @@ static int client_node_transport(void *object, clean_transport(data); - data->activation = pw_mempool_map_id(data->remote->pool, mem_id, + data->activation = pw_mempool_map_id(data->pool, mem_id, PW_MEMMAP_FLAG_READWRITE, offset, size, NULL); if (data->activation == NULL) { pw_log_debug("remote-node %p: can't map activation: %m", proxy); @@ -408,7 +409,7 @@ client_node_set_io(void *object, void *ptr; uint32_t tag[5] = { data->remote_id, id, }; - if ((mm = pw_mempool_find_tag(data->remote->pool, tag, sizeof(tag))) != NULL) + if ((mm = pw_mempool_find_tag(data->pool, tag, sizeof(tag))) != NULL) pw_memmap_free(mm); if (memid == SPA_ID_INVALID) { @@ -416,7 +417,7 @@ client_node_set_io(void *object, size = 0; } else { - mm = pw_mempool_map_id(data->remote->pool, memid, + mm = pw_mempool_map_id(data->pool, memid, PW_MEMMAP_FLAG_READWRITE, offset, size, tag); if (mm == NULL) { pw_log_warn("can't map memory id %u: %m", memid); @@ -599,7 +600,7 @@ client_node_port_use_buffers(void *object, off_t offset; struct pw_memmap *mm; - mm = pw_mempool_map_id(data->remote->pool, buffers[i].mem_id, + mm = pw_mempool_map_id(data->pool, buffers[i].mem_id, prot, buffers[i].offset, buffers[i].size, NULL); if (mm == NULL) { res = -errno; @@ -661,7 +662,7 @@ client_node_port_use_buffers(void *object, uint32_t mem_id = SPA_PTR_TO_UINT32(d->data); struct pw_memblock *bm; - bm = pw_mempool_find_id(data->remote->pool, mem_id); + bm = pw_mempool_find_id(data->pool, mem_id); if (bm == NULL) { pw_log_error("unknown buffer mem %u", mem_id); res = -ENODEV; @@ -730,7 +731,7 @@ client_node_port_set_io(void *object, goto error_exit; } - if ((mm = pw_mempool_find_tag(data->remote->pool, tag, sizeof(tag))) != NULL) + if ((mm = pw_mempool_find_tag(data->pool, tag, sizeof(tag))) != NULL) pw_memmap_free(mm); if (memid == SPA_ID_INVALID) { @@ -738,7 +739,7 @@ client_node_port_set_io(void *object, size = 0; } else { - mm = pw_mempool_map_id(data->remote->pool, memid, + mm = pw_mempool_map_id(data->pool, memid, PW_MEMMAP_FLAG_READWRITE, offset, size, tag); if (mm == NULL) { res = -errno; @@ -819,7 +820,7 @@ client_node_set_activation(void *object, size = 0; } else { - mm = pw_mempool_map_id(data->remote->pool, memid, + mm = pw_mempool_map_id(data->pool, memid, PW_MEMMAP_FLAG_READWRITE, offset, size, NULL); if (mm == NULL) { res = -errno; @@ -1104,7 +1105,7 @@ static const struct spa_node_callbacks node_callbacks = { .xrun = node_xrun }; -static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool do_free, +static struct pw_proxy *node_export(struct pw_core_proxy *core_proxy, void *object, bool do_free, size_t user_data_size) { struct pw_node *node = object; @@ -1112,7 +1113,7 @@ static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool struct node_data *data; int i; - client_node = pw_core_proxy_create_object(remote->core_proxy, + client_node = pw_core_proxy_create_object(core_proxy, "client-node", PW_TYPE_INTERFACE_ClientNode, PW_VERSION_CLIENT_NODE, @@ -1122,7 +1123,7 @@ static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool return NULL; data = pw_proxy_get_user_data(client_node); - data->remote = remote; + data->pool = pw_core_proxy_get_mempool(core_proxy); data->node = node; data->do_free = do_free; data->core = pw_node_get_core(node); @@ -1166,13 +1167,12 @@ struct pw_proxy *pw_core_proxy_node_export(struct pw_core_proxy *core_proxy, size_t user_data_size) { struct pw_node *node = object; - struct pw_remote *remote = pw_proxy_get_remote((struct pw_proxy*)core_proxy); if (props) { pw_node_update_properties(node, &props->dict); pw_properties_free(props); } - return node_export(remote, object, false, user_data_size); + return node_export(core_proxy, object, false, user_data_size); } struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy, @@ -1180,9 +1180,8 @@ struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy, size_t user_data_size) { struct pw_node *node; - struct pw_remote *remote = pw_proxy_get_remote((struct pw_proxy*)core_proxy); - node = pw_node_new(pw_remote_get_core(remote), props, 0); + node = pw_node_new(pw_core_proxy_get_core(core_proxy), props, 0); if (node == NULL) return NULL; @@ -1190,5 +1189,5 @@ struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy, pw_node_register(node, NULL); pw_node_set_active(node, true); - return node_export(remote, node, true, user_data_size); + return node_export(core_proxy, node, true, user_data_size); } diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index e930007a0..fde1ac17e 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -79,6 +79,7 @@ struct protocol_data { struct client { struct pw_protocol_client this; + struct pw_core *core; struct spa_source *source; @@ -579,9 +580,11 @@ static void on_remote_data(void *data, int fd, uint32_t mask) { struct client *impl = data; - struct pw_remote *this = impl->this.remote; + struct pw_core_proxy *this = impl->this.core_proxy; + struct pw_remote *remote = pw_proxy_get_remote((struct pw_proxy*)this); struct pw_protocol_native_connection *conn = impl->connection; - struct pw_core *core = pw_remote_get_core(this); + struct pw_core *core = pw_core_proxy_get_core(this); + struct pw_loop *loop = pw_core_get_main_loop(core); int res; if (mask & (SPA_IO_ERR | SPA_IO_HUP)) { @@ -593,7 +596,7 @@ on_remote_data(void *data, int fd, uint32_t mask) if (res >= 0) { int mask = impl->source->mask; SPA_FLAG_CLEAR(mask, SPA_IO_OUT); - pw_loop_update_io(core->main_loop, + pw_loop_update_io(loop, impl->source, mask); impl->flushing = false; } else if (res != EAGAIN) @@ -620,7 +623,7 @@ on_remote_data(void *data, int fd, uint32_t mask) pw_log_trace(NAME" %p: got message %d from %u seq:%d", this, msg->opcode, msg->id, msg->seq); - this->recv_seq = msg->seq; + remote->recv_seq = msg->seq; if (debug_messages) { fprintf(stderr, "<<<<<<<<< in: id:%d op:%d size:%d seq:%d\n", @@ -628,7 +631,7 @@ on_remote_data(void *data, int fd, uint32_t mask) spa_debug_pod(0, NULL, (struct spa_pod *)msg->data); } - proxy = pw_remote_find_proxy(this, msg->id); + proxy = pw_core_proxy_find_proxy(this, msg->id); if (proxy == NULL || proxy->zombie) { if (proxy == NULL) pw_log_error(NAME" %p: could not find proxy %u", this, msg->id); @@ -667,25 +670,24 @@ on_remote_data(void *data, int fd, uint32_t mask) return; error: pw_log_error(NAME" %p: got connection error %d (%s)", impl, res, spa_strerror(res)); - pw_proxy_notify((struct pw_proxy*)this->core_proxy, + pw_proxy_notify((struct pw_proxy*)this, struct pw_core_proxy_events, error, 0, 0, - this->recv_seq, res, "connection error"); - pw_loop_destroy_source(pw_core_get_main_loop(core), impl->source); + remote->recv_seq, res, "connection error"); + pw_loop_destroy_source(loop, impl->source); impl->source = NULL; - pw_remote_disconnect(this); + pw_core_proxy_disconnect(this); } static void on_need_flush(void *data) { struct client *impl = data; - struct pw_remote *remote = impl->this.remote; if (!impl->flushing && impl->source) { int mask = impl->source->mask; impl->flushing = true; SPA_FLAG_SET(mask, SPA_IO_OUT); - pw_loop_update_io(remote->core->main_loop, + pw_loop_update_io(impl->core->main_loop, impl->source, mask); } } @@ -698,15 +700,15 @@ static const struct pw_protocol_native_connection_events client_conn_events = { static int impl_connect_fd(struct pw_protocol_client *client, int fd, bool do_close) { struct client *impl = SPA_CONTAINER_OF(client, struct client, this); - struct pw_remote *remote = client->remote; int res; impl->disconnecting = false; pw_protocol_native_connection_set_fd(impl->connection, fd); - impl->source = pw_loop_add_io(remote->core->main_loop, + impl->flushing = true; + impl->source = pw_loop_add_io(impl->core->main_loop, fd, - SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR, + SPA_IO_IN | SPA_IO_OUT | SPA_IO_HUP | SPA_IO_ERR, do_close, on_remote_data, impl); if (impl->source == NULL) { res = -errno; @@ -730,12 +732,11 @@ error_cleanup: static void impl_disconnect(struct pw_protocol_client *client) { struct client *impl = SPA_CONTAINER_OF(client, struct client, this); - struct pw_remote *remote = client->remote; impl->disconnecting = true; if (impl->source) - pw_loop_destroy_source(remote->core->main_loop, impl->source); + pw_loop_destroy_source(impl->core->main_loop, impl->source); impl->source = NULL; if (impl->connection) @@ -755,7 +756,6 @@ static void impl_destroy(struct pw_protocol_client *client) static struct pw_protocol_client * impl_new_client(struct pw_protocol *protocol, - struct pw_remote *remote, struct pw_properties *properties) { struct client *impl; @@ -768,9 +768,9 @@ impl_new_client(struct pw_protocol *protocol, this = &impl->this; this->protocol = protocol; - this->remote = remote; - impl->connection = pw_protocol_native_connection_new(remote->core, -1); + impl->core = protocol->core; + impl->connection = pw_protocol_native_connection_new(protocol->core, -1); if (impl->connection == NULL) { res = -errno; goto error_free; @@ -872,10 +872,10 @@ get_name(const struct pw_properties *properties) static struct pw_protocol_server * impl_add_server(struct pw_protocol *protocol, - struct pw_core *core, struct pw_properties *properties) { struct pw_protocol_server *this; + struct pw_core *core = protocol->core; struct server *s; const char *name; int res; @@ -1034,7 +1034,7 @@ int pipewire__module_init(struct pw_module *module, const char *args) if (val == NULL) val = pw_properties_get(pw_core_get_properties(core), PW_KEY_CORE_DAEMON); if (val && pw_properties_parse_bool(val)) { - if (impl_add_server(this, core, NULL) == NULL) { + if (impl_add_server(this, NULL) == NULL) { res = -errno; goto error_cleanup; } diff --git a/src/modules/module-protocol-native/defs.h b/src/modules/module-protocol-native/defs.h index 92f155c77..a1c9ba361 100644 --- a/src/modules/module-protocol-native/defs.h +++ b/src/modules/module-protocol-native/defs.h @@ -23,8 +23,10 @@ */ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data); int pw_protocol_native_connect_portal_screencast(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data); diff --git a/src/modules/module-protocol-native/local-socket.c b/src/modules/module-protocol-native/local-socket.c index 49373347f..8622b3262 100644 --- a/src/modules/module-protocol-native/local-socket.c +++ b/src/modules/module-protocol-native/local-socket.c @@ -37,12 +37,12 @@ #include static const char * -get_remote(const struct pw_properties *properties) +get_remote(const struct spa_dict *props) { const char *name = NULL; - if (properties) - name = pw_properties_get(properties, PW_KEY_REMOTE_NAME); + if (props) + name = spa_dict_lookup(props, PW_KEY_REMOTE_NAME); if (name == NULL) name = getenv("PIPEWIRE_REMOTE"); if (name == NULL) @@ -51,10 +51,10 @@ get_remote(const struct pw_properties *properties) } int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data) { - struct pw_remote *remote = client->remote; struct sockaddr_un addr; socklen_t size; const char *runtime_dir, *name = NULL; @@ -66,7 +66,7 @@ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, goto error; } - name = get_remote(pw_remote_get_properties(remote)); + name = get_remote(props); if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0) { res = -errno; diff --git a/src/modules/module-protocol-native/portal-screencast.c b/src/modules/module-protocol-native/portal-screencast.c index d5f2ba59d..7cb661480 100644 --- a/src/modules/module-protocol-native/portal-screencast.c +++ b/src/modules/module-protocol-native/portal-screencast.c @@ -33,6 +33,7 @@ #include int pw_protocol_native_connect_portal_screencast(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data) { diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index 2124bed13..63b7229dd 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -70,7 +70,6 @@ struct queue { struct data { struct pw_core *core; - struct pw_remote *remote; struct spa_hook filter_listener; }; @@ -120,8 +119,6 @@ struct filter { enum pw_filter_flags flags; - struct spa_hook remote_listener; - struct pw_node *node; struct spa_node impl_node; @@ -139,7 +136,6 @@ struct filter { uintptr_t seq; struct pw_time time; - unsigned int async_connect:1; unsigned int disconnecting:1; unsigned int free_data:1; unsigned int subscribe:1; @@ -882,83 +878,25 @@ static const struct pw_proxy_events proxy_events = { .bound = proxy_bound, }; -static int handle_connect(struct pw_filter *filter) -{ - struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); - struct pw_properties *props; - int res; - - pw_log_debug(NAME" %p: creating node", filter); - props = pw_properties_copy(filter->properties); - - impl->node = pw_node_new(impl->core, props, 0); - if (impl->node == NULL) { - res = -errno; - goto error_node; - } - - impl->node->port_user_data_size = sizeof(struct port); - - pw_node_set_implementation(impl->node, &impl->impl_node); - - pw_log_debug(NAME" %p: export node %p", filter, impl->node); - filter->proxy = pw_remote_export(filter->remote, - PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); - if (filter->proxy == NULL) { - res = -errno; - goto error_proxy; - } - - pw_proxy_add_listener(filter->proxy, &filter->proxy_listener, &proxy_events, filter); - - if (!SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_INACTIVE)) - pw_node_set_active(impl->node, true); - - return 0; - -error_node: - pw_log_error(NAME" %p: can't make node: %s", filter, spa_strerror(res)); - return res; -error_proxy: - pw_log_error(NAME" %p: can't make proxy: %s", filter, spa_strerror(res)); - return res; -} - -static void on_remote_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *_data, uint32_t id, int seq, int res, const char *message) { struct pw_filter *filter = _data; - struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); - pw_log_debug(NAME" %p: remote state %d", filter, state); - - switch (state) { - case PW_REMOTE_STATE_ERROR: - filter_set_state(filter, PW_FILTER_STATE_ERROR, error); - break; - - case PW_REMOTE_STATE_UNCONNECTED: - filter_set_state(filter, PW_FILTER_STATE_UNCONNECTED, "remote unconnected"); - break; - - case PW_REMOTE_STATE_CONNECTED: - if (impl->async_connect) - handle_connect(filter); - break; - - default: - break; + pw_log_error(NAME" %p: error id:%u seq:%d res:%d (%s): %s", filter, + id, seq, res, spa_strerror(res), message); + if (id == 0) { + filter_set_state(filter, PW_FILTER_STATE_UNCONNECTED, message); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; -SPA_EXPORT -struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, - struct pw_properties *props) +static struct filter * +filter_new(struct pw_core *core, const char *name, + struct pw_properties *props, struct pw_properties *extra) { struct filter *impl; struct pw_filter *this; @@ -984,12 +922,10 @@ struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, goto error_properties; } - if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL) { - const struct pw_properties *p = pw_remote_get_properties(remote); - - if ((str = pw_properties_get(p, PW_KEY_APP_NAME)) != NULL) + if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { + if ((str = pw_properties_get(extra, PW_KEY_APP_NAME)) != NULL) pw_properties_set(props, PW_KEY_NODE_NAME, str); - else if ((str = pw_properties_get(p, PW_KEY_APP_PROCESS_BINARY)) != NULL) + else if ((str = pw_properties_get(extra, PW_KEY_APP_PROCESS_BINARY)) != NULL) pw_properties_set(props, PW_KEY_NODE_NAME, str); else pw_properties_set(props, PW_KEY_NODE_NAME, name); @@ -998,7 +934,6 @@ struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, spa_hook_list_init(&impl->hooks); this->properties = props; - this->remote = remote; this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1010,13 +945,11 @@ struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, this->state = PW_FILTER_STATE_UNCONNECTED; - impl->core = remote->core; + impl->core = core; - pw_remote_add_listener(remote, &impl->remote_listener, &remote_events, this); +// spa_list_append(&remote->filter_list, &this->link); - spa_list_append(&remote->filter_list, &this->link); - - return this; + return impl; error_properties: free(impl); @@ -1027,6 +960,26 @@ error_cleanup: return NULL; } +SPA_EXPORT +struct pw_filter * pw_filter_new(struct pw_core_proxy *core_proxy, const char *name, + struct pw_properties *props) +{ + struct filter *impl; + struct pw_filter *this; + struct pw_core *core = pw_core_proxy_get_core(core_proxy); + + impl = filter_new(core, name, props, NULL); + if (impl == NULL) + return NULL; + + this = &impl->this; + this->core_proxy = core_proxy; + pw_core_proxy_add_listener(core_proxy, + &this->core_listener, &core_events, this); + + return this; +} + SPA_EXPORT struct pw_filter * pw_filter_new_simple(struct pw_loop *loop, @@ -1035,30 +988,26 @@ pw_filter_new_simple(struct pw_loop *loop, const struct pw_filter_events *events, void *data) { - struct pw_filter *filter; + struct pw_filter *this; struct filter *impl; struct pw_core *core; - struct pw_remote *remote; int res; core = pw_core_new(loop, NULL, 0); - remote = pw_remote_new(core, NULL, 0); - filter = pw_filter_new(remote, name, props); - if (filter == NULL) { + impl = filter_new(core, name, props, NULL); + if (impl == NULL) { res = -errno; goto error_cleanup; } - impl = SPA_CONTAINER_OF(filter, struct filter, this); + this = &impl->this; impl->free_data = true; impl->data.core = core; - impl->data.remote = remote; + pw_filter_add_listener(this, &impl->data.filter_listener, events, data); - pw_filter_add_listener(filter, &impl->data.filter_listener, events, data); - - return filter; + return this; error_cleanup: pw_core_destroy(core); @@ -1095,8 +1044,11 @@ void pw_filter_destroy(struct pw_filter *filter) pw_filter_disconnect(filter); - spa_hook_remove(&impl->remote_listener); - spa_list_remove(&filter->link); + if (filter->core_proxy) { + spa_hook_remove(&filter->core_listener); + filter->core_proxy = NULL; + } +// spa_list_remove(&filter->link); clear_params(impl, NULL, SPA_ID_INVALID); @@ -1131,9 +1083,9 @@ enum pw_filter_state pw_filter_get_state(struct pw_filter *filter, const char ** } SPA_EXPORT -struct pw_remote *pw_filter_get_remote(struct pw_filter *filter) +struct pw_core_proxy *pw_filter_get_core_proxy(struct pw_filter *filter) { - return filter->remote; + return filter->core_proxy; } SPA_EXPORT @@ -1183,7 +1135,7 @@ pw_filter_connect(struct pw_filter *filter, uint32_t n_params) { struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); - enum pw_remote_state state; + struct pw_properties *props; int res; uint32_t i; @@ -1203,15 +1155,53 @@ pw_filter_connect(struct pw_filter *filter, impl->disconnecting = false; filter_set_state(filter, PW_FILTER_STATE_CONNECTING, NULL); - state = pw_remote_get_state(filter->remote, NULL); - impl->async_connect = (state == PW_REMOTE_STATE_UNCONNECTED || - state == PW_REMOTE_STATE_ERROR); + if (filter->core_proxy == NULL) { + filter->core_proxy = pw_core_connect(impl->core, + pw_properties_copy(filter->properties), 0); + if (filter->core_proxy == NULL) { + res = -errno; + goto error_connect; + } + pw_core_proxy_add_listener(filter->core_proxy, + &filter->core_listener, &core_events, filter); + } - if (impl->async_connect) - res = pw_remote_connect(filter->remote); - else - res = handle_connect(filter); + pw_log_debug(NAME" %p: creating node", filter); + props = pw_properties_copy(filter->properties); + impl->node = pw_node_new(impl->core, props, 0); + if (impl->node == NULL) { + res = -errno; + goto error_node; + } + + impl->node->port_user_data_size = sizeof(struct port); + + pw_node_set_implementation(impl->node, &impl->impl_node); + + pw_log_debug(NAME" %p: export node %p", filter, impl->node); + filter->proxy = pw_core_proxy_export(filter->core_proxy, + PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); + if (filter->proxy == NULL) { + res = -errno; + goto error_proxy; + } + + pw_proxy_add_listener(filter->proxy, &filter->proxy_listener, &proxy_events, filter); + + if (!SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_INACTIVE)) + pw_node_set_active(impl->node, true); + + return 0; + +error_connect: + pw_log_error(NAME" %p: can't connect: %s", filter, spa_strerror(res)); + return res; +error_node: + pw_log_error(NAME" %p: can't make node: %s", filter, spa_strerror(res)); + return res; +error_proxy: + pw_log_error(NAME" %p: can't make proxy: %s", filter, spa_strerror(res)); return res; } diff --git a/src/pipewire/filter.h b/src/pipewire/filter.h index 4db4f5752..96978019f 100644 --- a/src/pipewire/filter.h +++ b/src/pipewire/filter.h @@ -124,7 +124,7 @@ enum pw_filter_port_flags { /** Create a new unconneced \ref pw_filter \memberof pw_filter * \return a newly allocated \ref pw_filter */ struct pw_filter * -pw_filter_new(struct pw_remote *remote, /**< a \ref pw_remote */ +pw_filter_new(struct pw_core_proxy *proxy, /**< a \ref pw_core_proxy */ const char *name, /**< a filter media name */ struct pw_properties *props /**< filter properties, ownership is taken */); @@ -147,7 +147,7 @@ enum pw_filter_state pw_filter_get_state(struct pw_filter *filter, const char ** const char *pw_stream_get_name(struct pw_stream *stream); -struct pw_remote *pw_filter_get_remote(struct pw_filter *filter); +struct pw_core_proxy *pw_filter_get_core_proxy(struct pw_filter *filter); /** Connect a filter for processing. \memberof pw_filter * \return 0 on success < 0 on error. diff --git a/src/pipewire/private.h b/src/pipewire/private.h index bd55c3374..4af3986fa 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -774,8 +774,10 @@ struct pw_remote { struct pw_stream { - struct pw_remote *remote; /**< the owner remote */ - struct spa_list link; /**< link in the remote */ + struct pw_core_proxy *core_proxy; /**< the owner core_proxy */ + struct spa_hook core_listener; + + struct spa_list link; /**< link in the core_proxy */ char *name; /**< the name of the stream */ struct pw_properties *properties; /**< properties of the stream */ @@ -808,8 +810,10 @@ struct pw_stream { struct pw_filter { - struct pw_remote *remote; /**< the owner remote */ - struct spa_list link; /**< link in the remote */ + struct pw_core_proxy *core_proxy; /**< the owner core proxy */ + struct spa_hook core_listener; + + struct spa_list link; /**< link in the core proxy */ char *name; /**< the name of the filter */ struct pw_properties *properties; /**< properties of the filter */ diff --git a/src/pipewire/protocol.h b/src/pipewire/protocol.h index 62283e524..c99c732d0 100644 --- a/src/pipewire/protocol.h +++ b/src/pipewire/protocol.h @@ -44,9 +44,10 @@ struct pw_protocol_client { struct spa_list link; /**< link in protocol client_list */ struct pw_protocol *protocol; /**< the owner protocol */ - struct pw_remote *remote; /**< the associated remote */ + struct pw_core_proxy *core_proxy; int (*connect) (struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int result), void *data); int (*connect_fd) (struct pw_protocol_client *client, int fd, bool close); @@ -55,7 +56,7 @@ struct pw_protocol_client { void (*destroy) (struct pw_protocol_client *client); }; -#define pw_protocol_client_connect(c,cb,d) ((c)->connect(c,cb,d)) +#define pw_protocol_client_connect(c,p,cb,d) ((c)->connect(c,p,cb,d)) #define pw_protocol_client_connect_fd(c,fd,cl) ((c)->connect_fd(c,fd,cl)) #define pw_protocol_client_steal_fd(c) ((c)->steal_fd(c)) #define pw_protocol_client_disconnect(c) ((c)->disconnect(c)) @@ -90,10 +91,8 @@ struct pw_protocol_implementaton { uint32_t version; struct pw_protocol_client * (*new_client) (struct pw_protocol *protocol, - struct pw_remote *remote, struct pw_properties *properties); struct pw_protocol_server * (*add_server) (struct pw_protocol *protocol, - struct pw_core *core, struct pw_properties *properties); }; diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 5919ec8f7..96ba9259b 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -247,7 +247,7 @@ struct pw_remote *pw_remote_new(struct pw_core *core, goto error_protocol; } - this->conn = pw_protocol_new_client(protocol, this, properties); + this->conn = pw_protocol_new_client(protocol, properties); if (this->conn == NULL) goto error_connection; @@ -411,6 +411,8 @@ static int init_connect(struct pw_remote *remote) pw_core_proxy_hello(remote->core_proxy, PW_VERSION_CORE_PROXY); pw_client_proxy_update_properties(remote->client_proxy, &remote->properties->dict); + remote->conn->core_proxy = remote->core_proxy; + return 0; error_clean_core_proxy: @@ -469,7 +471,9 @@ int pw_remote_connect(struct pw_remote *remote) if ((res = init_connect(remote)) < 0) goto error; - if ((res = pw_protocol_client_connect(remote->conn, done_connect, remote)) < 0) + if ((res = pw_protocol_client_connect(remote->conn, + &remote->properties->dict, + done_connect, remote)) < 0) goto error; return remote->state == PW_REMOTE_STATE_ERROR ? -EIO : 0; @@ -587,3 +591,99 @@ exit: errno = -res; return NULL; } + +SPA_EXPORT +struct pw_core_proxy * +pw_core_connect(struct pw_core *core, struct pw_properties *properties, + size_t user_data_size) +{ + struct pw_remote *remote; + int res; + + remote = pw_remote_new(core, properties, user_data_size); + if (remote == NULL) + return NULL; + + if ((res = pw_remote_connect(remote)) < 0) + goto error_free; + + return remote->core_proxy; + +error_free: + pw_remote_destroy(remote); + errno = -res; + return NULL; +} + +SPA_EXPORT +struct pw_core_proxy * +pw_core_connect_fd(struct pw_core *core, int fd, struct pw_properties *properties, + size_t user_data_size) +{ + struct pw_remote *remote; + int res; + + remote = pw_remote_new(core, properties, user_data_size); + if (remote == NULL) + return NULL; + + if ((res = pw_remote_connect_fd(remote, fd)) < 0) + goto error_free; + + return remote->core_proxy; + +error_free: + pw_remote_destroy(remote); + errno = -res; + return NULL; +} + +SPA_EXPORT +struct pw_client_proxy * pw_core_proxy_get_client_proxy(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return remote->client_proxy; +} + +SPA_EXPORT +struct pw_core * pw_core_proxy_get_core(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return remote->core; +} +SPA_EXPORT +struct pw_remote * pw_core_proxy_get_remote(struct pw_core_proxy *proxy) +{ + return ((struct pw_proxy*)proxy)->remote; +} + +SPA_EXPORT +struct pw_mempool * pw_core_proxy_get_mempool(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return remote->pool; +} + +SPA_EXPORT +struct pw_proxy *pw_core_proxy_find_proxy(struct pw_core_proxy *proxy, uint32_t id) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_find_proxy(remote, id); +} + +SPA_EXPORT +int pw_core_proxy_disconnect(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + pw_remote_destroy(remote); + return 0; +} + +SPA_EXPORT +struct pw_proxy *pw_core_proxy_export(struct pw_core_proxy *proxy, + uint32_t type, struct pw_properties *properties, + void *object, size_t user_data_size) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_export(remote, type, properties, object, user_data_size); +} diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h index 0b975f7e5..5c86c2494 100644 --- a/src/pipewire/remote.h +++ b/src/pipewire/remote.h @@ -203,6 +203,41 @@ struct pw_proxy *pw_remote_export(struct pw_remote *remote, /**< the remote */ void *object, /**< object to export */ size_t user_data_size /**< extra user data */); + +struct pw_core_proxy * +pw_core_connect(struct pw_core *core, /**< a \ref pw_core */ + struct pw_properties *properties, /**< optional properties, ownership of + * the properties is taken.*/ + size_t user_data_size /**< extra user data size */); + +struct pw_core_proxy * +pw_core_connect_fd(struct pw_core *core, /**< a \ref pw_core */ + int fd, /**< an fd */ + struct pw_properties *properties, /**< optional properties, ownership of + * the properties is taken.*/ + size_t user_data_size /**< extra user data size */); + +int pw_core_proxy_disconnect(struct pw_core_proxy *proxy); + +/** Get the client proxy */ +struct pw_client_proxy * pw_core_proxy_get_client_proxy(struct pw_core_proxy *proxy); + +struct pw_core * pw_core_proxy_get_core(struct pw_core_proxy *proxy); + +struct pw_remote * pw_core_proxy_get_remote(struct pw_core_proxy *proxy); + +struct pw_mempool * pw_core_proxy_get_mempool(struct pw_core_proxy *proxy); + +/** Get the proxy with the given id */ +struct pw_proxy *pw_core_proxy_find_proxy(struct pw_core_proxy *proxy, uint32_t id); + +struct pw_proxy *pw_core_proxy_export(struct pw_core_proxy *proxy, /**< the proxy */ + uint32_t type, /**< the type of object */ + struct pw_properties *properties, /**< extra properties */ + void *object, /**< object to export */ + size_t user_data_size /**< extra user data */); + + #ifdef __cplusplus } #endif diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index b5a2caf36..25ea11419 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -67,7 +67,6 @@ struct queue { struct data { struct pw_core *core; - struct pw_remote *remote; struct spa_hook stream_listener; }; @@ -125,7 +124,6 @@ struct stream { uintptr_t seq; struct pw_time time; - unsigned int async_connect:1; unsigned int disconnecting:1; unsigned int free_data:1; unsigned int alloc_buffers:1; @@ -1000,114 +998,25 @@ static const struct pw_node_events node_events = { .info_changed = node_event_info, }; -static int handle_connect(struct pw_stream *stream) +static void on_core_error(void *object, uint32_t id, int seq, int res, const char *message) { - struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - struct pw_factory *factory; - struct pw_properties *props; - struct pw_node *slave; - const char *str; - int res; + struct pw_stream *stream = object; - pw_log_debug(NAME" %p: creating node", stream); - props = pw_properties_copy(stream->properties); - - if ((str = pw_properties_get(props, PW_KEY_STREAM_MONITOR)) && - pw_properties_parse_bool(str)) { - pw_properties_set(props, "resample.peaks", "1"); - } - - slave = pw_node_new(impl->core, pw_properties_copy(props), 0); - if (slave == NULL) { - res = -errno; - goto error_node; - } - - pw_node_set_implementation(slave, &impl->impl_node); - - if (!SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_INACTIVE)) - pw_node_set_active(slave, true); - - if (impl->media_type == SPA_MEDIA_TYPE_audio && - impl->media_subtype == SPA_MEDIA_SUBTYPE_raw) { - factory = pw_core_find_factory(impl->core, "adapter"); - if (factory == NULL) { - pw_log_error(NAME" %p: no adapter factory found", stream); - res = -ENOENT; - goto error_node; - } - pw_properties_setf(props, "adapt.slave.node", "pointer:%p", slave); - impl->node = pw_factory_create_object(factory, - NULL, - PW_TYPE_INTERFACE_Node, - PW_VERSION_NODE_PROXY, - props, - 0); - if (impl->node == NULL) { - res = -errno; - goto error_node; - } - } else { - impl->node = slave; - } - - pw_log_debug(NAME" %p: export node %p", stream, impl->node); - stream->proxy = pw_remote_export(stream->remote, - PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); - if (stream->proxy == NULL) { - res = -errno; - goto error_proxy; - } - - pw_proxy_add_listener(stream->proxy, &stream->proxy_listener, &proxy_events, stream); - - - pw_node_add_listener(impl->node, &stream->node_listener, &node_events, stream); - - return 0; - -error_node: - pw_log_error(NAME" %p: can't make node: %s", stream, spa_strerror(res)); - return res; -error_proxy: - pw_log_error(NAME" %p: can't make proxy: %s", stream, spa_strerror(res)); - return res; -} - -static void on_remote_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) -{ - struct pw_stream *stream = _data; - struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - - pw_log_debug(NAME" %p: remote state %d", stream, state); - - switch (state) { - case PW_REMOTE_STATE_ERROR: - stream_set_state(stream, PW_STREAM_STATE_ERROR, error); - break; - case PW_REMOTE_STATE_UNCONNECTED: - stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, "remote unconnected"); - break; - - case PW_REMOTE_STATE_CONNECTED: - if (impl->async_connect) - handle_connect(stream); - break; - - default: - break; + pw_log_error(NAME" %p: error id:%u seq:%d res:%d (%s): %s", stream, + id, seq, res, spa_strerror(res), message); + if (id == 0) { + stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, message); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; -SPA_EXPORT -struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, - struct pw_properties *props) +static struct stream * +stream_new(struct pw_core *core, const char *name, + struct pw_properties *props, struct pw_properties *extra) { struct stream *impl; struct pw_stream *this; @@ -1133,12 +1042,10 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, goto error_properties; } - if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL) { - const struct pw_properties *p = pw_remote_get_properties(remote); - - if ((str = pw_properties_get(p, PW_KEY_APP_NAME)) != NULL) + if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { + if ((str = pw_properties_get(extra, PW_KEY_APP_NAME)) != NULL) pw_properties_set(props, PW_KEY_NODE_NAME, str); - else if ((str = pw_properties_get(p, PW_KEY_APP_PROCESS_BINARY)) != NULL) + else if ((str = pw_properties_get(extra, PW_KEY_APP_PROCESS_BINARY)) != NULL) pw_properties_set(props, PW_KEY_NODE_NAME, str); else pw_properties_set(props, PW_KEY_NODE_NAME, name); @@ -1147,7 +1054,6 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, spa_hook_list_init(&impl->hooks); this->properties = props; - this->remote = remote; this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1160,13 +1066,11 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, this->state = PW_STREAM_STATE_UNCONNECTED; - impl->core = remote->core; + impl->core = core; - pw_remote_add_listener(remote, &impl->remote_listener, &remote_events, this); +// spa_list_append(&remote->stream_list, &this->link); - spa_list_append(&remote->stream_list, &this->link); - - return this; + return impl; error_properties: free(impl); @@ -1177,6 +1081,26 @@ error_cleanup: return NULL; } +SPA_EXPORT +struct pw_stream * pw_stream_new(struct pw_core_proxy *core_proxy, const char *name, + struct pw_properties *props) +{ + struct stream *impl; + struct pw_stream *this; + struct pw_core *core = pw_core_proxy_get_core(core_proxy); + + impl = stream_new(core, name, props, NULL); + if (impl == NULL) + return NULL; + + this = &impl->this; + this->core_proxy = core_proxy; + pw_core_proxy_add_listener(core_proxy, + &this->core_listener, &core_events, this); + + return this; +} + SPA_EXPORT struct pw_stream * pw_stream_new_simple(struct pw_loop *loop, @@ -1185,30 +1109,25 @@ pw_stream_new_simple(struct pw_loop *loop, const struct pw_stream_events *events, void *data) { - struct pw_stream *stream; + struct pw_stream *this; struct stream *impl; struct pw_core *core; - struct pw_remote *remote; int res; core = pw_core_new(loop, NULL, 0); - remote = pw_remote_new(core, NULL, 0); - stream = pw_stream_new(remote, name, props); - if (stream == NULL) { + impl = stream_new(core, name, props, NULL); + if (impl == NULL) { res = -errno; goto error_cleanup; } - impl = SPA_CONTAINER_OF(stream, struct stream, this); - + this = &impl->this; impl->free_data = true; impl->data.core = core; - impl->data.remote = remote; + pw_stream_add_listener(this, &impl->data.stream_listener, events, data); - pw_stream_add_listener(stream, &impl->data.stream_listener, events, data); - - return stream; + return this; error_cleanup: pw_core_destroy(core); @@ -1246,8 +1165,11 @@ void pw_stream_destroy(struct pw_stream *stream) pw_stream_disconnect(stream); - spa_hook_remove(&impl->remote_listener); - spa_list_remove(&stream->link); + if (stream->core_proxy) { + spa_hook_remove(&stream->core_listener); + stream->core_proxy = NULL; + } +// spa_list_remove(&stream->link); clear_params(impl, SPA_ID_INVALID); @@ -1316,9 +1238,9 @@ int pw_stream_update_properties(struct pw_stream *stream, const struct spa_dict } SPA_EXPORT -struct pw_remote *pw_stream_get_remote(struct pw_stream *stream) +struct pw_core_proxy *pw_stream_get_core_proxy(struct pw_stream *stream) { - return stream->remote; + return stream->core_proxy; } static void add_params(struct stream *impl) @@ -1390,9 +1312,12 @@ pw_stream_connect(struct pw_stream *stream, uint32_t n_params) { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - enum pw_remote_state state; - int res; + struct pw_factory *factory; + struct pw_properties *props; + struct pw_node *slave; + const char *str; uint32_t i; + int res; pw_log_debug(NAME" %p: connect target:%d", stream, target_id); impl->direction = @@ -1445,15 +1370,82 @@ pw_stream_connect(struct pw_stream *stream, direction == PW_DIRECTION_INPUT ? "Input" : "Output", get_media_class(impl)); - state = pw_remote_get_state(stream->remote, NULL); - impl->async_connect = (state == PW_REMOTE_STATE_UNCONNECTED || - state == PW_REMOTE_STATE_ERROR); + if (stream->core_proxy == NULL) { + stream->core_proxy = pw_core_connect(impl->core, + pw_properties_copy(stream->properties), 0); + if (stream->core_proxy == NULL) { + res = -errno; + goto error_connect; + } + pw_core_proxy_add_listener(stream->core_proxy, + &stream->core_listener, &core_events, stream); + } - if (impl->async_connect) - res = pw_remote_connect(stream->remote); - else - res = handle_connect(stream); + pw_log_debug(NAME" %p: creating node", stream); + props = pw_properties_copy(stream->properties); + if ((str = pw_properties_get(props, PW_KEY_STREAM_MONITOR)) && + pw_properties_parse_bool(str)) { + pw_properties_set(props, "resample.peaks", "1"); + } + + slave = pw_node_new(impl->core, pw_properties_copy(props), 0); + if (slave == NULL) { + res = -errno; + goto error_node; + } + + pw_node_set_implementation(slave, &impl->impl_node); + + if (!SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_INACTIVE)) + pw_node_set_active(slave, true); + + if (impl->media_type == SPA_MEDIA_TYPE_audio && + impl->media_subtype == SPA_MEDIA_SUBTYPE_raw) { + factory = pw_core_find_factory(impl->core, "adapter"); + if (factory == NULL) { + pw_log_error(NAME" %p: no adapter factory found", stream); + res = -ENOENT; + goto error_node; + } + pw_properties_setf(props, "adapt.slave.node", "pointer:%p", slave); + impl->node = pw_factory_create_object(factory, + NULL, + PW_TYPE_INTERFACE_Node, + PW_VERSION_NODE_PROXY, + props, + 0); + if (impl->node == NULL) { + res = -errno; + goto error_node; + } + } else { + impl->node = slave; + } + + pw_log_debug(NAME" %p: export node %p", stream, impl->node); + stream->proxy = pw_core_proxy_export(stream->core_proxy, + PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); + if (stream->proxy == NULL) { + res = -errno; + goto error_proxy; + } + + pw_proxy_add_listener(stream->proxy, &stream->proxy_listener, &proxy_events, stream); + + + pw_node_add_listener(impl->node, &stream->node_listener, &node_events, stream); + + return 0; + +error_connect: + pw_log_error(NAME" %p: can't connect: %s", stream, spa_strerror(res)); + return res; +error_node: + pw_log_error(NAME" %p: can't make node: %s", stream, spa_strerror(res)); + return res; +error_proxy: + pw_log_error(NAME" %p: can't make proxy: %s", stream, spa_strerror(res)); return res; } diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index 75ab4f586..342343679 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -247,7 +247,7 @@ enum pw_stream_flags { /** Create a new unconneced \ref pw_stream \memberof pw_stream * \return a newly allocated \ref pw_stream */ struct pw_stream * -pw_stream_new(struct pw_remote *remote, /**< a \ref pw_remote */ +pw_stream_new(struct pw_core_proxy *proxy, /**< a \ref pw_core_proxy */ const char *name, /**< a stream media name */ struct pw_properties *props /**< stream properties, ownership is taken */); @@ -270,7 +270,7 @@ enum pw_stream_state pw_stream_get_state(struct pw_stream *stream, const char ** const char *pw_stream_get_name(struct pw_stream *stream); -struct pw_remote *pw_stream_get_remote(struct pw_stream *stream); +struct pw_core_proxy *pw_stream_get_core_proxy(struct pw_stream *stream); const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream); diff --git a/src/tests/test-stream.c b/src/tests/test-stream.c index bc73d75b3..aea797eed 100644 --- a/src/tests/test-stream.c +++ b/src/tests/test-stream.c @@ -134,7 +134,6 @@ static void test_create(void) { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; struct pw_stream *stream; struct pw_stream_events stream_events = stream_events_error; struct spa_hook listener = { 0, }; @@ -143,8 +142,7 @@ static void test_create(void) loop = pw_main_loop_new(NULL); core = pw_core_new(pw_main_loop_get_loop(loop), NULL, 12); - remote = pw_remote_new(core, NULL, 12); - stream = pw_stream_new(remote, "test", NULL); + stream = pw_stream_new(NULL, "test", NULL); spa_assert(stream != NULL); pw_stream_add_listener(stream, &listener, &stream_events, stream); @@ -153,8 +151,6 @@ static void test_create(void) spa_assert(error == NULL); /* check name */ spa_assert(!strcmp(pw_stream_get_name(stream), "test")); - /* check remote */ - spa_assert(pw_stream_get_remote(stream) == remote); /* check id, only when connected */ spa_assert(pw_stream_get_node_id(stream) == SPA_ID_INVALID); @@ -184,7 +180,6 @@ static void test_properties(void) struct pw_main_loop *loop; struct pw_core *core; const struct pw_properties *props; - struct pw_remote *remote; struct pw_stream *stream; struct pw_stream_events stream_events = stream_events_error; struct spa_hook listener = { NULL, }; @@ -192,8 +187,7 @@ static void test_properties(void) loop = pw_main_loop_new(NULL); core = pw_core_new(pw_main_loop_get_loop(loop), NULL, 0); - remote = pw_remote_new(core, NULL, 0); - stream = pw_stream_new(remote, "test", + stream = pw_stream_new(NULL, "test", pw_properties_new("foo", "bar", "biz", "fuzz", NULL)); diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 4b880f2c3..34d61db8b 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -71,12 +72,11 @@ struct remote_data { char *name; uint32_t id; - struct pw_remote *remote; - struct spa_hook remote_listener; int prompt_pending; struct pw_core_proxy *core_proxy; struct spa_hook core_listener; + struct spa_hook core_proxy_listener; struct pw_registry_proxy *registry_proxy; struct spa_hook registry_listener; @@ -370,7 +370,27 @@ static const struct pw_registry_proxy_events registry_events = { .global_remove = registry_event_global_remove, }; -static void on_remote_destroy(void *_data) +static void on_core_error(void *_data, uint32_t id, int seq, int res, const char *message) +{ + struct remote_data *rd = _data; + struct data *data = rd->data; + + pw_log_error("remote %p: error id:%u seq:%d res:%d (%s): %s", rd, + id, seq, res, spa_strerror(res), message); + + if (id == 0) { + pw_main_loop_quit(data->loop); + } +} + +static const struct pw_core_proxy_events remote_core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .info = on_core_info, + .done = on_core_done, + .error = on_core_error, +}; + +static void on_core_destroy(void *_data) { struct remote_data *rd = _data; struct data *data = rd->data; @@ -385,78 +405,49 @@ static void on_remote_destroy(void *_data) free(rd->name); } -static const struct pw_core_proxy_events remote_core_events = { - PW_VERSION_CORE_EVENTS, - .info = on_core_info, - .done = on_core_done, +static const struct pw_proxy_events core_proxy_events = { + PW_VERSION_PROXY_EVENTS, + .destroy = on_core_destroy, }; -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) -{ - struct remote_data *rd = _data; - struct data *data = rd->data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - fprintf(stderr, "remote %d error: %s\n", rd->id, error); - pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state)); - rd->core_proxy = pw_remote_get_core_proxy(rd->remote); - pw_core_proxy_add_listener(rd->core_proxy, - &rd->core_listener, - &remote_core_events, rd); - rd->registry_proxy = pw_core_proxy_get_registry(rd->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(rd->registry_proxy, - &rd->registry_listener, - ®istry_events, rd); - rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0, 0); - break; - - default: - fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state)); - break; - } -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .destroy = on_remote_destroy, - .state_changed = on_state_changed, -}; - - static bool do_connect(struct data *data, const char *cmd, char *args, char **error) { char *a[1]; int n; - struct pw_remote *remote; struct pw_properties *props = NULL; + struct pw_core_proxy *core_proxy; struct remote_data *rd; n = pw_split_ip(args, WHITESPACE, 1, a); if (n == 1) { props = pw_properties_new(PW_KEY_REMOTE_NAME, a[0], NULL); } - remote = pw_remote_new(data->core, props, sizeof(struct remote_data)); + core_proxy = pw_core_connect(data->core, props, sizeof(struct remote_data)); + if (core_proxy == NULL) + return false; - rd = pw_remote_get_user_data(remote); - rd->remote = remote; + rd = pw_proxy_get_user_data((struct pw_proxy*)core_proxy); + rd->core_proxy = core_proxy; rd->data = data; pw_map_init(&rd->globals, 64, 16); rd->id = pw_map_insert_new(&data->vars, rd); spa_list_append(&data->remotes, &rd->link); - fprintf(stdout, "%d = @remote:%p\n", rd->id, remote); + fprintf(stdout, "%d = @remote:%p\n", rd->id, rd->core_proxy); data->current = rd; - pw_remote_add_listener(remote, &rd->remote_listener, &remote_events, rd); - if (pw_remote_connect(remote) < 0) - return false; + pw_core_proxy_add_listener(rd->core_proxy, + &rd->core_listener, + &remote_core_events, rd); + pw_proxy_add_listener((struct pw_proxy*)rd->core_proxy, + &rd->core_proxy_listener, + &core_proxy_events, rd); + rd->registry_proxy = pw_core_proxy_get_registry(rd->core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(rd->registry_proxy, + &rd->registry_listener, + ®istry_events, rd); + rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0, 0); return true; } @@ -476,8 +467,7 @@ static bool do_disconnect(struct data *data, const char *cmd, char *args, char * goto no_remote; } - pw_remote_disconnect(rd->remote); - pw_remote_destroy(rd->remote); + pw_core_proxy_disconnect(rd->core_proxy); if (data->current == NULL) { if (spa_list_is_empty(&data->remotes)) { @@ -498,7 +488,7 @@ static bool do_list_remotes(struct data *data, const char *cmd, char *args, char struct remote_data *rd; spa_list_for_each(rd, &data->remotes, link) - fprintf(stdout, "\t%d = @remote:%p '%s'\n", rd->id, rd->remote, rd->name); + fprintf(stdout, "\t%d = @remote:%p '%s'\n", rd->id, rd->core_proxy, rd->name); return true; } @@ -1428,7 +1418,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char return false; } node = pw_global_get_object(global); - proxy = pw_remote_export(rd->remote, PW_TYPE_INTERFACE_Node, NULL, node, 0); + proxy = pw_core_proxy_export(rd->core_proxy, PW_TYPE_INTERFACE_Node, NULL, node, 0); id = pw_map_insert_new(&data->vars, proxy); fprintf(stdout, "%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); diff --git a/src/tools/pipewire-dot.c b/src/tools/pipewire-dot.c index ebd121d2a..86f583c26 100644 --- a/src/tools/pipewire-dot.c +++ b/src/tools/pipewire-dot.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -48,9 +49,6 @@ struct data { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; struct spa_hook core_listener; @@ -711,42 +709,22 @@ static void on_core_done(void *data, uint32_t id, int seq) pw_main_loop_quit(d->loop); } -static const struct pw_core_proxy_events core_events = { - PW_VERSION_CORE_EVENTS, - .done = on_core_done, -}; - -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; + struct data *d = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - case PW_REMOTE_STATE_CONNECTED: - data->core_proxy = pw_remote_get_core_proxy(data->remote); - pw_core_proxy_add_listener(data->core_proxy, - &data->core_listener, - &core_events, data); - data->registry_proxy = pw_core_proxy_get_registry(data->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(data->registry_proxy, - &data->registry_listener, - ®istry_events, data); - break; - - default: - break; + if (id == 0) { + pw_main_loop_quit(d->loop); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .done = on_core_done, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -843,12 +821,8 @@ int main(int argc, char *argv[]) if (remote_name) props = pw_properties_new(PW_KEY_REMOTE_NAME, remote_name, NULL); - data.remote = pw_remote_new(data.core, props, 0); - if (data.remote == NULL) - return -1; - - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); - if (pw_remote_connect(data.remote) < 0) + data.core_proxy = pw_core_connect(data.core, props, 0); + if (data.core_proxy == NULL) return -1; data.dot_str = dot_str_new(); @@ -857,12 +831,20 @@ int main(int argc, char *argv[]) spa_list_init(&data.globals); + pw_core_proxy_add_listener(data.core_proxy, + &data.core_listener, + &core_events, &data); + data.registry_proxy = pw_core_proxy_get_registry(data.core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(data.registry_proxy, + &data.registry_listener, + ®istry_events, &data); + pw_main_loop_run(data.loop); draw_graph(&data, dot_path); dot_str_clear(&data.dot_str); - pw_remote_destroy(data.remote); pw_core_destroy(data.core); pw_main_loop_destroy(data.loop); diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 822dae0d0..1394464f4 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -25,13 +25,13 @@ #include #include +#include #include #include #include #include #include -#include #include #include @@ -50,9 +50,6 @@ struct data { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; struct spa_hook core_listener; @@ -670,46 +667,22 @@ static const struct pw_registry_proxy_events registry_events = { .global_remove = registry_event_global_remove, }; -static const struct pw_core_proxy_events core_events = { - PW_VERSION_CORE_EVENTS, - .info = on_core_info, - .done = on_core_done, -}; - -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *_data, uint32_t id, int seq, int res, const char *message) { struct data *data = _data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + if (id == 0) { pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - - data->core_proxy = pw_remote_get_core_proxy(data->remote); - pw_core_proxy_add_listener(data->core_proxy, - &data->core_listener, - &core_events, data); - data->registry_proxy = pw_core_proxy_get_registry(data->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(data->registry_proxy, - &data->registry_listener, - ®istry_events, data); - 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 const struct pw_core_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .info = on_core_info, + .done = on_core_done, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -741,19 +714,23 @@ int main(int argc, char *argv[]) if (argc > 1) props = pw_properties_new(PW_KEY_REMOTE_NAME, argv[1], NULL); - data.remote = pw_remote_new(data.core, props, 0); - if (data.remote == NULL) - return -1; - - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); - if (pw_remote_connect(data.remote) < 0) - return -1; - spa_list_init(&data.pending_list); + data.core_proxy = pw_core_connect(data.core, props, 0); + if (data.core_proxy == NULL) + return -1; + + pw_core_proxy_add_listener(data.core_proxy, + &data.core_listener, + &core_events, &data); + data.registry_proxy = pw_core_proxy_get_registry(data.core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(data.registry_proxy, + &data.registry_listener, + ®istry_events, &data); + pw_main_loop_run(data.loop); - pw_remote_destroy(data.remote); pw_core_destroy(data.core); pw_main_loop_destroy(data.loop);