core: remove parent_id from the global event

Remove the parent_id from the global event. Remove the parent
and owner from the global object.

Use properties instead to mark parents and owners of objects.

Properties are easier to control for client exported objects and
usually a simple parent/child is not enough. For example, a client
exported node has the client as a parent but also the factory that
created the node.
This commit is contained in:
Wim Taymans 2019-08-16 22:11:42 +02:00
parent 32ce5c4deb
commit 8db4a797aa
58 changed files with 482 additions and 464 deletions

View file

@ -58,6 +58,7 @@ struct alsa_object {
struct monitor *monitor;
struct spa_list link;
uint32_t id;
uint32_t device_id;
struct pw_properties *props;
@ -111,8 +112,10 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id,
node->props = pw_properties_new_dict(info->props);
str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK);
if (str)
if (obj->device_id != 0)
pw_properties_setf(node->props, PW_KEY_DEVICE_ID, "%d", obj->device_id);
if ((str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK)) != NULL)
pw_properties_set(node->props, PW_KEY_NODE_NICK, str);
str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME);
@ -169,7 +172,13 @@ static void alsa_remove_node(struct alsa_object *obj, struct alsa_node *node)
static void alsa_device_info(void *data, const struct spa_device_info *info)
{
struct alsa_object *obj = data;
const char *str;
pw_properties_update(obj->props, info->props);
if ((str = pw_properties_get(obj->props, PW_KEY_DEVICE_ID)) != NULL)
obj->device_id = pw_properties_parse_int(str);
spa_debug_dict(0, info->props);
}

View file

@ -386,7 +386,7 @@ int main(int argc, char *argv[])
pw_core_add_spa_lib(impl.core, "api.bluez5.*", "bluez5/libspa-bluez5");
pw_module_load(impl.core, "libpipewire-module-client-device", NULL, NULL, NULL, NULL);
pw_module_load(impl.core, "libpipewire-module-client-device", NULL, NULL);
clock_gettime(CLOCK_MONOTONIC, &impl.now);

View file

@ -127,8 +127,8 @@ int main(int argc, char *argv[])
data.library = argv[1];
data.factory = argv[2];
pw_module_load(data.core, "libpipewire-module-spa-device-factory", NULL, NULL, NULL, NULL);
pw_module_load(data.core, "libpipewire-module-client-device", NULL, NULL, NULL, NULL);
pw_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);

View file

@ -135,7 +135,7 @@ int main(int argc, char *argv[])
if (argc > 3)
data.path = argv[3];
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL, NULL, NULL);
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL);
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);

View file

@ -346,7 +346,7 @@ static int make_nodes(struct data *data)
&impl_node, data);
pw_node_set_implementation(data->node, &data->impl_node);
pw_node_register(data->node, NULL, NULL, NULL);
pw_node_register(data->node, NULL);
factory = pw_core_find_factory(data->core, "spa-node-factory");
props = pw_properties_new(SPA_KEY_LIBRARY_NAME, "v4l2/libspa-v4l2",
@ -366,7 +366,7 @@ static int make_nodes(struct data *data)
NULL,
NULL,
0);
pw_link_register(data->link, NULL, NULL, NULL);
pw_link_register(data->link, NULL);
pw_node_set_active(data->node, true);
pw_node_set_active(data->v4l2, true);
@ -385,7 +385,7 @@ int main(int argc, char *argv[])
spa_hook_list_init(&data.hooks);
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL, NULL, NULL);
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL);
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("can't initialize SDL: %s\n", SDL_GetError());

View file

@ -89,7 +89,6 @@ struct impl {
struct object {
struct impl *impl;
uint32_t id;
uint32_t parent_id;
uint32_t type;
struct pw_proxy *proxy;
struct spa_hook listener;
@ -112,6 +111,8 @@ struct node {
struct spa_hook listener;
struct pw_node_info *info;
uint32_t client_id;
struct spa_list session_link;
struct session *session;
@ -401,7 +402,7 @@ static const struct pw_proxy_events node_proxy_events = {
};
static int
handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
handle_node(struct impl *impl, uint32_t id,
uint32_t type, const struct spa_dict *props)
{
const char *str, *media_class;
@ -409,8 +410,10 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
enum pw_direction direction;
struct pw_proxy *p;
struct node *node;
uint32_t client_id = SPA_ID_INVALID;
media_class = props ? spa_dict_lookup(props, PW_KEY_MEDIA_CLASS) : NULL;
if (props && (str = spa_dict_lookup(props, PW_KEY_CLIENT_ID)) != NULL)
client_id = atoi(str);
p = pw_registry_proxy_bind(impl->registry_proxy,
id, type, PW_VERSION_NODE_PROXY,
@ -419,9 +422,9 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
node = pw_proxy_get_user_data(p);
node->obj.impl = impl;
node->obj.id = id;
node->obj.parent_id = parent_id;
node->obj.type = type;
node->obj.proxy = p;
node->client_id = client_id;
spa_list_init(&node->port_list);
pw_proxy_add_listener(p, &node->obj.listener, &node_proxy_events, node);
pw_proxy_add_object_listener(p, &node->listener, &node_events, node);
@ -429,6 +432,8 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
spa_list_append(&impl->node_list, &node->l);
node->type = NODE_TYPE_UNKNOWN;
media_class = props ? spa_dict_lookup(props, PW_KEY_MEDIA_CLASS) : NULL;
pw_log_debug(NAME" %p: node "PW_KEY_MEDIA_CLASS" %s", impl, media_class);
if (media_class == NULL)
@ -571,15 +576,21 @@ static const struct pw_proxy_events port_proxy_events = {
};
static int
handle_port(struct impl *impl, uint32_t id, uint32_t parent_id, uint32_t type,
handle_port(struct impl *impl, uint32_t id, uint32_t type,
const struct spa_dict *props)
{
struct port *port;
struct pw_proxy *p;
struct node *node;
const char *str;
uint32_t node_id;
if ((node = find_object(impl, parent_id)) == NULL)
if (props == NULL || (str = spa_dict_lookup(props, PW_KEY_NODE_ID)) == NULL)
return -EINVAL;
node_id = atoi(str);
if ((node = find_object(impl, node_id)) == NULL)
return -ESRCH;
if (props == NULL || (str = spa_dict_lookup(props, PW_KEY_PORT_DIRECTION)) == NULL)
@ -592,7 +603,6 @@ handle_port(struct impl *impl, uint32_t id, uint32_t parent_id, uint32_t type,
port = pw_proxy_get_user_data(p);
port->obj.impl = impl;
port->obj.id = id;
port->obj.parent_id = parent_id;
port->obj.type = type;
port->obj.proxy = p;
port->node = node;
@ -607,7 +617,7 @@ handle_port(struct impl *impl, uint32_t id, uint32_t parent_id, uint32_t type,
spa_list_append(&node->port_list, &port->l);
pw_log_debug(NAME" %p: new port %d for node %d type %d %08x", impl, id, parent_id,
pw_log_debug(NAME" %p: new port %d for node %d type %d %08x", impl, id, node_id,
node->type, port->flags);
if (node->type == NODE_TYPE_DEVICE) {
@ -655,7 +665,7 @@ static const struct pw_proxy_events client_proxy_events = {
};
static int
handle_client(struct impl *impl, uint32_t id, uint32_t parent_id,
handle_client(struct impl *impl, uint32_t id,
uint32_t type, const struct spa_dict *props)
{
struct pw_proxy *p;
@ -670,7 +680,6 @@ handle_client(struct impl *impl, uint32_t id, uint32_t parent_id,
client = pw_proxy_get_user_data(p);
client->obj.impl = impl;
client->obj.id = id;
client->obj.parent_id = parent_id;
client->obj.type = type;
client->obj.proxy = p;
@ -695,7 +704,7 @@ handle_client(struct impl *impl, uint32_t id, uint32_t parent_id,
}
static void
registry_global(void *data,uint32_t id, uint32_t parent_id,
registry_global(void *data,uint32_t id,
uint32_t permissions, uint32_t type, uint32_t version,
const struct spa_dict *props)
{
@ -706,15 +715,15 @@ registry_global(void *data,uint32_t id, uint32_t parent_id,
switch (type) {
case PW_TYPE_INTERFACE_Client:
res = handle_client(impl, id, parent_id, type, props);
res = handle_client(impl, id, type, props);
break;
case PW_TYPE_INTERFACE_Node:
res = handle_node(impl, id, parent_id, type, props);
res = handle_node(impl, id, type, props);
break;
case PW_TYPE_INTERFACE_Port:
res = handle_port(impl, id, parent_id, type, props);
res = handle_port(impl, id, type, props);
break;
default:
@ -1053,7 +1062,7 @@ static int rescan_node(struct impl *impl, struct node *node)
pw_log_warn(NAME " %p: no session found for %d", impl, node->obj.id);
client = find_object(impl, node->obj.parent_id);
client = find_object(impl, node->client_id);
if (client && client->obj.type == PW_TYPE_INTERFACE_Client) {
pw_client_proxy_error((struct pw_client_proxy*)client->obj.proxy,
node->obj.id, -ENOENT, "no session available");
@ -1256,8 +1265,8 @@ int main(int argc, char *argv[])
pw_core_add_spa_lib(impl.core, "api.alsa.*", "alsa/libspa-alsa");
pw_core_add_spa_lib(impl.core, "api.v4l2.*", "v4l2/libspa-v4l2");
pw_module_load(impl.core, "libpipewire-module-client-device", NULL, NULL, NULL, NULL);
pw_module_load(impl.core, "libpipewire-module-adapter", NULL, NULL, NULL, NULL);
pw_module_load(impl.core, "libpipewire-module-client-device", NULL, NULL);
pw_module_load(impl.core, "libpipewire-module-adapter", NULL, NULL);
clock_gettime(CLOCK_MONOTONIC, &impl.now);