diff --git a/src/examples/media-session/alsa-monitor.c b/src/examples/media-session/alsa-monitor.c index 0b220de8b..29200ff8d 100644 --- a/src/examples/media-session/alsa-monitor.c +++ b/src/examples/media-session/alsa-monitor.c @@ -103,7 +103,8 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id, struct monitor *monitor = obj->monitor; struct impl *impl = monitor->impl; int res; - const char *dev, *subdev; + const char *card, *dev, *subdev; + int priority; pw_log_debug("new node %u", id); @@ -124,11 +125,22 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id, pw_properties_set(node->props, "factory.name", info->factory_name); + if ((card = pw_properties_get(node->props, SPA_KEY_API_ALSA_PCM_CARD)) == NULL) + card = "0"; if ((dev = pw_properties_get(node->props, SPA_KEY_API_ALSA_PCM_DEVICE)) == NULL) dev = "0"; if ((subdev = pw_properties_get(node->props, SPA_KEY_API_ALSA_PCM_SUBDEVICE)) == NULL) subdev = "0"; + priority = 1000; + priority -= atol(card) * 64; + priority -= atol(dev) * 16; + priority -= atol(subdev); + + if (pw_properties_get(node->props, PW_KEY_NODE_PRIORITY) == NULL) { + pw_properties_setf(node->props, PW_KEY_NODE_PRIORITY, "%d", priority); + } + if (pw_properties_get(node->props, SPA_KEY_NODE_NAME) == NULL) { const char *devname, *stream; if ((devname = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME)) == NULL) diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index 1d25752e3..68f387dc3 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -172,6 +172,7 @@ struct session { struct impl *impl; enum pw_direction direction; + int priority; uint64_t plugged; struct node *node; @@ -503,6 +504,11 @@ handle_node(struct impl *impl, uint32_t id, else sess->plugged = SPA_TIMESPEC_TO_NSEC(&impl->now); + if ((str = spa_dict_lookup(props, PW_KEY_NODE_PRIORITY)) != NULL) + sess->priority = pw_properties_parse_int(str); + else + sess->priority = 0; + spa_list_init(&sess->node_list); spa_list_append(&impl->session_list, &sess->l); @@ -793,6 +799,7 @@ struct find_data { const char *media_class; struct session *sess; bool exclusive; + int priority; uint64_t plugged; }; @@ -802,6 +809,7 @@ static int find_session(void *data, struct session *sess) struct impl *impl = find->impl; const struct spa_dict *props; const char *str; + int priority = 0; uint64_t plugged = 0; pw_log_debug(NAME " %p: looking at session '%d' enabled:%d busy:%d exclusive:%d", @@ -824,6 +832,7 @@ static int find_session(void *data, struct session *sess) return 0; plugged = sess->plugged; + priority = sess->priority; } if ((find->exclusive && sess->busy) || sess->exclusive) { @@ -834,9 +843,12 @@ static int find_session(void *data, struct session *sess) pw_log_debug(NAME " %p: found session '%d' %" PRIu64, impl, sess->id, plugged); - if (find->sess == NULL || plugged > find->plugged) { - pw_log_debug(NAME " %p: new best %" PRIu64, impl, plugged); + if (find->sess == NULL || + priority > find->priority || + (priority == find->priority && plugged > find->plugged)) { + pw_log_debug(NAME " %p: new best %d %" PRIu64, impl, priority, plugged); find->sess = sess; + find->priority = priority; find->plugged = plugged; } return 0; @@ -953,6 +965,8 @@ static int rescan_node(struct impl *impl, struct node *node) return 0; } + spa_zero(find); + if ((category = spa_dict_lookup(props, PW_KEY_MEDIA_CATEGORY)) == NULL) { pw_log_debug(NAME" %p: node %d find category from ports: %d %d", impl, node->obj.id, info->n_input_ports, info->n_output_ports); @@ -1041,9 +1055,8 @@ static int rescan_node(struct impl *impl, struct node *node) media, category, role, exclusive, find.path_id); find.impl = impl; - find.sess = NULL; - find.plugged = 0; find.exclusive = exclusive; + spa_list_for_each(session, &impl->session_list, l) find_session(&find, session); diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index 6bf91a763..87785130c 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -115,6 +115,7 @@ extern "C" { * description. Ex. "Foobar USB Headset" */ #define PW_KEY_NODE_PLUGGED "node.plugged" /**< when the node was created. As a uint64 in * nanoseconds. */ +#define PW_KEY_NODE_PRIORITY "node.priority" /**< priority of node */ #define PW_KEY_NODE_SESSION "node.session" /**< the session id this node is part of */ #define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */ #define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected diff --git a/src/pipewire/node.c b/src/pipewire/node.c index e2aa99892..900277133 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -554,6 +554,7 @@ int pw_node_register(struct pw_node *this, PW_KEY_FACTORY_ID, PW_KEY_CLIENT_ID, PW_KEY_DEVICE_ID, + PW_KEY_NODE_PRIORITY, PW_KEY_NODE_DESCRIPTION, PW_KEY_NODE_NAME, PW_KEY_NODE_NICK,