summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2019-12-05 10:28:19 +0100
committerWim Taymans <wtaymans@redhat.com>2019-12-05 10:28:19 +0100
commitf1c7ebc79160b45578c3393060a006fc62e930d6 (patch)
tree93448ef00c4228fa144b12ee4f34638f5f04fda6
parent4314fba7c4e245c1089b8937dbddfa9f227463d4 (diff)
More API experimentsAPI2
Try to hide the pw_remote, we don't really need it
-rw-r--r--doc/pulseaudio.md6
-rw-r--r--pipewire-alsa/alsa-plugins/pcm_pipewire.c98
-rw-r--r--pipewire-pulseaudio/src/context.c5
-rw-r--r--pipewire-pulseaudio/src/internal.h2
-rw-r--r--pipewire-pulseaudio/src/stream.c4
-rw-r--r--src/examples/bluez-session.c60
-rw-r--r--src/examples/export-sink.c75
-rw-r--r--src/examples/export-source.c43
-rw-r--r--src/examples/export-spa-device.c50
-rw-r--r--src/examples/export-spa.c50
-rw-r--r--src/examples/media-session/media-session.c4
-rw-r--r--src/examples/video-src.c109
-rw-r--r--src/gst/gstpipewiredeviceprovider.c2
-rw-r--r--src/gst/gstpipewiresink.c76
-rw-r--r--src/gst/gstpipewiresink.h3
-rw-r--r--src/gst/gstpipewiresrc.c75
-rw-r--r--src/gst/gstpipewiresrc.h3
-rw-r--r--src/modules/module-client-device.c5
-rw-r--r--src/modules/module-client-device/proxy-device.c9
-rw-r--r--src/modules/module-client-node.c8
-rw-r--r--src/modules/module-client-node/remote-node.c16
-rw-r--r--src/modules/module-metadata.c4
-rw-r--r--src/modules/module-metadata/proxy-metadata.c8
-rw-r--r--src/modules/module-protocol-native.c32
-rw-r--r--src/modules/module-protocol-native/connection.c6
-rw-r--r--src/modules/module-protocol-native/connection.h2
-rw-r--r--src/modules/module-protocol-native/defs.h10
-rw-r--r--src/modules/module-protocol-native/local-socket.c11
-rw-r--r--src/pipewire/core-proxy.c179
-rw-r--r--src/pipewire/core-proxy.h103
-rw-r--r--src/pipewire/core.c20
-rw-r--r--src/pipewire/core.h17
-rw-r--r--src/pipewire/filter.c2
-rw-r--r--src/pipewire/interfaces.h8
-rw-r--r--src/pipewire/introspect.c2
-rw-r--r--src/pipewire/meson.build2
-rw-r--r--src/pipewire/pipewire.h2
-rw-r--r--src/pipewire/private.h2
-rw-r--r--src/pipewire/protocol.c6
-rw-r--r--src/pipewire/protocol.h8
-rw-r--r--src/pipewire/proxy.c6
-rw-r--r--src/pipewire/proxy.h3
-rw-r--r--src/pipewire/remote.c120
-rw-r--r--src/pipewire/remote.h20
-rw-r--r--src/pipewire/stream.c20
-rw-r--r--src/pipewire/stream.h9
-rw-r--r--src/tests/test-stream.c14
-rw-r--r--src/tools/pipewire-cli.c92
-rw-r--r--src/tools/pipewire-dot.c69
-rw-r--r--src/tools/pipewire-monitor.c68
50 files changed, 793 insertions, 755 deletions
diff --git a/doc/pulseaudio.md b/doc/pulseaudio.md
index 51f49260..4a0226c9 100644
--- a/doc/pulseaudio.md
+++ b/doc/pulseaudio.md
@@ -12,6 +12,7 @@ An ALSA card is exposed as a PipeWire device
Each alsa PCM is opened and a Node is created for each PCM stream.
+
# Session Manager
## ALSA UCM
@@ -65,4 +66,9 @@ only one profile is selected on the device, only 1 stream is visible on
the endpoint. This clashes with the notion that multiple streams can be
active at the same time but is a pulseaudio limitation.
+
+
+
+
+
Each Endpoint destination becomes a port on the sink/source.
diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c
index a55d1029..e66fc20d 100644
--- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c
+++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c
@@ -40,6 +40,8 @@
#include <pipewire/pipewire.h>
+#define NAME "alsa-plugin"
+
#define MIN_BUFFERS 3u
#define MAX_BUFFERS 64u
@@ -68,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;
@@ -193,7 +195,7 @@ snd_pcm_pipewire_process_playback(snd_pcm_pipewire_t *pw, struct pw_buffer *b)
ptr = SPA_MEMBER(d[0].data, offset, void);
nframes = nbytes / bpf;
- pw_log_trace("%d %d %lu %d %d %p %d", nbytes, avail, nframes, filled, offset, ptr, io->state);
+ pw_log_trace(NAME" %p: %d %d %lu %d %d %p %d", pw, nbytes, avail, nframes, filled, offset, ptr, io->state);
for (channel = 0; channel < io->channels; channel++) {
pwareas[channel].addr = ptr;
@@ -202,7 +204,7 @@ snd_pcm_pipewire_process_playback(snd_pcm_pipewire_t *pw, struct pw_buffer *b)
}
if (io->state != SND_PCM_STATE_RUNNING && io->state != SND_PCM_STATE_DRAINING) {
- pw_log_trace("silence %lu frames %d", nframes, io->state);
+ pw_log_trace(NAME" %p: silence %lu frames %d", pw, nframes, io->state);
for (channel = 0; channel < io->channels; channel++)
snd_pcm_area_silence(&pwareas[channel], 0, nframes, io->format);
goto done;
@@ -272,7 +274,7 @@ snd_pcm_pipewire_process_record(snd_pcm_pipewire_t *pw, struct pw_buffer *b)
nbytes = SPA_MIN(avail, maxsize - offset);
ptr = SPA_MEMBER(d[0].data, offset, void);
- pw_log_trace("%d %d %d %p", nbytes, avail, offset, ptr);
+ pw_log_trace(NAME" %p: %d %d %d %p", pw, nbytes, avail, offset, ptr);
nframes = nbytes / bpf;
for (channel = 0; channel < io->channels; channel++) {
@@ -329,8 +331,8 @@ static void on_stream_param_changed(void *data, uint32_t id, const struct spa_po
buffers = SPA_CLAMP(io->buffer_size / io->period_size, MIN_BUFFERS, MAX_BUFFERS);
size = io->period_size * stride;
- pw_log_info("buffer_size:%lu period_size:%lu buffers:%u stride:%u size:%u min_avail:%lu",
- io->buffer_size, io->period_size, buffers, stride, size, pw->min_avail);
+ pw_log_info(NAME" %p: buffer_size:%lu period_size:%lu buffers:%u stride:%u size:%u min_avail:%lu",
+ pw, io->buffer_size, io->period_size, buffers, stride, size, pw->min_avail);
params[n_params++] = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
@@ -389,7 +391,7 @@ static int snd_pcm_pipewire_prepare(snd_pcm_ioplug_t *io)
min_period = (MIN_PERIOD * io->rate / 48000);
pw->min_avail = SPA_MAX(pw->min_avail, min_period);
- pw_log_debug("prepare %d %p %lu %ld", pw->error, pw->stream, io->period_size, pw->min_avail);
+ pw_log_debug(NAME" %p: prepare %d %p %lu %ld", pw, pw->error, pw->stream, io->period_size, pw->min_avail);
if (!pw->error && pw->stream != NULL)
goto done;
@@ -407,7 +409,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;
@@ -519,7 +521,7 @@ static int snd_pcm_pipewire_hw_params(snd_pcm_ioplug_t * io,
snd_pcm_pipewire_t *pw = io->private_data;
bool planar;
- pw_log_debug("hw_params %lu %lu", io->buffer_size, io->period_size);
+ pw_log_debug(NAME" %p: hw_params %lu %lu", pw, io->buffer_size, io->period_size);
switch(io->access) {
case SND_PCM_ACCESS_MMAP_INTERLEAVED:
@@ -747,66 +749,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("error %s", 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,
@@ -827,7 +789,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name,
str = getenv("PIPEWIRE_NODE");
- pw_log_debug("open %s %d %d %08x '%s'", name, stream, mode, flags, str);
+ pw_log_debug(NAME" %p: open %s %d %d %08x '%s'", pw, name, stream, mode, flags, str);
pw->fd = -1;
pw->io.poll_fd = -1;
@@ -860,14 +822,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) {
+ pw_thread_loop_unlock(pw->main_loop);
+ err = -errno;
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);
@@ -882,7 +848,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name,
if ((err = snd_pcm_ioplug_create(&pw->io, name, stream, mode)) < 0)
goto error;
- pw_log_debug("open %s %d %d", name, pw->io.stream, mode);
+ pw_log_debug(NAME" %p: open %s %d %d", pw, name, pw->io.stream, mode);
if ((err = pipewire_set_hw_constraint(pw)) < 0)
goto error;
diff --git a/pipewire-pulseaudio/src/context.c b/pipewire-pulseaudio/src/context.c
index 0ebea4ef..f374d3a2 100644
--- a/pipewire-pulseaudio/src/context.c
+++ b/pipewire-pulseaudio/src/context.c
@@ -22,6 +22,7 @@
#include <spa/param/props.h>
#include <pipewire/pipewire.h>
+#include <pipewire/remote.h>
#include <pulse/context.h>
#include <pulse/timeval.h>
@@ -29,12 +30,12 @@
#include "internal.h"
-int pa_context_set_error(pa_context *c, int error) {
+int pa_context_set_error(PA_CONST pa_context *c, int error) {
pa_assert(error >= 0);
pa_assert(error < PA_ERR_MAX);
if (c && c->error != error) {
pw_log_debug("context %p: error %d %s", c, error, pa_strerror(error));
- c->error = error;
+ ((pa_context*)c)->error = error;
}
return error;
}
diff --git a/pipewire-pulseaudio/src/internal.h b/pipewire-pulseaudio/src/internal.h
index fd80d8b8..c9feb26a 100644
--- a/pipewire-pulseaudio/src/internal.h
+++ b/pipewire-pulseaudio/src/internal.h
@@ -127,7 +127,7 @@ static inline const char *pa_strnull(const char *x) {
return x ? x : "(null)";
}
-int pa_context_set_error(pa_context *c, int error);
+int pa_context_set_error(PA_CONST pa_context *c, int error);
#define PA_CHECK_VALIDITY(context, expression, error) \
do { \
diff --git a/pipewire-pulseaudio/src/stream.c b/pipewire-pulseaudio/src/stream.c
index f5207fc5..4ea40964 100644
--- a/pipewire-pulseaudio/src/stream.c
+++ b/pipewire-pulseaudio/src/stream.c
@@ -28,7 +28,9 @@
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
+#include <pipewire/introspect.h>
#include <pipewire/stream.h>
+#include <pipewire/remote.h>
#include <pipewire/keys.h>
#include "core-format.h"
#include "internal.h"
@@ -554,7 +556,7 @@ 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->stream = pw_stream_new(c->core_proxy, name, props);
s->refcount = 1;
s->context = c;
spa_list_init(&s->pending);
diff --git a/src/examples/bluez-session.c b/src/examples/bluez-session.c
index aafef325..b4f5ef78 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,37 @@ 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;
-
- 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);
- if ((res = start_monitor(impl)) < 0) {
- pw_log_debug("error starting monitor: %s", spa_strerror(res));
- pw_main_loop_quit(impl->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_UNCONNECTED:
- pw_log_info(NAME" %p: disconnected", impl);
+ if (id == 0) {
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);
+ impl.core_proxy = pw_core_connect(impl.core, NULL, 0);
+ if (impl.core_proxy == NULL)
+ return -1;
+
+ spa_list_init(&impl.device_list);
pw_core_add_spa_lib(impl.core, "api.bluez5.*", "bluez5/libspa-bluez5");
@@ -389,15 +376,14 @@ int main(int argc, char *argv[])
clock_gettime(CLOCK_MONOTONIC, &impl.now);
- spa_list_init(&impl.device_list);
-
- pw_remote_add_listener(impl.remote,
- &impl.remote_listener,
- &remote_events, &impl);
+ pw_core_proxy_add_listener(impl.core_proxy,
+ &impl.core_listener,
+ &core_events, &impl);
- if (pw_remote_connect(impl.remote) < 0)
+ if ((res = start_monitor(&impl)) < 0) {
+ pw_log_debug("error starting monitor: %s", spa_strerror(res));
return -1;
-
+ }
pw_main_loop_run(impl.loop);
pw_core_destroy(impl.core);
diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c
index d2e626d6..d617efec 100644
--- a/src/examples/export-sink.c
+++ b/src/examples/export-sink.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <sys/mman.h>
+#include <spa/utils/result.h>
#include <spa/param/video/format-utils.h>
#include <spa/param/props.h>
#include <spa/node/utils.h>
@@ -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;
-
- 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:
- {
- struct pw_permission permissions[2];
+ struct pw_permission permissions[2];
+
+ /* 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;
+
+ 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 *data = _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(data->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,12 @@ 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.core_proxy = pw_core_connect(data.core, NULL, 0);
+ if (data.core_proxy == NULL)
+ return -1;
+
+ pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data);
+
data.path = argc > 1 ? argv[1] : NULL;
spa_hook_list_init(&data.hooks);
@@ -554,10 +554,9 @@ int main(int argc, char *argv[])
return -1;
}
- pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
+ set_permissions(&data);
- if (pw_remote_connect(data.remote) < 0)
- return -1;
+ make_node(&data);
pw_main_loop_run(data.loop);
diff --git a/src/examples/export-source.c b/src/examples/export-source.c
index e4c426b0..270e8a06 100644
--- a/src/examples/export-source.c
+++ b/src/examples/export-source.c
@@ -27,6 +27,7 @@
#include <math.h>
#include <sys/mman.h>
+#include <spa/utils/result.h>
#include <spa/param/audio/format-utils.h>
#include <spa/param/props.h>
#include <spa/node/io.h>
@@ -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;
- 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(data->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,12 @@ 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.core_proxy = pw_core_connect(data.core, NULL, 0);
+ if (data.core_proxy == NULL)
+ return -1;
+
+ pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data);
+
data.path = argc > 1 ? argv[1] : NULL;
data.info_all = SPA_PORT_CHANGE_MASK_FLAGS |
@@ -540,9 +537,7 @@ 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);
-
- pw_remote_connect(data.remote);
+ 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 cc14a318..280577ef 100644
--- a/src/examples/export-spa-device.c
+++ b/src/examples/export-spa-device.c
@@ -26,6 +26,7 @@
#include <sys/mman.h>
#include <signal.h>
+#include <spa/utils/result.h>
#include <spa/param/video/format-utils.h>
#include <spa/param/props.h>
@@ -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;
-
- switch (state) {
- case PW_REMOTE_STATE_ERROR:
- printf("remote error: %s\n", error);
- pw_main_loop_quit(data->loop);
- break;
-
- case PW_REMOTE_STATE_CONNECTED:
- printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
- if (make_device(data) < 0) {
- pw_log_error("can't make device");
- pw_main_loop_quit(data->loop);
- }
- break;
-
- default:
- printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
- break;
+ struct data *d = _data;
+
+ 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(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,16 +112,19 @@ 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.core_proxy = pw_core_connect(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_module_load(data.core, "libpipewire-module-client-device", NULL, NULL);
- pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
+ pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data);
- pw_remote_connect(data.remote);
+ 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 7aef757f..77abff23 100644
--- a/src/examples/export-spa.c
+++ b/src/examples/export-spa.c
@@ -26,6 +26,7 @@
#include <sys/mman.h>
#include <signal.h>
+#include <spa/utils/result.h>
#include <spa/param/video/format-utils.h>
#include <spa/param/props.h>
@@ -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;
-
- switch (state) {
- case PW_REMOTE_STATE_ERROR:
- printf("remote error: %s\n", error);
- pw_main_loop_quit(data->loop);
- break;
-
- case PW_REMOTE_STATE_CONNECTED:
- printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
- if (make_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;
+ struct data *d = _data;
+
+ 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(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,7 @@ 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.core_proxy = pw_core_connect(data.core, NULL, 0);
data.library = argv[1];
data.factory = argv[2];
if (argc > 3)
@@ -163,9 +152,12 @@ 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);
+ 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 c4a0de3e..b98e8a37 100644
--- a/src/examples/media-session/media-session.c
+++ b/src/examples/media-session/media-session.c
@@ -1216,7 +1216,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_remote->core_proxy, type,
properties, object, user_data_size);
}
@@ -1229,7 +1229,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_remote->core_proxy, SPA_TYPE_INTERFACE_Device,
properties, object, sizeof(struct sm_device));
device = (struct sm_device *) create_object(impl, proxy, &properties->dict);
diff --git a/src/examples/video-src.c b/src/examples/video-src.c
index 35a81854..f76eb064 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,9 +185,17 @@ 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_UNCONNECTED:
+ case PW_STREAM_STATE_ERROR:
+ pw_main_loop_quit(data->loop);
+ break;
+
case PW_STREAM_STATE_PAUSED:
printf("node id: %d\n", pw_stream_get_node_id(data->stream));
+ pw_loop_update_timer(pw_main_loop_get_loop(data->loop),
+ data->timer, NULL, NULL, false);
break;
+
case PW_STREAM_STATE_STREAMING:
{
struct timespec timeout, interval;
@@ -203,8 +210,6 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum
break;
}
default:
- pw_loop_update_timer(pw_main_loop_get_loop(data->loop),
- data->timer, NULL, NULL, false);
break;
}
}
@@ -266,81 +271,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;
+
+ data.stream = pw_stream_new(data.core_proxy, "video-src",
+ pw_properties_new(
+ PW_KEY_MEDIA_CLASS, "Video/Source",
+ NULL));
- pw_remote_connect(data.remote);
+ 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 8283a805..4efefe29 100644
--- a/src/gst/gstpipewiredeviceprovider.c
+++ b/src/gst/gstpipewiredeviceprovider.c
@@ -28,6 +28,8 @@
#include <string.h>
+#include <pipewire/remote.h>
+
#include <gst/gst.h>
#include "gstpipewireformat.h"
diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c
index fa77fe3a..ae63cbb7 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);
@@ -804,11 +753,6 @@ gst_pipewire_sink_close (GstPipeWireSink * pwsink)
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 90866aba..75f6cf3a 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 cc27445d..08fce6ba 100644
--- a/src/gst/gstpipewiresrc.c
+++ b/src/gst/gstpipewiresrc.c
@@ -493,6 +493,7 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc)
{
const char *error = NULL;
pw_thread_loop_lock (pwsrc->main_loop);
+
GST_DEBUG_OBJECT (pwsrc, "doing stream start");
while (TRUE) {
enum pw_stream_state state = pw_stream_get_state (pwsrc->stream, &error);
@@ -504,9 +505,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 +540,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 +633,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 +907,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 +921,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,36 +934,19 @@ 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)
- goto connect_error;
-
- pw_thread_loop_wait (pwsrc->main_loop);
- }
+ if (pwsrc->core_proxy == NULL)
+ goto connect_error;
if (pwsrc->properties) {
props = pw_properties_new (NULL, NULL);
@@ -1005,16 +955,14 @@ 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;
-
pw_stream_add_listener(pwsrc->stream,
&pwsrc->stream_listener,
&stream_events,
pwsrc);
-
pwsrc->clock = gst_pipewire_clock_new (pwsrc->stream, pwsrc->last_time);
pw_thread_loop_unlock (pwsrc->main_loop);
@@ -1026,14 +974,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 +1008,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 14dc4261..af61ad9e 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 64091971..869c6325 100644
--- a/src/modules/module-client-device.c
+++ b/src/modules/module-client-device.c
@@ -32,6 +32,7 @@
#include <spa/utils/result.h>
#include <pipewire/pipewire.h>
+#include <pipewire/remote.h>
#include "module-client-device/client-device.h"
@@ -43,7 +44,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_remote *remote,
+struct pw_proxy *pw_core_proxy_spa_device_export(struct pw_core_proxy *core,
uint32_t type, struct pw_properties *props, void *object,
size_t user_data_size);
@@ -188,7 +189,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 ac30c602..6b4fc7dc 100644
--- a/src/modules/module-client-device/proxy-device.c
+++ b/src/modules/module-client-device/proxy-device.c
@@ -33,9 +33,6 @@
#include "pipewire/private.h"
struct device_data {
- struct pw_remote *remote;
- struct pw_core *core;
-
struct spa_device *device;
struct spa_hook device_listener;
struct spa_hook device_methods;
@@ -55,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_remote *remote,
+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)
{
@@ -64,7 +61,7 @@ struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote,
struct pw_proxy *proxy;
struct device_data *data;
- proxy = pw_core_proxy_create_object(remote->core_proxy,
+ proxy = pw_core_proxy_create_object(core_proxy,
"client-device",
SPA_TYPE_INTERFACE_Device,
SPA_VERSION_DEVICE,
@@ -77,9 +74,7 @@ struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote,
data = pw_proxy_get_user_data(proxy);
data = SPA_MEMBER(data, user_data_size, struct device_data);
- data->remote = remote;
data->device = device;
- data->core = pw_remote_get_core(remote);
data->proxy = proxy;
iface = (struct spa_interface*)proxy;
diff --git a/src/modules/module-client-node.c b/src/modules/module-client-node.c
index 5b470ab0..e7a8d697 100644
--- a/src/modules/module-client-node.c
+++ b/src/modules/module-client-node.c
@@ -44,9 +44,9 @@ static const struct spa_dict_item module_props[] = {
{ PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
};
-struct pw_proxy *pw_remote_node_export(struct pw_remote *remote,
+struct pw_proxy *pw_core_proxy_node_export(struct pw_core_proxy *core_proxy,
uint32_t type, struct pw_properties *props, void *object, size_t user_data_size);
-struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote,
+struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy,
uint32_t type, struct pw_properties *props, void *object, size_t user_data_size);
struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_core *core);
@@ -178,11 +178,11 @@ int pipewire__module_init(struct pw_module *module, const char *args)
pw_protocol_native_ext_client_node0_init(core);
data->export_node.type = PW_TYPE_INTERFACE_Node;
- data->export_node.func = pw_remote_node_export;
+ data->export_node.func = pw_core_proxy_node_export;
pw_core_register_export_type(core, &data->export_node);
data->export_spanode.type = SPA_TYPE_INTERFACE_Node;
- data->export_spanode.func = pw_remote_spa_node_export;
+ data->export_spanode.func = pw_core_proxy_spa_node_export;
pw_core_register_export_type(core, &data->export_spanode);
pw_module_add_listener(module, &data->module_listener, &module_events, data);
diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c
index a5ffcba4..3e1d7331 100644
--- a/src/modules/module-client-node/remote-node.c
+++ b/src/modules/module-client-node/remote-node.c
@@ -1104,7 +1104,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 +1112,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 +1122,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->remote = ((struct pw_proxy *)core_proxy)->remote;
data->node = node;
data->do_free = do_free;
data->core = pw_node_get_core(node);
@@ -1161,7 +1161,7 @@ static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool
return data->proxy;
}
-struct pw_proxy *pw_remote_node_export(struct pw_remote *remote,
+struct pw_proxy *pw_core_proxy_node_export(struct pw_core_proxy *core_proxy,
uint32_t type, struct pw_properties *props, void *object,
size_t user_data_size)
{
@@ -1171,16 +1171,16 @@ struct pw_proxy *pw_remote_node_export(struct pw_remote *remote,
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_remote_spa_node_export(struct pw_remote *remote,
+struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy,
uint32_t type, struct pw_properties *props, void *object,
size_t user_data_size)
{
struct pw_node *node;
- 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;
@@ -1188,5 +1188,5 @@ struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote,
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-metadata.c b/src/modules/module-metadata.c
index 1aaf1585..f475f694 100644
--- a/src/modules/module-metadata.c
+++ b/src/modules/module-metadata.c
@@ -46,7 +46,7 @@ static const struct spa_dict_item module_props[] = {
void * pw_metadata_new(struct pw_core *core, struct pw_resource *resource,
struct pw_properties *properties);
-struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote,
+struct pw_proxy *pw_core_proxy_metadata_export(struct pw_core_proxy *core_proxy,
uint32_t type, struct pw_properties *props, void *object, size_t user_data_size);
int pw_protocol_native_ext_metadata_init(struct pw_core *core);
@@ -174,7 +174,7 @@ int pipewire__module_init(struct pw_module *module, const char *args)
data);
data->export_metadata.type = PW_TYPE_INTERFACE_Metadata;
- data->export_metadata.func = pw_remote_metadata_export;
+ data->export_metadata.func = pw_core_proxy_metadata_export;
pw_core_register_export_type(core, &data->export_metadata);
pw_module_add_listener(module, &data->module_listener, &module_events, data);
diff --git a/src/modules/module-metadata/proxy-metadata.c b/src/modules/module-metadata/proxy-metadata.c
index ce224796..45989260 100644
--- a/src/modules/module-metadata/proxy-metadata.c
+++ b/src/modules/module-metadata/proxy-metadata.c
@@ -33,7 +33,6 @@
#include "extensions/metadata.h"
struct object_data {
- struct pw_remote *remote;
struct pw_core *core;
struct pw_metadata *object;
@@ -55,7 +54,7 @@ static const struct pw_proxy_events proxy_events = {
.destroy = object_proxy_destroy,
};
-struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote,
+struct pw_proxy *pw_core_proxy_metadata_export(struct pw_core_proxy *core_proxy,
uint32_t type, struct pw_properties *props, void *object,
size_t user_data_size)
{
@@ -64,7 +63,7 @@ struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote,
struct pw_proxy *proxy;
struct object_data *data;
- proxy = pw_core_proxy_create_object(remote->core_proxy,
+ proxy = pw_core_proxy_create_object(core_proxy,
"metadata",
PW_TYPE_INTERFACE_Metadata,
PW_VERSION_METADATA,
@@ -77,9 +76,8 @@ struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote,
data = pw_proxy_get_user_data(proxy);
data = SPA_MEMBER(data, user_data_size, struct object_data);
- data->remote = remote;
data->object = object;
- data->core = pw_remote_get_core(remote);
+ data->core = pw_core_proxy_get_core(core_proxy);
data->proxy = proxy;
iface = (struct spa_interface*)proxy;
diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c
index 6c54e26d..62817a31 100644
--- a/src/modules/module-protocol-native.c
+++ b/src/modules/module-protocol-native.c
@@ -80,6 +80,7 @@ struct protocol_data {
struct client {
struct pw_protocol_client this;
+ struct pw_remote *remote;
struct spa_source *source;
struct pw_protocol_native_connection *connection;
@@ -579,7 +580,7 @@ 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_remote *this = impl->remote;
struct pw_protocol_native_connection *conn = impl->connection;
struct pw_core *core = pw_remote_get_core(this);
int res;
@@ -667,6 +668,8 @@ 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,
+ 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);
impl->source = NULL;
pw_remote_disconnect(this);
@@ -676,7 +679,7 @@ error:
static void on_need_flush(void *data)
{
struct client *impl = data;
- struct pw_remote *remote = impl->this.remote;
+ struct pw_remote *remote = impl->remote;
if (!impl->flushing && impl->source) {
int mask = impl->source->mask;
@@ -695,17 +698,12 @@ 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;
+ struct pw_remote *remote = impl->remote;
int res;
impl->disconnecting = false;
- impl->connection = pw_protocol_native_connection_new(remote->core, fd);
- if (impl->connection == NULL) {
- res = -errno;
- goto error_cleanup;
- }
-
+ pw_protocol_native_connection_set_fd(impl->connection, fd);
impl->source = pw_loop_add_io(remote->core->main_loop,
fd,
SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR,
@@ -732,7 +730,7 @@ 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;
+ struct pw_remote *remote = impl->remote;
impl->disconnecting = true;
@@ -763,13 +761,14 @@ impl_new_client(struct pw_protocol *protocol,
struct client *impl;
struct pw_protocol_client *this;
const char *str = NULL;
+ int res;
if ((impl = calloc(1, sizeof(struct client))) == NULL)
return NULL;
this = &impl->this;
this->protocol = protocol;
- this->remote = remote;
+ impl->remote = remote;
if (properties)
str = pw_properties_get(properties, PW_KEY_REMOTE_INTENTION);
@@ -786,9 +785,20 @@ impl_new_client(struct pw_protocol *protocol,
this->disconnect = impl_disconnect;
this->destroy = impl_destroy;
+ impl->connection = pw_protocol_native_connection_new(remote->core, -1);
+ if (impl->connection == NULL) {
+ res = -errno;
+ goto error_free;
+ }
+
spa_list_append(&protocol->client_list, &this->link);
return this;
+
+error_free:
+ free(impl);
+ errno = -res;
+ return NULL;
}
static void destroy_server(struct pw_protocol_server *server)
diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c
index c3260fd5..2b26dbfc 100644
--- a/src/modules/module-protocol-native/connection.c
+++ b/src/modules/module-protocol-native/connection.c
@@ -266,6 +266,12 @@ no_mem:
return NULL;
}
+int pw_protocol_native_connection_set_fd(struct pw_protocol_native_connection *conn, int fd)
+{
+ conn->fd = fd;
+ return 0;
+}
+
/** Destroy a connection
*
* \param conn the connection to destroy
diff --git a/src/modules/module-protocol-native/connection.h b/src/modules/module-protocol-native/connection.h
index c4eb476b..4e37af4d 100644
--- a/src/modules/module-protocol-native/connection.h
+++ b/src/modules/module-protocol-native/connection.h
@@ -72,6 +72,8 @@ pw_protocol_native_connection_add_listener(struct pw_protocol_native_connection
struct pw_protocol_native_connection *
pw_protocol_native_connection_new(struct pw_core *core, int fd);
+int pw_protocol_native_connection_set_fd(struct pw_protocol_native_connection *conn, int fd);
+
void
pw_protocol_native_connection_destroy(struct pw_protocol_native_connection *conn);
diff --git a/src/modules/module-protocol-native/defs.h b/src/modules/module-protocol-native/defs.h
index 92f155c7..451c940d 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,
- void (*done_callback) (void *data, int res),
- void *data);
+ 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,
- void (*done_callback) (void *data, int res),
- void *data);
+ 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 49373347..8a85d30b 100644
--- a/src/modules/module-protocol-native/local-socket.c
+++ b/src/modules/module-protocol-native/local-socket.c
@@ -35,14 +35,15 @@
#include <sys/file.h>
#include <pipewire/pipewire.h>
+#include <pipewire/remote.h>
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 +52,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 +67,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/pipewire/core-proxy.c b/src/pipewire/core-proxy.c
new file mode 100644
index 00000000..1064af01
--- /dev/null
+++ b/src/pipewire/core-proxy.c
@@ -0,0 +1,179 @@
+/* PipeWire
+ *
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+#include <spa/pod/parser.h>
+#include <spa/debug/types.h>
+
+#include "pipewire/pipewire.h"
+#include "pipewire/private.h"
+
+#include "extensions/protocol-native.h"
+
+#define NAME "core-proxy"
+
+/** \cond */
+SPA_EXPORT
+struct pw_core_proxy *pw_core_connect(struct pw_core *core,
+ struct pw_properties *props, size_t user_data_size)
+{
+ struct pw_remote *remote;
+ int res;
+
+ remote = pw_remote_new(core, props, 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 *props, size_t user_data_size)
+{
+ struct pw_remote *remote;
+ int res;
+
+ remote = pw_remote_new(core, props, 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
+int pw_core_proxy_steal_fd(struct pw_core_proxy *proxy)
+{
+ struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote;
+ return pw_remote_steal_fd(remote);
+}
+
+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_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_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;
+}
+
+const struct pw_properties *pw_core_proxy_get_properties(struct pw_core_proxy *proxy)
+{
+ struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote;
+ return pw_remote_get_properties(remote);
+}
+
+SPA_EXPORT
+int pw_core_proxy_update_properties(struct pw_core_proxy *proxy, const struct spa_dict *dict)
+{
+ struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote;
+ return pw_remote_update_properties(remote, dict);
+}
+
+SPA_EXPORT
+void *pw_core_proxy_get_user_data(struct pw_core_proxy *proxy)
+{
+ struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote;
+ return pw_remote_get_user_data(remote);
+}
+
+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
+struct pw_proxy *pw_core_proxy_export(struct pw_core_proxy *proxy,
+ uint32_t type, struct pw_properties *props, void *object,
+ size_t user_data_size)
+{
+ struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote;
+ struct pw_core *core = remote->core;
+ struct pw_proxy *p;
+ const struct pw_export_type *t;
+ int res;
+
+ t = pw_core_find_export_type(core, type);
+ if (t == NULL) {
+ res = -EPROTO;
+ goto error_export_type;
+ }
+
+ p = t->func(proxy, type, props, object, user_data_size);
+ if (p == NULL) {
+ res = -errno;
+ goto error_proxy_failed;
+ }
+ return p;
+
+error_export_type:
+ pw_log_error(NAME" %p: can't export type %d: %s", core, type, spa_strerror(res));
+ goto exit_free;
+error_proxy_failed:
+ pw_log_error(NAME" %p: failed to create proxy: %s", core, spa_strerror(res));
+ goto exit;
+exit_free:
+ if (props)
+ pw_properties_free(props);
+exit:
+ errno = -res;
+ return NULL;
+}
diff --git a/src/pipewire/core-proxy.h b/src/pipewire/core-proxy.h
new file mode 100644
index 00000000..c256b06c
--- /dev/null
+++ b/src/pipewire/core-proxy.h
@@ -0,0 +1,103 @@
+/* PipeWire
+ *
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PIPEWIRE_CORE_PROXY_H
+#define PIPEWIRE_CORE_PROXY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <spa/utils/hook.h>
+
+/** \class pw_core_proxy
+ *
+ * \brief Represents a connection with a PipeWire instance
+ *
+ * a \ref pw_core_proxy is created when connecting to a PipeWire
+ * instance.
+ *
+ * See also \ref page_core_api
+ */
+#include <pipewire/core.h>
+#include <pipewire/properties.h>
+#include <pipewire/node.h>
+#include <pipewire/proxy.h>
+
+/** Create a new connected core_proxy
+ * \return a new connected core_proxy */
+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 */);
+
+/** Connect to a PipeWire instance on the given socket \memberof pw_core_proxy
+ * \param fd the connected socket to use, the socket will be closed
+ * automatically on disconnect or error.
+ * \return 0 on success, < 0 on error */
+struct pw_core_proxy *
+pw_core_connect_fd(struct pw_core *core, /**< a \ref pw_core */
+ int fd, /**< an fd to connect to */
+ struct pw_properties *properties, /**< optional properties, ownership of
+ * the properties is taken.*/
+ size_t user_data_size /**< extra user data size */);
+
+/** Steal the fd of the core_proxy connection or < 0 on error. The core_proxy
+ * will be disconnected after this call. */
+int pw_core_proxy_steal_fd(struct pw_core_proxy *core_proxy);
+
+/** disconnect and destroy a core_proxy \memberof pw_core_proxy */
+int pw_core_proxy_disconnect(struct pw_core_proxy *core_proxy);
+
+/** Get the core used to construct this core_proxy */
+struct pw_core *pw_core_proxy_get_core(struct pw_core_proxy *core_proxy);
+
+/** Get the core_proxy properties */
+const struct pw_properties *pw_core_proxy_get_properties(struct pw_core_proxy *core_proxy);
+
+/** Update properties */
+int pw_core_proxy_update_properties(struct pw_core_proxy *core_proxy, const struct spa_dict *dict);
+
+/** Get the user_data. The size was given in \ref pw_core_connect */
+void *pw_core_proxy_get_user_data(struct pw_core_proxy *core_proxy);
+
+/** Get the client proxy */
+struct pw_client_proxy * pw_core_proxy_get_client_proxy(struct pw_core_proxy *core_proxy);
+
+/** Get the proxy with the given id */
+struct pw_proxy *pw_core_proxy_find_proxy(struct pw_core_proxy *core_proxy, uint32_t id);
+
+/** run a local object in the given PipeWire instance */
+struct pw_proxy *pw_core_proxy_export(struct pw_core_proxy *proxy, /**< a core 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
+
+#endif /* PIPEWIRE_CORE_PROXY_H */
diff --git a/src/pipewire/core.c b/src/pipewire/core.c
index 3459237d..1719817e 100644
--- a/src/pipewire/core.c
+++ b/src/pipewire/core.c
@@ -731,6 +731,26 @@ struct pw_loop *pw_core_get_main_loop(struct pw_core *core)
}
SPA_EXPORT
+int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type)
+{
+ pw_log_debug("core %p: Add export type %d/%s to core", core, type->type,
+ spa_debug_type_find_name(pw_type_info(), type->type));
+ spa_list_append(&core->export_list, &type->link);
+ return 0;
+}
+
+SPA_EXPORT
+const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type)
+{
+ const struct pw_export_type *t;
+ spa_list_for_each(t, &core->export_list, link) {
+ if (t->type == type)
+ return t;
+ }
+ return NULL;
+}
+
+SPA_EXPORT
const struct pw_properties *pw_core_get_properties(struct pw_core *core)
{
return core->properties;
diff --git a/src/pipewire/core.h b/src/pipewire/core.h
index 7fdce82e..0ba45cc9 100644
--- a/src/pipewire/core.h
+++ b/src/pipewire/core.h
@@ -44,6 +44,7 @@ struct pw_core;
#include <pipewire/client.h>
#include <pipewire/introspect.h>
+#include <pipewire/interfaces.h>
#include <pipewire/global.h>
#include <pipewire/loop.h>
#include <pipewire/factory.h>
@@ -157,6 +158,22 @@ struct spa_handle *pw_core_load_spa_handle(struct pw_core *core,
const char *factory_name,
const struct spa_dict *info);
+
+/** data for registering export functions */
+struct pw_export_type {
+ struct spa_list link;
+ uint32_t type;
+ struct pw_proxy * (*func) (struct pw_core_proxy *proxy,
+ uint32_t type, struct pw_properties *properties, void *object,
+ size_t user_data_size);
+};
+
+/** register a type that can be exported on a core_proxy. This is usually used by
+ * extension modules */
+int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type);
+/** find information about registered export type */
+const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c
index 2124bed1..fe7a4a00 100644
--- a/src/pipewire/filter.c
+++ b/src/pipewire/filter.c
@@ -902,7 +902,7 @@ static int handle_connect(struct pw_filter *filter)
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,
+ filter->proxy = pw_core_proxy_export(filter->remote->core_proxy,
PW_TYPE_INTERFACE_Node, NULL, impl->node, 0);
if (filter->proxy == NULL) {
res = -errno;
diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h
index 40e826e6..1b222b2b 100644
--- a/src/pipewire/interfaces.h
+++ b/src/pipewire/interfaces.h
@@ -37,10 +37,6 @@ extern "C" {
#include <spa/node/command.h>
#include <spa/param/param.h>
-#include <pipewire/introspect.h>
-#include <pipewire/proxy.h>
-#include <pipewire/permission.h>
-
#define PW_VERSION_CORE_PROXY 3
struct pw_core_proxy { struct spa_interface iface; };
#define PW_VERSION_REGISTRY_PROXY 3
@@ -60,6 +56,10 @@ struct pw_client_proxy { struct spa_interface iface; };
#define PW_VERSION_LINK_PROXY 3
struct pw_link_proxy { struct spa_interface iface; };
+#include <pipewire/introspect.h>
+#include <pipewire/proxy.h>
+#include <pipewire/permission.h>
+
/**
* \page page_pipewire_protocol The PipeWire protocol
* \section page_ifaces_pipewire Interfaces
diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c
index d8f6442b..9164751d 100644
--- a/src/pipewire/introspect.c
+++ b/src/pipewire/introspect.c
@@ -28,8 +28,6 @@
#include "pipewire/pipewire.h"
-#include "pipewire/remote.h"
-
SPA_EXPORT
const char *pw_node_state_as_string(enum pw_node_state state)
{
diff --git a/src/pipewire/meson.build b/src/pipewire/meson.build
index 357531b2..c22ef73a 100644
--- a/src/pipewire/meson.build
+++ b/src/pipewire/meson.build
@@ -4,6 +4,7 @@ pipewire_headers = [
'client.h',
'control.h',
'core.h',
+ 'core-proxy.h',
'data-loop.h',
'device.h',
'filter.h',
@@ -40,6 +41,7 @@ pipewire_sources = [
'client.c',
'control.c',
'core.c',
+ 'core-proxy.c',
'data-loop.c',
'device.c',
'filter.c',
diff --git a/src/pipewire/pipewire.h b/src/pipewire/pipewire.h
index 3a0a1441..9aeb85d5 100644
--- a/src/pipewire/pipewire.h
+++ b/src/pipewire/pipewire.h
@@ -33,6 +33,7 @@ extern "C" {
#include <pipewire/client.h>
#include <pipewire/core.h>
+#include <pipewire/core-proxy.h>
#include <pipewire/device.h>
#include <pipewire/interfaces.h>
#include <pipewire/introspect.h>
@@ -47,7 +48,6 @@ extern "C" {
#include <pipewire/port.h>
#include <pipewire/properties.h>
#include <pipewire/proxy.h>
-#include <pipewire/remote.h>
#include <pipewire/resource.h>
#include <pipewire/stream.h>
#include <pipewire/thread-loop.h>
diff --git a/src/pipewire/private.h b/src/pipewire/private.h
index 1f939def..1a630a74 100644
--- a/src/pipewire/private.h
+++ b/src/pipewire/private.h
@@ -898,8 +898,6 @@ pw_core_find_port(struct pw_core *core,
struct spa_pod **format_filters,
char **error);
-const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type);
-
int pw_proxy_install_marshal(struct pw_proxy *proxy, bool implementor);
int pw_resource_install_marshal(struct pw_resource *resource, bool implementor);
diff --git a/src/pipewire/protocol.c b/src/pipewire/protocol.c
index c7776c75..5d27a1e1 100644
--- a/src/pipewire/protocol.c
+++ b/src/pipewire/protocol.c
@@ -79,6 +79,12 @@ void *pw_protocol_get_user_data(struct pw_protocol *protocol)
}
SPA_EXPORT
+struct pw_core *pw_protocol_get_core(struct pw_protocol *protocol)
+{
+ return protocol->core;
+}
+
+SPA_EXPORT
const struct pw_protocol_implementaton *
pw_protocol_get_implementation(struct pw_protocol *protocol)
{
diff --git a/src/pipewire/protocol.h b/src/pipewire/protocol.h
index b35e02af..0ac0012b 100644
--- a/src/pipewire/protocol.h
+++ b/src/pipewire/protocol.h
@@ -34,6 +34,7 @@ extern "C" {
struct pw_protocol;
#include <pipewire/core.h>
+#include <pipewire/remote.h>
#include <pipewire/properties.h>
#include <pipewire/utils.h>
@@ -44,9 +45,8 @@ 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 */
-
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 +55,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))
@@ -112,6 +112,8 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size
void pw_protocol_destroy(struct pw_protocol *protocol);
+struct pw_core *pw_protocol_get_core(struct pw_protocol *protocol);
+
void *pw_protocol_get_user_data(struct pw_protocol *protocol);
const struct pw_protocol_implementaton *
diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c
index ddcecba1..18f07c8d 100644
--- a/src/pipewire/proxy.c
+++ b/src/pipewire/proxy.c
@@ -153,6 +153,12 @@ struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy)
}
SPA_EXPORT
+struct pw_remote *pw_proxy_get_remote(struct pw_proxy *proxy)
+{
+ return proxy->remote;
+}
+
+SPA_EXPORT
void pw_proxy_add_listener(struct pw_proxy *proxy,
struct spa_hook *listener,
const struct pw_proxy_events *events,
diff --git a/src/pipewire/proxy.h b/src/pipewire/proxy.h
index 6abea884..d32ec737 100644
--- a/src/pipewire/proxy.h
+++ b/src/pipewire/proxy.h
@@ -154,6 +154,9 @@ uint32_t pw_proxy_get_id(struct pw_proxy *proxy);
/** Get the type and version of the proxy */
uint32_t pw_proxy_get_type(struct pw_proxy *proxy, uint32_t *version);
+/** Get the remote managing this proxy */
+struct pw_remote *pw_proxy_get_remote(struct pw_proxy *proxy);
+
/** Get the protocol used for the proxy */
struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy);
diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c
index 99d82aaa..5fee398a 100644
--- a/src/pipewire/remote.c
+++ b/src/pipewire/remote.c
@@ -45,6 +45,7 @@ struct remote {
struct pw_remote this;
struct spa_hook core_listener;
struct spa_hook core_proxy_listener;
+ size_t user_data_size;
};
/** \endcond */
@@ -210,6 +211,7 @@ struct pw_remote *pw_remote_new(struct pw_core *core,
pw_log_debug(NAME" %p: new", impl);
this->core = core;
+ impl->user_data_size = user_data_size;
if (user_data_size > 0)
this->user_data = SPA_MEMBER(impl, sizeof(struct remote), void);
@@ -388,11 +390,8 @@ static const struct pw_proxy_events core_proxy_events = {
.destroy = core_proxy_destroy,
};
-static int
-do_connect(struct spa_loop *loop,
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
+static int init_connect(struct pw_remote *remote)
{
- struct pw_remote *remote = user_data;
struct remote *impl = SPA_CONTAINER_OF(remote, struct remote, this);
struct pw_proxy dummy, *core_proxy;
int res;
@@ -400,10 +399,10 @@ do_connect(struct spa_loop *loop,
spa_zero(dummy);
dummy.remote = remote;
- core_proxy = pw_proxy_new(&dummy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE_PROXY, 0);
+ core_proxy = pw_proxy_new(&dummy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE_PROXY, impl->user_data_size);
if (core_proxy == NULL) {
res = -errno;
- goto error_disconnect;
+ goto error;
}
remote->core_proxy = (struct pw_core_proxy*)core_proxy;
@@ -420,19 +419,27 @@ do_connect(struct spa_loop *loop,
pw_core_proxy_hello(remote->core_proxy, PW_VERSION_CORE_PROXY);
pw_client_proxy_update_properties(remote->client_proxy, &remote->properties->dict);
- pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTED, NULL);
return 0;
error_clean_core_proxy:
((struct pw_proxy*)remote->core_proxy)->removed = true;
pw_proxy_destroy((struct pw_proxy*)remote->core_proxy);
-error_disconnect:
- pw_protocol_client_disconnect(remote->conn);
+error:
pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, "can't connect: %s", spa_strerror(res));
return res;
}
+static int
+do_connect(struct spa_loop *loop,
+ bool async, uint32_t seq, const void *data, size_t size, void *user_data)
+{
+ struct pw_remote *remote = user_data;
+ pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTED, NULL);
+ return 0;
+}
+
+
SPA_EXPORT
struct pw_core_proxy * pw_remote_get_core_proxy(struct pw_remote *remote)
{
@@ -470,12 +477,19 @@ int pw_remote_connect(struct pw_remote *remote)
pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL);
- if ((res = pw_protocol_client_connect(remote->conn, done_connect, remote)) < 0) {
- pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR,
- "connect failed %s", spa_strerror(res));
- return res;
- }
+ if ((res = init_connect(remote)) < 0)
+ goto error;
+
+ 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;
+error:
+ pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR,
+ "connect failed %s", spa_strerror(res));
+ return res;
}
SPA_EXPORT
@@ -485,15 +499,20 @@ int pw_remote_connect_fd(struct pw_remote *remote, int fd)
pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL);
- if ((res = pw_protocol_client_connect_fd(remote->conn, fd, true)) < 0) {
- pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR,
- "connect_fd failed %s", spa_strerror(res));
- return res;
- }
+ if ((res = init_connect(remote)) < 0)
+ goto error;
+
+ if ((res = pw_protocol_client_connect_fd(remote->conn, fd, true)) < 0)
+ goto error;
+
pw_loop_invoke(remote->core->main_loop,
do_connect, 0, NULL, 0, false, remote);
return remote->state == PW_REMOTE_STATE_ERROR ? -EIO : 0;
+error:
+ pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR,
+ "connect_fd failed %s", spa_strerror(res));
+ return res;
}
SPA_EXPORT
@@ -537,66 +556,3 @@ int pw_remote_disconnect(struct pw_remote *remote)
return 0;
}
-
-SPA_EXPORT
-struct pw_proxy *pw_remote_export(struct pw_remote *remote,
- uint32_t type, struct pw_properties *props, void *object,
- size_t user_data_size)
-{
- struct pw_proxy *proxy;
- const struct pw_export_type *t;
- int res;
-
- if (remote->core_proxy == NULL) {
- res = -ENETDOWN;
- goto error_core_proxy;
- }
-
- t = pw_core_find_export_type(remote->core, type);
- if (t == NULL) {
- res = -EPROTO;
- goto error_export_type;
- }
-
- proxy = t->func(remote, type, props, object, user_data_size);
- if (proxy == NULL) {
- res = -errno;
- goto error_proxy_failed;
- }
- return proxy;
-
-error_core_proxy:
- pw_log_error(NAME" %p: no core proxy: %s", remote, spa_strerror(res));
- goto exit_free;
-error_export_type:
- pw_log_error(NAME" %p: can't export type %d: %s", remote, type, spa_strerror(res));
- goto exit_free;
-error_proxy_failed:
- pw_log_error(NAME" %p: failed to create proxy: %s", remote, spa_strerror(res));
- goto exit;
-exit_free:
- if (props)
- pw_properties_free(props);
-exit:
- errno = -res;
- return NULL;
-}
-
-SPA_EXPORT
-int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type)
-{
- pw_log_debug("core %p: Add export type %d/%s to core", core, type->type,
- spa_debug_type_find_name(pw_type_info(), type->type));
- spa_list_append(&core->export_list, &type->link);
- return 0;
-}
-
-const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type)
-{
- const struct pw_export_type *t;
- spa_list_for_each(t, &core->export_list, link) {
- if (t->type == type)
- return t;
- }
- return NULL;
-}
diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h
index d35bb0bd..873f25fc 100644
--- a/src/pipewire/remote.h
+++ b/src/pipewire/remote.h
@@ -196,26 +196,6 @@ struct pw_proxy *pw_remote_find_proxy(struct pw_remote *remote, uint32_t id);
/** Disconnect from the remote PipeWire. \memberof pw_remote */
int pw_remote_disconnect(struct pw_remote *remote);
-/** run a local node in a remote graph */
-struct pw_proxy *pw_remote_export(struct pw_remote *remote, /**< the remote */
- 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 */);
-
-/** data for registering export functions */
-struct pw_export_type {
- struct spa_list link;
- uint32_t type;
- struct pw_proxy * (*func) (struct pw_remote *remote,
- uint32_t type, struct pw_properties *properties, void *object,
- size_t user_data_size);
-};
-
-/** register a type that can be exported on a remote. This is usually used by
- * extension modules */
-int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c
index b5a2caf3..6b06f154 100644
--- a/src/pipewire/stream.c
+++ b/src/pipewire/stream.c
@@ -1052,7 +1052,7 @@ static int handle_connect(struct pw_stream *stream)
}
pw_log_debug(NAME" %p: export node %p", stream, impl->node);
- stream->proxy = pw_remote_export(stream->remote,
+ stream->proxy = pw_core_proxy_export(stream->remote->core_proxy,
PW_TYPE_INTERFACE_Node, NULL, impl->node, 0);
if (stream->proxy == NULL) {
res = -errno;
@@ -1105,8 +1105,8 @@ static const struct pw_remote_events remote_events = {
.state_changed = on_remote_state_changed,
};
-SPA_EXPORT
-struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name,
+static struct pw_stream *
+stream_new(struct pw_remote *remote, const char *name,
struct pw_properties *props)
{
struct stream *impl;
@@ -1178,6 +1178,14 @@ error_cleanup:
}
SPA_EXPORT
+struct pw_stream * pw_stream_new(struct pw_core_proxy *core, const char *name,
+ struct pw_properties *props)
+{
+ struct pw_remote *remote = ((struct pw_proxy*)core)->remote;
+ return stream_new(remote, name, props);
+}
+
+SPA_EXPORT
struct pw_stream *
pw_stream_new_simple(struct pw_loop *loop,
const char *name,
@@ -1194,7 +1202,7 @@ pw_stream_new_simple(struct pw_loop *loop,
core = pw_core_new(loop, NULL, 0);
remote = pw_remote_new(core, NULL, 0);
- stream = pw_stream_new(remote, name, props);
+ stream = stream_new(remote, name, props);
if (stream == NULL) {
res = -errno;
goto error_cleanup;
@@ -1316,9 +1324,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->remote->core_proxy;
}
static void add_params(struct stream *impl)
diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h
index 75ab4f58..88e46573 100644
--- a/src/pipewire/stream.h
+++ b/src/pipewire/stream.h
@@ -48,7 +48,7 @@ extern "C" {
*
* For more complicated nodes such as filters or ports with multiple
* inputs and/or outputs you will need to use the pw_filter or make
- * a pw_node yourself and export it with \ref pw_remote_export.
+ * a pw_node yourself and export it with \ref pw_core_proxy_export.
*
* \section sec_create Create
*
@@ -152,7 +152,7 @@ struct pw_stream;
#include <spa/buffer/buffer.h>
#include <spa/param/param.h>
-#include <pipewire/remote.h>
+#include <pipewire/pipewire.h>
/** \enum pw_stream_state The state of a stream \memberof pw_stream */
enum pw_stream_state {
@@ -247,10 +247,11 @@ 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 *core, /**< a \ref pw_core_proxy */
const char *name, /**< a stream media name */
struct pw_properties *props /**< stream properties, ownership is taken */);
+
struct pw_stream *
pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use */
const char *name, /**< a stream media name */
@@ -270,7 +271,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 bc73d75b..4ba025bf 100644
--- a/src/tests/test-stream.c
+++ b/src/tests/test-stream.c
@@ -134,7 +134,7 @@ static void test_create(void)
{
struct pw_main_loop *loop;
struct pw_core *core;
- struct pw_remote *remote;
+ struct pw_core_proxy *proxy;
struct pw_stream *stream;
struct pw_stream_events stream_events = stream_events_error;
struct spa_hook listener = { 0, };
@@ -143,8 +143,8 @@ 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);
+ proxy = pw_core_connect(core, NULL, 0);
+ stream = pw_stream_new(proxy, "test", NULL);
spa_assert(stream != NULL);
pw_stream_add_listener(stream, &listener, &stream_events, stream);
@@ -154,7 +154,7 @@ static void test_create(void)
/* check name */
spa_assert(!strcmp(pw_stream_get_name(stream), "test"));
/* check remote */
- spa_assert(pw_stream_get_remote(stream) == remote);
+ spa_assert(pw_stream_get_core_proxy(stream) == proxy);
/* check id, only when connected */
spa_assert(pw_stream_get_node_id(stream) == SPA_ID_INVALID);
@@ -183,8 +183,8 @@ static void test_properties(void)
{
struct pw_main_loop *loop;
struct pw_core *core;
+ struct pw_core_proxy *proxy;
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 +192,8 @@ 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",
+ proxy = pw_core_connect(core, NULL, 0);
+ stream = pw_stream_new(proxy, "test",
pw_properties_new("foo", "bar",
"biz", "fuzz",
NULL));
diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c
index 4b880f2c..9c360c9e 100644
--- a/src/tools/pipewire-cli.c
+++ b/src/tools/pipewire-cli.c
@@ -28,6 +28,7 @@
#include <signal.h>
#include <string.h>
+#include <spa/utils/result.h>
#include <spa/debug/pod.h>
#include <spa/debug/format.h>
@@ -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,71 +370,51 @@ 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;
- spa_list_remove(&rd->link);
-
- pw_map_remove(&data->vars, rd->id);
- pw_map_for_each(&rd->globals, destroy_global, rd);
+ pw_log_error("remote %p: error id:%u seq:%d res:%d (%s): %s", rd,
+ id, seq, res, spa_strerror(res), message);
- if (data->current == rd)
- data->current = NULL;
- free(rd->name);
+ if (id == 0) {
+ pw_main_loop_quit(data->loop);
+ }
}
static const struct pw_core_proxy_events remote_core_events = {
- PW_VERSION_CORE_EVENTS,
+ PW_VERSION_CORE_PROXY_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)
+static void on_core_destroy(void *_data)
{
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;
+ spa_list_remove(&rd->link);
- 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,
- &registry_events, rd);
- rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0, 0);
- break;
+ pw_map_remove(&data->vars, rd->id);
+ pw_map_for_each(&rd->globals, destroy_global, rd);
- default:
- fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state));
- break;
- }
+ if (data->current == rd)
+ data->current = NULL;
+ free(rd->name);
}
-static const struct pw_remote_events remote_events = {
- PW_VERSION_REMOTE_EVENTS,
- .destroy = on_remote_destroy,
- .state_changed = on_state_changed,
+static const struct pw_proxy_events core_proxy_events = {
+ PW_VERSION_PROXY_EVENTS,
+ .destroy = on_core_destroy,
};
-
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_core_proxy *core;
struct pw_properties *props = NULL;
struct remote_data *rd;
@@ -442,21 +422,30 @@ static bool do_connect(struct data *data, const char *cmd, char *args, char **er
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 = pw_core_connect(data->core, props, sizeof(struct remote_data));
- rd = pw_remote_get_user_data(remote);
- rd->remote = remote;
+ rd = pw_proxy_get_user_data((struct pw_proxy*)core);
+ rd->core_proxy = core;
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 = @core_proxy:%p\n", rd->id, core);
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,
+ &registry_events, rd);
+ rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0, 0);
return true;
}
@@ -476,8 +465,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 +486,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 = @core_proxy:%p '%s'\n", rd->id, rd->core_proxy, rd->name);
return true;
}
@@ -1428,7 +1416,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 ebd121d2..2d1568a8 100644
--- a/src/tools/pipewire-dot.c
+++ b/src/tools/pipewire-dot.c
@@ -26,13 +26,13 @@
#include <signal.h>
#include <getopt.h>
+#include <spa/utils/result.h>
#include <spa/debug/pod.h>
#include <spa/debug/format.h>
#include <spa/debug/types.h>
#include <pipewire/interfaces.h>
#include <pipewire/type.h>
-#include <pipewire/remote.h>
#include <pipewire/main-loop.h>
#include <pipewire/pipewire.h>
@@ -48,9 +48,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 +708,21 @@ 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;
-
- 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:
- 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,
- &registry_events, data);
- break;
+ struct data *d = data;
- default:
- break;
+ 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(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,26 +819,27 @@ 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)
- return -1;
-
data.dot_str = dot_str_new();
- if (data.dot_str == NULL)
+ spa_list_init(&data.globals);
+
+ data.core_proxy = pw_core_connect(data.core, props, 0);
+ if (data.core_proxy == NULL)
return -1;
- 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,
+ &registry_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 822dae0d..39dc2a99 100644
--- a/src/tools/pipewire-monitor.c
+++ b/src/tools/pipewire-monitor.c
@@ -25,13 +25,13 @@
#include <stdio.h>
#include <signal.h>
+#include <spa/utils/result.h>
#include <spa/debug/pod.h>
#include <spa/debug/format.h>
#include <spa/debug/types.h>
#include <pipewire/interfaces.h>
#include <pipewire/type.h>
-#include <pipewire/remote.h>
#include <pipewire/main-loop.h>
#include <pipewire/pipewire.h>
@@ -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,23 @@ 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_main_loop_quit(data->loop);
- break;
+ struct data *d = data;
- 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,
- &registry_events, data);
- break;
+ pw_log_error("error id:%u seq:%d res:%d (%s): %s",
+ id, seq, res, spa_strerror(res), message);
- 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_EVENTS,
+ .info = on_core_info,
+ .done = on_core_done,
+ .error = on_core_error,
};
static void do_quit(void *data, int signal_number)
@@ -741,19 +715,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;
+ spa_list_init(&data.pending_list);
- 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;
- spa_list_init(&data.pending_list);
+ 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,
+ &registry_events, &data);
pw_main_loop_run(data.loop);
- pw_remote_destroy(data.remote);
pw_core_destroy(data.core);
pw_main_loop_destroy(data.loop);