mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	use id to store default sink/source
This is easier to handle in general and we should not use the name as a unique id. If the session manager wants to save things, it can use whatever fields it wants from the object to create a unique persistent name.
This commit is contained in:
		
							parent
							
								
									db0c224b06
								
							
						
					
					
						commit
						266e1301d2
					
				
					 5 changed files with 72 additions and 94 deletions
				
			
		| 
						 | 
					@ -56,7 +56,6 @@
 | 
				
			||||||
#define JACK_DEFAULT_VIDEO_TYPE	"32 bit float RGBA video"
 | 
					#define JACK_DEFAULT_VIDEO_TYPE	"32 bit float RGBA video"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define JACK_CLIENT_NAME_SIZE		64
 | 
					#define JACK_CLIENT_NAME_SIZE		64
 | 
				
			||||||
#define JACK_CLIENT_KEY_SIZE		256
 | 
					 | 
				
			||||||
#define JACK_PORT_NAME_SIZE		256
 | 
					#define JACK_PORT_NAME_SIZE		256
 | 
				
			||||||
#define JACK_PORT_MAX			4096
 | 
					#define JACK_PORT_MAX			4096
 | 
				
			||||||
#define JACK_PORT_TYPE_SIZE             32
 | 
					#define JACK_PORT_TYPE_SIZE             32
 | 
				
			||||||
| 
						 | 
					@ -70,7 +69,6 @@
 | 
				
			||||||
#define MAX_BUFFER_DATAS		1u
 | 
					#define MAX_BUFFER_DATAS		1u
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REAL_JACK_PORT_NAME_SIZE (JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE)
 | 
					#define REAL_JACK_PORT_NAME_SIZE (JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE)
 | 
				
			||||||
#define REAL_JACK_PORT_KEY_SIZE (JACK_CLIENT_KEY_SIZE + JACK_PORT_NAME_SIZE)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME	"jack-client"
 | 
					#define NAME	"jack-client"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,7 +108,6 @@ struct object {
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
			char name[JACK_CLIENT_NAME_SIZE+1];
 | 
								char name[JACK_CLIENT_NAME_SIZE+1];
 | 
				
			||||||
			char key[JACK_CLIENT_KEY_SIZE+1];
 | 
					 | 
				
			||||||
			int32_t priority;
 | 
								int32_t priority;
 | 
				
			||||||
			uint32_t client_id;
 | 
								uint32_t client_id;
 | 
				
			||||||
		} node;
 | 
							} node;
 | 
				
			||||||
| 
						 | 
					@ -123,7 +120,6 @@ struct object {
 | 
				
			||||||
			char name[REAL_JACK_PORT_NAME_SIZE+1];
 | 
								char name[REAL_JACK_PORT_NAME_SIZE+1];
 | 
				
			||||||
			char alias1[REAL_JACK_PORT_NAME_SIZE+1];
 | 
								char alias1[REAL_JACK_PORT_NAME_SIZE+1];
 | 
				
			||||||
			char alias2[REAL_JACK_PORT_NAME_SIZE+1];
 | 
								char alias2[REAL_JACK_PORT_NAME_SIZE+1];
 | 
				
			||||||
			char key[REAL_JACK_PORT_KEY_SIZE+1];
 | 
					 | 
				
			||||||
			uint32_t type_id;
 | 
								uint32_t type_id;
 | 
				
			||||||
			uint32_t node_id;
 | 
								uint32_t node_id;
 | 
				
			||||||
			uint32_t port_id;
 | 
								uint32_t port_id;
 | 
				
			||||||
| 
						 | 
					@ -236,8 +232,8 @@ struct metadata {
 | 
				
			||||||
	struct pw_metadata *proxy;
 | 
						struct pw_metadata *proxy;
 | 
				
			||||||
	struct spa_hook listener;
 | 
						struct spa_hook listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *default_audio_sink;
 | 
						uint32_t default_audio_sink;
 | 
				
			||||||
	char *default_audio_source;
 | 
						uint32_t default_audio_source;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct client {
 | 
					struct client {
 | 
				
			||||||
| 
						 | 
					@ -1955,12 +1951,10 @@ static int metadata_property(void *object, uint32_t id,
 | 
				
			||||||
	uuid = jack_port_uuid_generate(id);
 | 
						uuid = jack_port_uuid_generate(id);
 | 
				
			||||||
	update_property(c, uuid, key, type, value);
 | 
						update_property(c, uuid, key, type, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (key && strcmp(key, "default.audio.sink.name") == 0) {
 | 
						if (key && strcmp(key, "default.audio.sink") == 0) {
 | 
				
			||||||
		free(c->metadata->default_audio_sink);
 | 
							c->metadata->default_audio_sink = value ? (uint32_t)atoi(value) : SPA_ID_INVALID;
 | 
				
			||||||
		c->metadata->default_audio_sink = value ? strdup(value) : NULL;
 | 
						} else if (key && strcmp(key, "default.audio.source") == 0) {
 | 
				
			||||||
	} else if (key && strcmp(key, "default.audio.source.name") == 0) {
 | 
							c->metadata->default_audio_source = value ? (uint32_t)atoi(value) : SPA_ID_INVALID;
 | 
				
			||||||
		free(c->metadata->default_audio_source);
 | 
					 | 
				
			||||||
		c->metadata->default_audio_source = value ? strdup(value) : NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2008,10 +2002,6 @@ static void registry_event_global(void *data, uint32_t id,
 | 
				
			||||||
		if (ot != NULL && o->node.client_id != ot->node.client_id)
 | 
							if (ot != NULL && o->node.client_id != ot->node.client_id)
 | 
				
			||||||
			snprintf(o->node.name, sizeof(o->node.name), "%s-%d", str, id);
 | 
								snprintf(o->node.name, sizeof(o->node.name), "%s-%d", str, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((str = spa_dict_lookup(props, PW_KEY_NODE_NAME)) == NULL)
 | 
					 | 
				
			||||||
			str = o->node.name;
 | 
					 | 
				
			||||||
		snprintf(o->node.key, sizeof(o->node.key), "%s", str);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ((str = spa_dict_lookup(props, PW_KEY_PRIORITY_MASTER)) != NULL)
 | 
							if ((str = spa_dict_lookup(props, PW_KEY_PRIORITY_MASTER)) != NULL)
 | 
				
			||||||
			o->node.priority = pw_properties_parse_int(str);
 | 
								o->node.priority = pw_properties_parse_int(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2084,7 +2074,6 @@ static void registry_event_global(void *data, uint32_t id,
 | 
				
			||||||
				goto exit_free;
 | 
									goto exit_free;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			snprintf(o->port.name, sizeof(o->port.name), "%s:%s", ot->node.name, str);
 | 
								snprintf(o->port.name, sizeof(o->port.name), "%s:%s", ot->node.name, str);
 | 
				
			||||||
			snprintf(o->port.key, sizeof(o->port.key), "%s:%s", ot->node.key, str);
 | 
					 | 
				
			||||||
			o->port.port_id = SPA_ID_INVALID;
 | 
								o->port.port_id = SPA_ID_INVALID;
 | 
				
			||||||
			o->port.priority = ot->node.priority;
 | 
								o->port.priority = ot->node.priority;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -2115,8 +2104,8 @@ static void registry_event_global(void *data, uint32_t id,
 | 
				
			||||||
			snprintf(o->port.name, sizeof(o->port.name), "%.*s-%d",
 | 
								snprintf(o->port.name, sizeof(o->port.name), "%.*s-%d",
 | 
				
			||||||
					(int)(sizeof(op->port.name)-11), op->port.name, id);
 | 
										(int)(sizeof(op->port.name)-11), op->port.name, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pw_log_debug(NAME" %p: add port %d name:%s key:%s %d", c, id,
 | 
							pw_log_debug(NAME" %p: add port %d name:%s %d", c, id,
 | 
				
			||||||
				o->port.name, o->port.key, type_id);
 | 
									o->port.name, type_id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (strcmp(type, PW_TYPE_INTERFACE_Link) == 0) {
 | 
						else if (strcmp(type, PW_TYPE_INTERFACE_Link) == 0) {
 | 
				
			||||||
		o = alloc_object(c);
 | 
							o = alloc_object(c);
 | 
				
			||||||
| 
						 | 
					@ -2148,6 +2137,8 @@ static void registry_event_global(void *data, uint32_t id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c->metadata = pw_proxy_get_user_data(proxy);
 | 
							c->metadata = pw_proxy_get_user_data(proxy);
 | 
				
			||||||
		c->metadata->proxy = (struct pw_metadata*)proxy;
 | 
							c->metadata->proxy = (struct pw_metadata*)proxy;
 | 
				
			||||||
 | 
							c->metadata->default_audio_sink = SPA_ID_INVALID;
 | 
				
			||||||
 | 
							c->metadata->default_audio_source = SPA_ID_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pw_metadata_add_listener(proxy,
 | 
							pw_metadata_add_listener(proxy,
 | 
				
			||||||
				&c->metadata->listener,
 | 
									&c->metadata->listener,
 | 
				
			||||||
| 
						 | 
					@ -2202,6 +2193,13 @@ static void registry_event_global_remove(void *object, uint32_t id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug(NAME" %p: removed: %u", c, id);
 | 
						pw_log_debug(NAME" %p: removed: %u", c, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->metadata) {
 | 
				
			||||||
 | 
							if (id == c->metadata->default_audio_sink)
 | 
				
			||||||
 | 
								c->metadata->default_audio_sink = SPA_ID_INVALID;
 | 
				
			||||||
 | 
							if (id == c->metadata->default_audio_source)
 | 
				
			||||||
 | 
								c->metadata->default_audio_source = SPA_ID_INVALID;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = pw_map_lookup(&c->context.globals, id);
 | 
						o = pw_map_lookup(&c->context.globals, id);
 | 
				
			||||||
	if (o == NULL)
 | 
						if (o == NULL)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -2444,8 +2442,6 @@ int jack_client_close (jack_client_t *client)
 | 
				
			||||||
		pw_proxy_destroy((struct pw_proxy*)c->registry);
 | 
							pw_proxy_destroy((struct pw_proxy*)c->registry);
 | 
				
			||||||
	if (c->metadata && c->metadata->proxy) {
 | 
						if (c->metadata && c->metadata->proxy) {
 | 
				
			||||||
		pw_proxy_destroy((struct pw_proxy*)c->metadata->proxy);
 | 
							pw_proxy_destroy((struct pw_proxy*)c->metadata->proxy);
 | 
				
			||||||
		free(c->metadata->default_audio_sink);
 | 
					 | 
				
			||||||
		free(c->metadata->default_audio_source);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pw_core_disconnect(c->core);
 | 
						pw_core_disconnect(c->core);
 | 
				
			||||||
	pw_context_destroy(c->context.context);
 | 
						pw_context_destroy(c->context.context);
 | 
				
			||||||
| 
						 | 
					@ -3967,16 +3963,17 @@ static int port_compare_func(const void *v1, const void *v2, void *arg)
 | 
				
			||||||
	is_cap1 = ((*o1)->port.flags & JackPortIsOutput) == JackPortIsOutput;
 | 
						is_cap1 = ((*o1)->port.flags & JackPortIsOutput) == JackPortIsOutput;
 | 
				
			||||||
	is_cap2 = ((*o2)->port.flags & JackPortIsOutput) == JackPortIsOutput;
 | 
						is_cap2 = ((*o2)->port.flags & JackPortIsOutput) == JackPortIsOutput;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (is_cap1 && c->metadata->default_audio_source != NULL)
 | 
						if (c->metadata) {
 | 
				
			||||||
		is_def1 = strstr((*o1)->port.key, c->metadata->default_audio_source) == (*o1)->port.key;
 | 
							if (is_cap1)
 | 
				
			||||||
	else if (!is_cap1 && c->metadata->default_audio_sink != NULL)
 | 
								is_def1 = (*o1)->port.node_id == c->metadata->default_audio_source;
 | 
				
			||||||
		is_def1 = strstr((*o1)->port.key, c->metadata->default_audio_sink) == (*o1)->port.key;
 | 
							else if (!is_cap1)
 | 
				
			||||||
 | 
								is_def1 = (*o1)->port.node_id == c->metadata->default_audio_sink;
 | 
				
			||||||
	if (is_cap2 && c->metadata->default_audio_source != NULL)
 | 
					 | 
				
			||||||
		is_def2 = strstr((*o2)->port.key, c->metadata->default_audio_source) == (*o2)->port.key;
 | 
					 | 
				
			||||||
	else if (!is_cap2 && c->metadata->default_audio_sink != NULL)
 | 
					 | 
				
			||||||
		is_def2 = strstr((*o2)->port.key, c->metadata->default_audio_sink) == (*o2)->port.key;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (is_cap2)
 | 
				
			||||||
 | 
								is_def2 = (*o2)->port.node_id == c->metadata->default_audio_source;
 | 
				
			||||||
 | 
							else if (!is_cap2)
 | 
				
			||||||
 | 
								is_def2 = (*o2)->port.node_id == c->metadata->default_audio_sink;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if ((*o1)->port.type_id != (*o2)->port.type_id)
 | 
						if ((*o1)->port.type_id != (*o2)->port.type_id)
 | 
				
			||||||
		res = (*o1)->port.type_id - (*o2)->port.type_id;
 | 
							res = (*o1)->port.type_id - (*o2)->port.type_id;
 | 
				
			||||||
	else if ((is_cap1 || is_cap2) && is_cap1 != is_cap2)
 | 
						else if ((is_cap1 || is_cap2) && is_cap1 != is_cap2)
 | 
				
			||||||
| 
						 | 
					@ -3988,8 +3985,7 @@ static int port_compare_func(const void *v1, const void *v2, void *arg)
 | 
				
			||||||
	else if ((res = strcmp((*o1)->port.alias1, (*o2)->port.alias1) == 0))
 | 
						else if ((res = strcmp((*o1)->port.alias1, (*o2)->port.alias1) == 0))
 | 
				
			||||||
		res = (*o1)->id - (*o2)->id;
 | 
							res = (*o1)->id - (*o2)->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug("port %s %s type:%d<->%d def:%d<->%d prio:%d<->%d id:%d<->%d res:%d",
 | 
						pw_log_debug("port type:%d<->%d def:%d<->%d prio:%d<->%d id:%d<->%d res:%d",
 | 
				
			||||||
			(*o1)->port.key, (*o2)->port.key,
 | 
					 | 
				
			||||||
			(*o1)->port.type_id, (*o2)->port.type_id,
 | 
								(*o1)->port.type_id, (*o2)->port.type_id,
 | 
				
			||||||
			is_def1, is_def2,
 | 
								is_def1, is_def2,
 | 
				
			||||||
			(*o1)->port.priority, (*o2)->port.priority,
 | 
								(*o1)->port.priority, (*o2)->port.priority,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1619,8 +1619,10 @@ static void do_default_node(pa_operation *o, void *userdata)
 | 
				
			||||||
	if (g == NULL) {
 | 
						if (g == NULL) {
 | 
				
			||||||
		error = PA_ERR_NOENTITY;
 | 
							error = PA_ERR_NOENTITY;
 | 
				
			||||||
	} else if (c->metadata) {
 | 
						} else if (c->metadata) {
 | 
				
			||||||
 | 
							char buf[16];
 | 
				
			||||||
 | 
							snprintf(buf, sizeof(buf), "%d", g->id);
 | 
				
			||||||
		pw_metadata_set_property(c->metadata->proxy,
 | 
							pw_metadata_set_property(c->metadata->proxy,
 | 
				
			||||||
				PW_ID_CORE, d->key, "text/plain", d->name);
 | 
									PW_ID_CORE, d->key, SPA_TYPE_INFO_BASE"Id", buf);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		error = PA_ERR_NOTIMPLEMENTED;
 | 
							error = PA_ERR_NOTIMPLEMENTED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -481,8 +481,9 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb
 | 
				
			||||||
void pa_operation_done(pa_operation *o);
 | 
					void pa_operation_done(pa_operation *o);
 | 
				
			||||||
int pa_operation_sync(pa_operation *o);
 | 
					int pa_operation_sync(pa_operation *o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define METADATA_DEFAULT_SINK		"default.audio.sink.name"
 | 
					#define METADATA_DEFAULT_SINK		"default.audio.sink"
 | 
				
			||||||
#define METADATA_DEFAULT_SOURCE		"default.audio.source.name"
 | 
					#define METADATA_DEFAULT_SOURCE		"default.audio.source"
 | 
				
			||||||
 | 
					#define METADATA_TARGET_NODE		"target.node"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_metadata_update(struct global *global, uint32_t subject, const char *key,
 | 
					int pa_metadata_update(struct global *global, uint32_t subject, const char *key,
 | 
				
			||||||
                        const char *type, const char *value);
 | 
					                        const char *type, const char *value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1244,7 +1244,7 @@ struct server_data {
 | 
				
			||||||
static const char *get_default_name(pa_context *c, uint32_t mask)
 | 
					static const char *get_default_name(pa_context *c, uint32_t mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct global *g;
 | 
						struct global *g;
 | 
				
			||||||
	const char *str, *name = NULL, *type, *key;
 | 
						const char *str, *id = NULL, *type, *key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c->metadata) {
 | 
						if (c->metadata) {
 | 
				
			||||||
		if (mask & PA_SUBSCRIPTION_MASK_SINK)
 | 
							if (mask & PA_SUBSCRIPTION_MASK_SINK)
 | 
				
			||||||
| 
						 | 
					@ -1254,15 +1254,15 @@ static const char *get_default_name(pa_context *c, uint32_t mask)
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (pa_metadata_get(c->metadata, PW_ID_CORE, key, &type, &name) <= 0)
 | 
							if (pa_metadata_get(c->metadata, PW_ID_CORE, key, &type, &id) <= 0)
 | 
				
			||||||
			name = NULL;
 | 
								id = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	spa_list_for_each(g, &c->globals, link) {
 | 
						spa_list_for_each(g, &c->globals, link) {
 | 
				
			||||||
		if ((g->mask & mask) != mask)
 | 
							if ((g->mask & mask) != mask)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (g->props != NULL &&
 | 
							if (g->props != NULL &&
 | 
				
			||||||
		    (str = pw_properties_get(g->props, PW_KEY_NODE_NAME)) != NULL &&
 | 
							    (str = pw_properties_get(g->props, PW_KEY_NODE_NAME)) != NULL &&
 | 
				
			||||||
		    (name == NULL || strcmp(name, str) == 0))
 | 
							    (id == NULL || (uint32_t)atoi(id) == g->id))
 | 
				
			||||||
			return str;
 | 
								return str;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return "unknown";
 | 
						return "unknown";
 | 
				
			||||||
| 
						 | 
					@ -2043,7 +2043,6 @@ struct target_node {
 | 
				
			||||||
	pa_context_success_cb_t cb;
 | 
						pa_context_success_cb_t cb;
 | 
				
			||||||
	void *userdata;
 | 
						void *userdata;
 | 
				
			||||||
	const char *key;
 | 
						const char *key;
 | 
				
			||||||
	const char *type;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void do_target_node(pa_operation *o, void *userdata)
 | 
					static void do_target_node(pa_operation *o, void *userdata)
 | 
				
			||||||
| 
						 | 
					@ -2067,15 +2066,14 @@ static void do_target_node(pa_operation *o, void *userdata)
 | 
				
			||||||
		if ((g = pa_context_find_global(c, d->target_idx)) == NULL ||
 | 
							if ((g = pa_context_find_global(c, d->target_idx)) == NULL ||
 | 
				
			||||||
		    !(g->mask & d->target_mask))
 | 
							    !(g->mask & d->target_mask))
 | 
				
			||||||
			g = NULL;
 | 
								g = NULL;
 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			d->target_name = spa_aprintf("%d", g->id);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (g == NULL) {
 | 
						if (g == NULL) {
 | 
				
			||||||
		error = PA_ERR_NOENTITY;
 | 
							error = PA_ERR_NOENTITY;
 | 
				
			||||||
	} else if (c->metadata) {
 | 
						} else if (c->metadata) {
 | 
				
			||||||
 | 
							char buf[16];
 | 
				
			||||||
 | 
							snprintf(buf, sizeof(buf), "%d", g->id);
 | 
				
			||||||
		pw_metadata_set_property(c->metadata->proxy,
 | 
							pw_metadata_set_property(c->metadata->proxy,
 | 
				
			||||||
				d->idx, d->key, d->type, d->target_name);
 | 
									d->idx, d->key, SPA_TYPE_INFO_BASE "Id", buf);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		error = PA_ERR_NOTIMPLEMENTED;
 | 
							error = PA_ERR_NOTIMPLEMENTED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2102,8 +2100,7 @@ pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, co
 | 
				
			||||||
	d->mask = PA_SUBSCRIPTION_MASK_SINK_INPUT;
 | 
						d->mask = PA_SUBSCRIPTION_MASK_SINK_INPUT;
 | 
				
			||||||
	d->target_name = pa_xstrdup(sink_name);
 | 
						d->target_name = pa_xstrdup(sink_name);
 | 
				
			||||||
	d->target_mask = PA_SUBSCRIPTION_MASK_SINK;
 | 
						d->target_mask = PA_SUBSCRIPTION_MASK_SINK;
 | 
				
			||||||
	d->key = "target.node.name";
 | 
						d->key = METADATA_TARGET_NODE;
 | 
				
			||||||
	d->type = SPA_TYPE_INFO_BASE "String";
 | 
					 | 
				
			||||||
	d->cb = cb;
 | 
						d->cb = cb;
 | 
				
			||||||
	d->userdata = userdata;
 | 
						d->userdata = userdata;
 | 
				
			||||||
	pa_operation_sync(o);
 | 
						pa_operation_sync(o);
 | 
				
			||||||
| 
						 | 
					@ -2125,8 +2122,7 @@ pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, u
 | 
				
			||||||
	d->mask = PA_SUBSCRIPTION_MASK_SINK_INPUT;
 | 
						d->mask = PA_SUBSCRIPTION_MASK_SINK_INPUT;
 | 
				
			||||||
	d->target_idx = sink_idx;
 | 
						d->target_idx = sink_idx;
 | 
				
			||||||
	d->target_mask = PA_SUBSCRIPTION_MASK_SINK;
 | 
						d->target_mask = PA_SUBSCRIPTION_MASK_SINK;
 | 
				
			||||||
	d->key = "target.node";
 | 
						d->key = METADATA_TARGET_NODE;
 | 
				
			||||||
	d->type = SPA_TYPE_INFO_BASE "Id";
 | 
					 | 
				
			||||||
	d->cb = cb;
 | 
						d->cb = cb;
 | 
				
			||||||
	d->userdata = userdata;
 | 
						d->userdata = userdata;
 | 
				
			||||||
	pa_operation_sync(o);
 | 
						pa_operation_sync(o);
 | 
				
			||||||
| 
						 | 
					@ -2459,8 +2455,7 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx,
 | 
				
			||||||
	d->mask = PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT;
 | 
						d->mask = PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT;
 | 
				
			||||||
	d->target_name = pa_xstrdup(source_name);
 | 
						d->target_name = pa_xstrdup(source_name);
 | 
				
			||||||
	d->target_mask = PA_SUBSCRIPTION_MASK_SOURCE;
 | 
						d->target_mask = PA_SUBSCRIPTION_MASK_SOURCE;
 | 
				
			||||||
	d->key = "target.node.name";
 | 
						d->key = METADATA_TARGET_NODE;
 | 
				
			||||||
	d->type = SPA_TYPE_INFO_BASE "String";
 | 
					 | 
				
			||||||
	d->cb = cb;
 | 
						d->cb = cb;
 | 
				
			||||||
	d->userdata = userdata;
 | 
						d->userdata = userdata;
 | 
				
			||||||
	pa_operation_sync(o);
 | 
						pa_operation_sync(o);
 | 
				
			||||||
| 
						 | 
					@ -2482,8 +2477,7 @@ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx
 | 
				
			||||||
	d->mask = PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT;
 | 
						d->mask = PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT;
 | 
				
			||||||
	d->target_idx = source_idx;
 | 
						d->target_idx = source_idx;
 | 
				
			||||||
	d->target_mask = PA_SUBSCRIPTION_MASK_SOURCE;
 | 
						d->target_mask = PA_SUBSCRIPTION_MASK_SOURCE;
 | 
				
			||||||
	d->key = "target.node";
 | 
						d->key = METADATA_TARGET_NODE;
 | 
				
			||||||
	d->type = SPA_TYPE_INFO_BASE "Id";
 | 
					 | 
				
			||||||
	d->cb = cb;
 | 
						d->cb = cb;
 | 
				
			||||||
	d->userdata = userdata;
 | 
						d->userdata = userdata;
 | 
				
			||||||
	pa_operation_sync(o);
 | 
						pa_operation_sync(o);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,8 +61,8 @@ struct impl {
 | 
				
			||||||
	struct spa_list node_list;
 | 
						struct spa_list node_list;
 | 
				
			||||||
	int seq;
 | 
						int seq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *default_audio_sink;
 | 
						uint32_t default_audio_sink;
 | 
				
			||||||
	char *default_audio_source;
 | 
						uint32_t default_audio_source;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct node {
 | 
					struct node {
 | 
				
			||||||
| 
						 | 
					@ -334,6 +334,10 @@ static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
			if (n->peer == node)
 | 
								if (n->peer == node)
 | 
				
			||||||
				n->peer = NULL;
 | 
									n->peer = NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (impl->default_audio_sink == object->id)
 | 
				
			||||||
 | 
								impl->default_audio_sink = SPA_ID_INVALID;
 | 
				
			||||||
 | 
							if (impl->default_audio_source == object->id)
 | 
				
			||||||
 | 
								impl->default_audio_source = SPA_ID_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sm_media_session_schedule_rescan(impl->session);
 | 
						sm_media_session_schedule_rescan(impl->session);
 | 
				
			||||||
| 
						 | 
					@ -355,7 +359,6 @@ static int find_node(void *data, struct node *node)
 | 
				
			||||||
	int priority = 0;
 | 
						int priority = 0;
 | 
				
			||||||
	uint64_t plugged = 0;
 | 
						uint64_t plugged = 0;
 | 
				
			||||||
	struct sm_device *device = node->obj->device;
 | 
						struct sm_device *device = node->obj->device;
 | 
				
			||||||
	const char *name;
 | 
					 | 
				
			||||||
	bool is_default = false;
 | 
						bool is_default = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug(NAME " %p: looking at node '%d' enabled:%d state:%d peer:%p exclusive:%d",
 | 
						pw_log_debug(NAME " %p: looking at node '%d' enabled:%d state:%d peer:%p exclusive:%d",
 | 
				
			||||||
| 
						 | 
					@ -377,15 +380,11 @@ static int find_node(void *data, struct node *node)
 | 
				
			||||||
		pw_log_debug(".. incompatible media %s <-> %s", node->media, find->target->media);
 | 
							pw_log_debug(".. incompatible media %s <-> %s", node->media, find->target->media);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((name = pw_properties_get(node->obj->obj.props, PW_KEY_NODE_NAME)) != NULL) {
 | 
					 | 
				
			||||||
	if (node->media && strcmp(node->media, "Audio") == 0) {
 | 
						if (node->media && strcmp(node->media, "Audio") == 0) {
 | 
				
			||||||
			if (node->direction == PW_DIRECTION_INPUT &&
 | 
							if (node->direction == PW_DIRECTION_INPUT)
 | 
				
			||||||
			    impl->default_audio_sink != NULL)
 | 
								is_default = impl->default_audio_sink == node->id;
 | 
				
			||||||
				is_default = strcmp(impl->default_audio_sink, name) == 0;
 | 
							else if (node->direction == PW_DIRECTION_OUTPUT)
 | 
				
			||||||
			else if (node->direction == PW_DIRECTION_OUTPUT &&
 | 
								is_default = impl->default_audio_source == node->id;
 | 
				
			||||||
			    impl->default_audio_source != NULL)
 | 
					 | 
				
			||||||
				is_default = strcmp(impl->default_audio_source, name) == 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	plugged = node->plugged;
 | 
						plugged = node->plugged;
 | 
				
			||||||
| 
						 | 
					@ -640,28 +639,15 @@ static struct node *find_node_by_id(struct impl *impl, uint32_t id)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct node *find_node_by_name(struct impl *impl, const char *name)
 | 
					static int move_node(struct impl *impl, uint32_t source, uint32_t target)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const char *str;
 | 
					 | 
				
			||||||
	struct node *node;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spa_list_for_each(node, &impl->node_list, link) {
 | 
					 | 
				
			||||||
		str = pw_properties_get(node->obj->obj.props, "node.name");
 | 
					 | 
				
			||||||
		if (str && strcmp(str, name) == 0)
 | 
					 | 
				
			||||||
			return node;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int move_node(struct impl *impl, const char *source, const char *target)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct node *n, *src_node, *dst_node;
 | 
						struct node *n, *src_node, *dst_node;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* find source and dest node */
 | 
						/* find source and dest node */
 | 
				
			||||||
	if ((src_node = find_node_by_name(impl, source)) == NULL)
 | 
						if ((src_node = find_node_by_id(impl, source)) == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
	if ((dst_node = find_node_by_name(impl, target)) == NULL)
 | 
						if ((dst_node = find_node_by_id(impl, target)) == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (src_node == dst_node)
 | 
						if (src_node == dst_node)
 | 
				
			||||||
| 
						 | 
					@ -694,6 +680,8 @@ static int handle_move(struct impl *impl, struct node *src_node, struct node *ds
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	struct pw_node_info *info;
 | 
						struct pw_node_info *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (src_node->peer == dst_node)
 | 
						if (src_node->peer == dst_node)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -722,21 +710,19 @@ static int metadata_property(void *object, uint32_t subject,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = object;
 | 
						struct impl *impl = object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (key == NULL || type == NULL)
 | 
						if (key == NULL)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (subject == PW_ID_CORE) {
 | 
						if (subject == PW_ID_CORE) {
 | 
				
			||||||
		if (strcmp(key, "default.audio.sink.name") == 0) {
 | 
							if (strcmp(key, "default.audio.sink") == 0) {
 | 
				
			||||||
			if (impl->default_audio_sink && value)
 | 
								if (impl->default_audio_sink != SPA_ID_INVALID && value)
 | 
				
			||||||
				move_node(impl, impl->default_audio_sink, value);
 | 
									move_node(impl, impl->default_audio_sink, atoi(value));
 | 
				
			||||||
			free(impl->default_audio_sink);
 | 
								impl->default_audio_sink = value ? (uint32_t)atoi(value) : SPA_ID_INVALID;
 | 
				
			||||||
			impl->default_audio_sink = value ? strdup(value) : NULL;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (strcmp(key, "default.audio.source.name") == 0) {
 | 
							else if (strcmp(key, "default.audio.source") == 0) {
 | 
				
			||||||
			if (impl->default_audio_source && value)
 | 
								if (impl->default_audio_source != SPA_ID_INVALID && value)
 | 
				
			||||||
				move_node(impl, impl->default_audio_source, value);
 | 
									move_node(impl, impl->default_audio_source, atoi(value));
 | 
				
			||||||
			free(impl->default_audio_source);
 | 
								impl->default_audio_source = value ? (uint32_t)atoi(value) : SPA_ID_INVALID;
 | 
				
			||||||
			impl->default_audio_source = value ? strdup(value) : NULL;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct node *src_node, *dst_node = NULL;
 | 
							struct node *src_node, *dst_node = NULL;
 | 
				
			||||||
| 
						 | 
					@ -746,9 +732,6 @@ static int metadata_property(void *object, uint32_t subject,
 | 
				
			||||||
		if (strcmp(key, "target.node") == 0 && value != NULL) {
 | 
							if (strcmp(key, "target.node") == 0 && value != NULL) {
 | 
				
			||||||
			dst_node = find_node_by_id(impl, atoi(value));
 | 
								dst_node = find_node_by_id(impl, atoi(value));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (strcmp(key, "target.node.name") == 0 && value != NULL) {
 | 
					 | 
				
			||||||
			dst_node = find_node_by_name(impl, value);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (src_node && dst_node)
 | 
							if (src_node && dst_node)
 | 
				
			||||||
			handle_move(impl, src_node, dst_node);
 | 
								handle_move(impl, src_node, dst_node);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -773,6 +756,8 @@ int sm_policy_node_start(struct sm_media_session *session)
 | 
				
			||||||
	impl->context = session->context;
 | 
						impl->context = session->context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->sample_rate = 48000;
 | 
						impl->sample_rate = 48000;
 | 
				
			||||||
 | 
						impl->default_audio_sink = SPA_ID_INVALID;
 | 
				
			||||||
 | 
						impl->default_audio_source = SPA_ID_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_init(&impl->node_list);
 | 
						spa_list_init(&impl->node_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue