core_proxy: prepare to rename pw_remote -> pw_core_proxy

The pw_remote object is really a wrapper around the pw_core_proxy.
The events it emits are also available in the core proxy and are
generally awkward to use.

With some clever new pw_core_proxy_* methods and a pw_core_connect
to create the core_proxy, we can convert all code away from pw_remote.

This is a first step in this conversion, using the pw_remote behind
the scenes. It leaks into some places because it really needs to become
its own struct in a next step.
This commit is contained in:
Wim Taymans 2019-12-06 11:48:40 +01:00
parent f8aabe69fe
commit 8a959ea7a1
37 changed files with 919 additions and 1185 deletions

View file

@ -75,8 +75,8 @@ struct impl {
struct pw_main_loop *loop;
struct pw_core *core;
struct pw_remote *remote;
struct spa_hook remote_listener;
struct pw_core_proxy *core_proxy;
struct spa_hook core_listener;
struct spa_handle *handle;
struct spa_device *device;
@ -140,7 +140,7 @@ static struct node *create_node(struct object *obj, uint32_t id,
node->id = id;
node->handle = handle;
node->node = iface;
node->proxy = pw_remote_export(impl->remote,
node->proxy = pw_core_proxy_export(impl->core_proxy,
info->type, pw_properties_new_dict(info->props), node->node, 0);
if (node->proxy == NULL)
goto clean_node;
@ -248,7 +248,7 @@ static struct object *create_object(struct impl *impl, uint32_t id,
obj->id = id;
obj->handle = handle;
obj->device = iface;
obj->proxy = pw_remote_export(impl->remote,
obj->proxy = pw_core_proxy_export(impl->core_proxy,
info->type, pw_properties_new_dict(info->props), obj->device, 0);
if (obj->proxy == NULL)
goto clean_object;
@ -338,50 +338,32 @@ static int start_monitor(struct impl *impl)
return res;
}
static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error)
static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message)
{
struct impl *impl = _data;
int res;
struct impl *impl = data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
pw_log_error(NAME" %p: remote error: %s", impl, error);
pw_log_error("error id:%u seq:%d res:%d (%s): %s",
id, seq, res, spa_strerror(res), message);
if (id == 0) {
pw_main_loop_quit(impl->loop);
break;
case PW_REMOTE_STATE_CONNECTED:
pw_log_info(NAME" %p: connected", impl);
if ((res = start_monitor(impl)) < 0) {
pw_log_debug("error starting monitor: %s", spa_strerror(res));
pw_main_loop_quit(impl->loop);
}
break;
case PW_REMOTE_STATE_UNCONNECTED:
pw_log_info(NAME" %p: disconnected", impl);
pw_main_loop_quit(impl->loop);
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
static const struct pw_core_proxy_events core_events = {
PW_VERSION_CORE_PROXY_EVENTS,
.error = on_core_error,
};
int main(int argc, char *argv[])
{
struct impl impl = { 0, };
int res;
pw_init(&argc, &argv);
impl.loop = pw_main_loop_new(NULL);
impl.core = pw_core_new(pw_main_loop_get_loop(impl.loop), NULL, 0);
impl.remote = pw_remote_new(impl.core, NULL, 0);
pw_core_add_spa_lib(impl.core, "api.bluez5.*", "bluez5/libspa-bluez5");
@ -389,12 +371,20 @@ int main(int argc, char *argv[])
spa_list_init(&impl.device_list);
pw_remote_add_listener(impl.remote,
&impl.remote_listener,
&remote_events, &impl);
if (pw_remote_connect(impl.remote) < 0)
impl.core_proxy = pw_core_connect(impl.core, NULL, 0);
if (impl.core_proxy == NULL) {
pw_log_error(NAME" %p: can't connect %m", &impl);
return -1;
}
pw_core_proxy_add_listener(impl.core_proxy,
&impl.core_listener,
&core_events, &impl);
if ((res = start_monitor(&impl)) < 0) {
pw_log_error(NAME" %p: error starting monitor: %s", &impl, spa_strerror(res));
return -1;
}
pw_main_loop_run(impl.loop);

View file

@ -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;
struct pw_permission permissions[2];
switch (state) {
case PW_REMOTE_STATE_ERROR:
printf("remote error: %s\n", error);
pw_main_loop_quit(data->loop);
break;
/* an example, set specific permissions on one object, this is the
* core object. */
permissions[0].id = 0;
permissions[0].permissions = PW_PERM_R | PW_PERM_X;
/* remove WX from all other objects */
permissions[1].id = SPA_ID_INVALID;
permissions[1].permissions = PW_PERM_R;
case PW_REMOTE_STATE_CONNECTED:
{
struct pw_permission permissions[2];
pw_client_proxy_update_permissions(
pw_core_proxy_get_client_proxy(data->core_proxy),
2, permissions);
}
/* an example, set specific permissions on one object, this is the
* core object. */
permissions[0].id = 0;
permissions[0].permissions = PW_PERM_R | PW_PERM_X;
/* remove WX from all other objects */
permissions[1].id = SPA_ID_INVALID;
permissions[1].permissions = PW_PERM_R;
static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message)
{
struct data *d = data;
pw_client_proxy_update_permissions(
pw_remote_get_client_proxy(data->remote),
2, permissions);
pw_log_error("error id:%u seq:%d res:%d (%s): %s",
id, seq, res, spa_strerror(res), message);
make_node(data);
break;
}
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
if (id == 0) {
pw_main_loop_quit(d->loop);
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
static const struct pw_core_proxy_events core_events = {
PW_VERSION_CORE_PROXY_EVENTS,
.error = on_core_error,
};
int main(int argc, char *argv[])
@ -524,7 +519,6 @@ int main(int argc, char *argv[])
data.loop = pw_main_loop_new(NULL);
data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0);
data.remote = pw_remote_new(data.core, NULL, 0);
data.path = argc > 1 ? argv[1] : NULL;
spa_hook_list_init(&data.hooks);
@ -554,10 +548,16 @@ int main(int argc, char *argv[])
return -1;
}
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
if (pw_remote_connect(data.remote) < 0)
data.core_proxy = pw_core_connect(data.core, NULL, 0);
if (data.core_proxy == NULL) {
printf("can't connect: %m\n");
return -1;
}
pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data);
set_permissions(&data);
make_node(&data);
pw_main_loop_run(data.loop);

View file

@ -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;
struct data *d = data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
printf("remote error: %s\n", error);
pw_main_loop_quit(data->loop);
break;
pw_log_error("error id:%u seq:%d res:%d (%s): %s",
id, seq, res, spa_strerror(res), message);
case PW_REMOTE_STATE_CONNECTED:
make_node(data);
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
if (id == 0) {
pw_main_loop_quit(d->loop);
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
static const struct pw_core_proxy_events core_events = {
PW_VERSION_CORE_PROXY_EVENTS,
.error = on_core_error,
};
int main(int argc, char *argv[])
@ -518,7 +510,6 @@ int main(int argc, char *argv[])
data.loop = pw_main_loop_new(NULL);
data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0);
data.remote = pw_remote_new(data.core, NULL, 0);
data.path = argc > 1 ? argv[1] : NULL;
data.info_all = SPA_PORT_CHANGE_MASK_FLAGS |
@ -540,9 +531,14 @@ int main(int argc, char *argv[])
spa_list_init(&data.empty);
spa_hook_list_init(&data.hooks);
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
if ((data.core_proxy = pw_core_connect(data.core, NULL, 0)) == NULL) {
printf("can't connect: %m\n");
return -1;
}
pw_remote_connect(data.remote);
pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data);
make_node(&data);
pw_main_loop_run(data.loop);

View file

@ -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;
struct data *d = data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
printf("remote error: %s\n", error);
pw_main_loop_quit(data->loop);
break;
pw_log_error("error id:%u seq:%d res:%d (%s): %s",
id, seq, res, spa_strerror(res), message);
case PW_REMOTE_STATE_CONNECTED:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
if (make_device(data) < 0) {
pw_log_error("can't make device");
pw_main_loop_quit(data->loop);
}
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
if (id == 0) {
pw_main_loop_quit(d->loop);
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
static const struct pw_core_proxy_events core_events = {
PW_VERSION_CORE_PROXY_EVENTS,
.error = on_core_error,
};
static void do_quit(void *data, int signal_number)
@ -123,15 +112,23 @@ int main(int argc, char *argv[])
pw_loop_add_signal(l, SIGINT, do_quit, &data);
pw_loop_add_signal(l, SIGTERM, do_quit, &data);
data.core = pw_core_new(l, NULL, 0);
data.remote = pw_remote_new(data.core, NULL, 0);
data.library = argv[1];
data.factory = argv[2];
pw_module_load(data.core, "libpipewire-module-spa-device-factory", NULL, NULL);
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
data.core_proxy = pw_core_connect(data.core, NULL, 0);
if (data.core_proxy == NULL) {
pw_log_error("can't connect %m");
return -1;
}
pw_remote_connect(data.remote);
pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data);
if (make_device(&data) < 0) {
pw_log_error("can't make device");
return -1;
}
pw_main_loop_run(data.loop);

View file

@ -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;
struct data *d = data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
printf("remote error: %s\n", error);
pw_main_loop_quit(data->loop);
break;
pw_log_error("error id:%u seq:%d res:%d (%s): %s",
id, seq, res, spa_strerror(res), message);
case PW_REMOTE_STATE_CONNECTED:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
if (make_node(data) < 0) {
pw_log_error("can't make node");
pw_main_loop_quit(data->loop);
}
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
if (id == 0) {
pw_main_loop_quit(d->loop);
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
static const struct pw_core_proxy_events core_events = {
PW_VERSION_CORE_PROXY_EVENTS,
.error = on_core_error,
};
static void do_quit(void *data, int signal_number)
@ -155,7 +144,6 @@ int main(int argc, char *argv[])
pw_loop_add_signal(l, SIGINT, do_quit, &data);
pw_loop_add_signal(l, SIGTERM, do_quit, &data);
data.core = pw_core_new(l, NULL, 0);
data.remote = pw_remote_new(data.core, NULL, 0);
data.library = argv[1];
data.factory = argv[2];
if (argc > 3)
@ -163,9 +151,19 @@ int main(int argc, char *argv[])
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL);
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
data.core_proxy = pw_core_connect(data.core, NULL, 0);
if (data.core_proxy == NULL) {
printf("can't connect: %m\n");
return -1;
}
pw_core_proxy_add_listener(data.core_proxy,
&data.core_listener,
&core_events, &data);
pw_remote_connect(data.remote);
if (make_node(&data) < 0) {
pw_log_error("can't make node");
return -1;
}
pw_main_loop_run(data.loop);

View file

@ -91,14 +91,11 @@ struct impl {
struct pw_main_loop *loop;
struct spa_dbus *dbus;
struct pw_remote *monitor_remote;
struct spa_hook monitor_listener;
struct pw_core_proxy *monitor_core;
struct spa_hook monitor_listener;
struct pw_remote *policy_remote;
struct spa_hook policy_listener;
struct pw_core_proxy *policy_core;
struct spa_hook core_listener;
struct spa_hook policy_listener;
struct pw_registry_proxy *registry_proxy;
struct spa_hook registry_listener;
@ -1216,7 +1213,7 @@ struct pw_proxy *sm_media_session_export(struct sm_media_session *sess,
void *object, size_t user_data_size)
{
struct impl *impl = SPA_CONTAINER_OF(sess, struct impl, this);
return pw_remote_export(impl->monitor_remote, type,
return pw_core_proxy_export(impl->monitor_core, type,
properties, object, user_data_size);
}
@ -1229,7 +1226,7 @@ struct sm_device *sm_media_session_export_device(struct sm_media_session *sess,
pw_log_debug(NAME " %p: device %p", impl, object);
proxy = pw_remote_export(impl->monitor_remote, SPA_TYPE_INTERFACE_Device,
proxy = pw_core_proxy_export(impl->monitor_core, SPA_TYPE_INTERFACE_Device,
properties, object, sizeof(struct sm_device));
device = (struct sm_device *) create_object(impl, proxy, &properties->dict);
@ -1526,6 +1523,12 @@ static const struct pw_proxy_events client_session_proxy_events = {
static int start_session(struct impl *impl)
{
impl->monitor_core = pw_core_connect(impl->this.core, NULL, 0);
if (impl->monitor_core == NULL) {
pw_log_error("can't start monitor: %m");
return -errno;
}
impl->client_session = pw_core_proxy_create_object(impl->monitor_core,
"client-session",
PW_TYPE_INTERFACE_ClientSession,
@ -1543,11 +1546,6 @@ static int start_session(struct impl *impl)
return 0;
}
static int start_policy(struct impl *impl)
{
return sm_policy_ep_start(&impl->this);
}
static void core_done(void *data, uint32_t id, int seq)
{
struct impl *impl = data;
@ -1567,91 +1565,50 @@ static void core_done(void *data, uint32_t id, int seq)
}
}
static void on_monitor_state_changed(void *_data, enum pw_remote_state old,
enum pw_remote_state state, const char *error)
static void core_error(void *data, uint32_t id, int seq, int res, const char *message)
{
struct impl *impl = _data;
struct impl *impl = data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
pw_log_error(NAME" %p: remote error: %s", impl, error);
pw_log_error("error id:%u seq:%d res:%d (%s): %s",
id, seq, res, spa_strerror(res), message);
if (id == 0) {
pw_main_loop_quit(impl->loop);
break;
case PW_REMOTE_STATE_CONNECTED:
pw_log_info(NAME" %p: connected", impl);
impl->monitor_core = pw_remote_get_core_proxy(impl->monitor_remote);
start_session(impl);
break;
case PW_REMOTE_STATE_UNCONNECTED:
pw_log_info(NAME" %p: disconnected", impl);
pw_main_loop_quit(impl->loop);
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
}
}
static const struct pw_remote_events monitor_remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_monitor_state_changed,
};
static const struct pw_core_proxy_events core_events = {
PW_VERSION_CORE_EVENTS,
.done = core_done
.done = core_done,
.error = core_error
};
static void on_policy_state_changed(void *_data, enum pw_remote_state old,
enum pw_remote_state state, const char *error)
static int start_policy(struct impl *impl)
{
struct impl *impl = _data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
pw_log_error(NAME" %p: remote error: %s", impl, error);
pw_main_loop_quit(impl->loop);
break;
case PW_REMOTE_STATE_CONNECTED:
pw_log_info(NAME" %p: connected", impl);
impl->policy_core = pw_remote_get_core_proxy(impl->policy_remote);
pw_core_proxy_add_listener(impl->policy_core,
&impl->core_listener,
&core_events, impl);
impl->registry_proxy = pw_core_proxy_get_registry(impl->policy_core,
PW_VERSION_REGISTRY_PROXY, 0);
pw_registry_proxy_add_listener(impl->registry_proxy,
&impl->registry_listener,
&registry_events, impl);
start_policy(impl);
break;
case PW_REMOTE_STATE_UNCONNECTED:
pw_log_info(NAME" %p: disconnected", impl);
pw_main_loop_quit(impl->loop);
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
impl->policy_core = pw_core_connect(impl->this.core, NULL, 0);
if (impl->policy_core == NULL) {
pw_log_error("can't start policy: %m");
return -errno;
}
}
static const struct pw_remote_events policy_remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_policy_state_changed,
};
pw_core_proxy_add_listener(impl->policy_core,
&impl->policy_listener,
&core_events, impl);
impl->registry_proxy = pw_core_proxy_get_registry(impl->policy_core,
PW_VERSION_REGISTRY_PROXY, 0);
pw_registry_proxy_add_listener(impl->registry_proxy,
&impl->registry_listener,
&registry_events, impl);
return sm_policy_ep_start(&impl->this);
}
int main(int argc, char *argv[])
{
struct impl impl = { 0, };
const struct spa_support *support;
uint32_t n_support;
int res;
pw_init(&argc, &argv);
@ -1663,12 +1620,6 @@ int main(int argc, char *argv[])
pw_core_add_spa_lib(impl.this.core, "api.alsa.*", "alsa/libspa-alsa");
pw_core_add_spa_lib(impl.this.core, "api.v4l2.*", "v4l2/libspa-v4l2");
impl.monitor_remote = pw_remote_new(impl.this.core, NULL, 0);
pw_remote_add_listener(impl.monitor_remote, &impl.monitor_listener, &monitor_remote_events, &impl);
impl.policy_remote = pw_remote_new(impl.this.core, NULL, 0);
pw_remote_add_listener(impl.policy_remote, &impl.policy_listener, &policy_remote_events, &impl);
pw_map_init(&impl.globals, 64, 64);
spa_list_init(&impl.global_list);
pw_map_init(&impl.endpoint_links, 64, 64);
@ -1686,10 +1637,10 @@ int main(int argc, char *argv[])
else
pw_log_debug("got dbus connection %p", impl.this.dbus_connection);
if ((res = pw_remote_connect(impl.monitor_remote)) < 0)
return res;
if ((res = pw_remote_connect(impl.policy_remote)) < 0)
return res;
if (start_session(&impl) < 0)
return -1;
if (start_policy(&impl) < 0)
return -1;
pw_main_loop_run(impl.loop);

View file

@ -47,8 +47,7 @@ struct data {
struct spa_source *timer;
struct pw_core *core;
struct pw_remote *remote;
struct spa_hook remote_listener;
struct pw_core_proxy *core_proxy;
struct pw_stream *stream;
struct spa_hook stream_listener;
@ -186,6 +185,11 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum
printf("stream state: \"%s\"\n", pw_stream_state_as_string(state));
switch (state) {
case PW_STREAM_STATE_ERROR:
case PW_STREAM_STATE_UNCONNECTED:
pw_main_loop_quit(data->loop);
break;
case PW_STREAM_STATE_PAUSED:
printf("node id: %d\n", pw_stream_get_node_id(data->stream));
break;
@ -266,81 +270,51 @@ static const struct pw_stream_events stream_events = {
.param_changed = on_stream_param_changed,
};
static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error)
{
struct data *data = _data;
struct pw_remote *remote = data->remote;
switch (state) {
case PW_REMOTE_STATE_ERROR:
printf("remote error: %s\n", error);
pw_main_loop_quit(data->loop);
break;
case PW_REMOTE_STATE_CONNECTED:
{
const struct spa_pod *params[1];
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
printf("remote state: \"%s\"\n",
pw_remote_state_as_string(state));
data->stream = pw_stream_new(remote, "video-src",
pw_properties_new(
PW_KEY_MEDIA_CLASS, "Video/Source",
NULL));
params[0] = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGB),
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
&SPA_RECTANGLE(320, 240),
&SPA_RECTANGLE(1, 1),
&SPA_RECTANGLE(4096, 4096)),
SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION(25, 1)));
pw_stream_add_listener(data->stream,
&data->stream_listener,
&stream_events,
data);
pw_stream_connect(data->stream,
PW_DIRECTION_OUTPUT,
SPA_ID_INVALID,
PW_STREAM_FLAG_DRIVER |
PW_STREAM_FLAG_MAP_BUFFERS,
params, 1);
break;
}
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
};
int main(int argc, char *argv[])
{
struct data data = { 0, };
const struct spa_pod *params[1];
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
pw_init(&argc, &argv);
data.loop = pw_main_loop_new(NULL);
data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0);
data.remote = pw_remote_new(data.core, NULL, 0);
data.timer = pw_loop_add_timer(pw_main_loop_get_loop(data.loop), on_timeout, &data);
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
data.core_proxy = pw_core_connect(data.core, NULL, 0);
if (data.core_proxy == NULL)
return -1;
pw_remote_connect(data.remote);
data.stream = pw_stream_new(data.core_proxy, "video-src",
pw_properties_new(
PW_KEY_MEDIA_CLASS, "Video/Source",
NULL));
params[0] = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGB),
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
&SPA_RECTANGLE(320, 240),
&SPA_RECTANGLE(1, 1),
&SPA_RECTANGLE(4096, 4096)),
SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION(25, 1)));
pw_stream_add_listener(data.stream,
&data.stream_listener,
&stream_events,
&data);
pw_stream_connect(data.stream,
PW_DIRECTION_OUTPUT,
SPA_ID_INVALID,
PW_STREAM_FLAG_DRIVER |
PW_STREAM_FLAG_MAP_BUFFERS,
params, 1);
pw_main_loop_run(data.loop);