mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
jack: do better port sorting
First sort by type, then by master priority, then by port id.
This commit is contained in:
parent
8997a078aa
commit
d9e9c6b7c8
1 changed files with 63 additions and 50 deletions
|
|
@ -95,6 +95,7 @@ struct object {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
char name[JACK_CLIENT_NAME_SIZE+1];
|
char name[JACK_CLIENT_NAME_SIZE+1];
|
||||||
|
int32_t priority;
|
||||||
} node;
|
} node;
|
||||||
struct {
|
struct {
|
||||||
uint32_t src;
|
uint32_t src;
|
||||||
|
|
@ -111,6 +112,7 @@ struct object {
|
||||||
uint32_t monitor_requests;
|
uint32_t monitor_requests;
|
||||||
jack_latency_range_t capture_latency;
|
jack_latency_range_t capture_latency;
|
||||||
jack_latency_range_t playback_latency;
|
jack_latency_range_t playback_latency;
|
||||||
|
int32_t priority;
|
||||||
} port;
|
} port;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -740,7 +742,6 @@ static void process_tee(struct client *c)
|
||||||
{
|
{
|
||||||
struct port *p;
|
struct port *p;
|
||||||
|
|
||||||
|
|
||||||
spa_list_for_each(p, &c->ports[SPA_DIRECTION_OUTPUT], link) {
|
spa_list_for_each(p, &c->ports[SPA_DIRECTION_OUTPUT], link) {
|
||||||
if (p->object->port.type_id != 1)
|
if (p->object->port.type_id != 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1729,17 +1730,20 @@ static void registry_event_global(void *data, uint32_t id,
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PW_TYPE_INTERFACE_Node:
|
case PW_TYPE_INTERFACE_Node:
|
||||||
|
o = alloc_object(c);
|
||||||
|
|
||||||
if ((str = spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION)) == NULL &&
|
if ((str = spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION)) == NULL &&
|
||||||
(str = spa_dict_lookup(props, PW_KEY_NODE_NICK)) == NULL &&
|
(str = spa_dict_lookup(props, PW_KEY_NODE_NICK)) == NULL &&
|
||||||
(str = spa_dict_lookup(props, PW_KEY_NODE_NAME)) == NULL) {
|
(str = spa_dict_lookup(props, PW_KEY_NODE_NAME)) == NULL) {
|
||||||
str = "node";
|
str = "node";
|
||||||
}
|
}
|
||||||
|
|
||||||
o = alloc_object(c);
|
|
||||||
spa_list_append(&c->context.nodes, &o->link);
|
|
||||||
|
|
||||||
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_PRIORITY_MASTER)) != NULL)
|
||||||
|
o->node.priority = pw_properties_parse_int(str);
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: add node %d", c, id);
|
pw_log_debug(NAME" %p: add node %d", c, id);
|
||||||
|
spa_list_append(&c->context.nodes, &o->link);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PW_TYPE_INTERFACE_Port:
|
case PW_TYPE_INTERFACE_Port:
|
||||||
|
|
@ -1805,6 +1809,7 @@ static void registry_event_global(void *data, uint32_t id,
|
||||||
|
|
||||||
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);
|
||||||
o->port.port_id = SPA_ID_INVALID;
|
o->port.port_id = SPA_ID_INVALID;
|
||||||
|
o->port.priority = ot->node.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((str = spa_dict_lookup(props, PW_KEY_OBJECT_PATH)) != NULL)
|
if ((str = spa_dict_lookup(props, PW_KEY_OBJECT_PATH)) != NULL)
|
||||||
|
|
@ -2745,7 +2750,7 @@ int jack_port_unregister (jack_client_t *client, jack_port_t *port)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *mix_audio(struct client *c, struct port *p, jack_nframes_t frames)
|
static inline void *get_buffer_input_float(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
{
|
{
|
||||||
struct mix *mix;
|
struct mix *mix;
|
||||||
struct buffer *b;
|
struct buffer *b;
|
||||||
|
|
@ -2773,7 +2778,7 @@ static void *mix_audio(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *mix_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
static inline void *get_buffer_input_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
{
|
{
|
||||||
struct mix *mix;
|
struct mix *mix;
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
|
|
@ -2809,16 +2814,6 @@ static void *mix_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *get_buffer_input_float(struct client *c, struct port *p, jack_nframes_t frames)
|
|
||||||
{
|
|
||||||
return mix_audio(c, p, frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *get_buffer_input_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
|
||||||
{
|
|
||||||
return mix_midi(c, p, frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *get_buffer_output_float(struct client *c, struct port *p, jack_nframes_t frames)
|
static inline void *get_buffer_output_float(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
@ -3468,6 +3463,19 @@ int jack_recompute_total_latency (jack_client_t *client, jack_port_t* port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int port_compare_func(const void *v1, const void *v2)
|
||||||
|
{
|
||||||
|
const struct object *const*o1 = v1, *const*o2 = v2;
|
||||||
|
|
||||||
|
if ((*o1)->port.type_id != (*o2)->port.type_id)
|
||||||
|
return (*o1)->port.type_id - (*o2)->port.type_id;
|
||||||
|
|
||||||
|
if ((*o1)->port.priority != (*o2)->port.priority)
|
||||||
|
return (*o2)->port.priority - (*o1)->port.priority;
|
||||||
|
|
||||||
|
return (*o1)->id - (*o2)->id;
|
||||||
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
const char ** jack_get_ports (jack_client_t *client,
|
const char ** jack_get_ports (jack_client_t *client,
|
||||||
const char *port_name_pattern,
|
const char *port_name_pattern,
|
||||||
|
|
@ -3475,11 +3483,11 @@ const char ** jack_get_ports (jack_client_t *client,
|
||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
struct client *c = (struct client *) client;
|
struct client *c = (struct client *) client;
|
||||||
const char **res = malloc(sizeof(char*) * (JACK_PORT_MAX + 1));
|
const char **res;
|
||||||
int count = 0;
|
|
||||||
struct object *o;
|
struct object *o;
|
||||||
|
struct object *tmp[JACK_PORT_MAX];
|
||||||
const char *str;
|
const char *str;
|
||||||
uint32_t i, id;
|
uint32_t i, count, id;
|
||||||
regex_t port_regex, type_regex;
|
regex_t port_regex, type_regex;
|
||||||
|
|
||||||
if ((str = getenv("PIPEWIRE_NODE")) != NULL)
|
if ((str = getenv("PIPEWIRE_NODE")) != NULL)
|
||||||
|
|
@ -3497,40 +3505,45 @@ const char ** jack_get_ports (jack_client_t *client,
|
||||||
pw_log_debug(NAME" %p: ports id:%d name:%s type:%s flags:%08lx", c, id,
|
pw_log_debug(NAME" %p: ports id:%d name:%s type:%s flags:%08lx", c, id,
|
||||||
port_name_pattern, type_name_pattern, flags);
|
port_name_pattern, type_name_pattern, flags);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
count = 0;
|
||||||
spa_list_for_each(o, &c->context.ports, link) {
|
spa_list_for_each(o, &c->context.ports, link) {
|
||||||
pw_log_debug(NAME" %p: check port type:%d flags:%08lx name:%s", c,
|
pw_log_debug(NAME" %p: check port type:%d flags:%08lx name:%s", c,
|
||||||
o->port.type_id, o->port.flags, o->port.name);
|
o->port.type_id, o->port.flags, o->port.name);
|
||||||
if (count == JACK_PORT_MAX)
|
if (count == JACK_PORT_MAX)
|
||||||
break;
|
break;
|
||||||
if (o->port.type_id != i)
|
if (o->port.type_id > 1)
|
||||||
continue;
|
continue;
|
||||||
if (!SPA_FLAG_IS_SET(o->port.flags, flags))
|
if (!SPA_FLAG_IS_SET(o->port.flags, flags))
|
||||||
continue;
|
continue;
|
||||||
if (id != SPA_ID_INVALID && o->port.node_id != id)
|
if (id != SPA_ID_INVALID && o->port.node_id != id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (port_name_pattern && port_name_pattern[0]) {
|
if (port_name_pattern && port_name_pattern[0]) {
|
||||||
if (regexec(&port_regex, o->port.name, 0, NULL, 0) == REG_NOMATCH)
|
if (regexec(&port_regex, o->port.name, 0, NULL, 0) == REG_NOMATCH)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (type_name_pattern && type_name_pattern[0]) {
|
if (type_name_pattern && type_name_pattern[0]) {
|
||||||
if (regexec(&type_regex, type_to_string(o->port.type_id),
|
if (regexec(&type_regex, type_to_string(o->port.type_id),
|
||||||
0, NULL, 0) == REG_NOMATCH)
|
0, NULL, 0) == REG_NOMATCH)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: port %s matches (%d)", c, o->port.name, count);
|
|
||||||
res[count++] = o->port.name;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
pw_thread_loop_unlock(c->context.loop);
|
|
||||||
|
|
||||||
if (count == 0) {
|
pw_log_debug(NAME" %p: port %s prio:%d matches (%d)",
|
||||||
free(res);
|
c, o->port.name, o->port.priority, count);
|
||||||
res = NULL;
|
tmp[count++] = o;
|
||||||
} else
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
qsort(tmp, count, sizeof(struct object *), port_compare_func);
|
||||||
|
|
||||||
|
res = malloc(sizeof(char*) * (count + 1));
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
res[i] = tmp[i]->port.name;
|
||||||
res[count] = NULL;
|
res[count] = NULL;
|
||||||
|
} else {
|
||||||
|
res = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_thread_loop_unlock(c->context.loop);
|
||||||
|
|
||||||
if (port_name_pattern && port_name_pattern[0])
|
if (port_name_pattern && port_name_pattern[0])
|
||||||
regfree(&port_regex);
|
regfree(&port_regex);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue