mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
pulse-server: add port_type and availability-group
This commit is contained in:
parent
8116da41b9
commit
0320eca79e
4 changed files with 77 additions and 10 deletions
|
|
@ -88,7 +88,7 @@ enum acp_available {
|
||||||
const char *acp_available_str(enum acp_available status);
|
const char *acp_available_str(enum acp_available status);
|
||||||
|
|
||||||
#define ACP_KEY_PORT_TYPE "port.type" /**< a Port type, like "aux", "speaker", ... */
|
#define ACP_KEY_PORT_TYPE "port.type" /**< a Port type, like "aux", "speaker", ... */
|
||||||
#define ACP_KEY_PORT_AVAILABLE_GROUP "port.available-group"
|
#define ACP_KEY_PORT_AVAILABILITY_GROUP "port.availability-group"
|
||||||
/**< An indentifier for the group of ports that share their availability status with
|
/**< An indentifier for the group of ports that share their availability status with
|
||||||
* each other. This is meant especially for handling cases where one 3.5 mm connector
|
* each other. This is meant especially for handling cases where one 3.5 mm connector
|
||||||
* is used for headphones, headsets and microphones, and the hardware can only tell
|
* is used for headphones, headsets and microphones, and the hardware can only tell
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, si
|
||||||
p->proplist = pa_proplist_new();
|
p->proplist = pa_proplist_new();
|
||||||
pa_proplist_sets(p->proplist, ACP_KEY_PORT_TYPE, str_port_type(data->type));
|
pa_proplist_sets(p->proplist, ACP_KEY_PORT_TYPE, str_port_type(data->type));
|
||||||
if (p->availability_group)
|
if (p->availability_group)
|
||||||
pa_proplist_sets(p->proplist, ACP_KEY_PORT_AVAILABLE_GROUP, p->availability_group);
|
pa_proplist_sets(p->proplist, ACP_KEY_PORT_AVAILABILITY_GROUP, p->availability_group);
|
||||||
|
|
||||||
p->user_data = (void*)((uint8_t*)p + sizeof(pa_device_port));
|
p->user_data = (void*)((uint8_t*)p + sizeof(pa_device_port));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -330,3 +330,39 @@ enum {
|
||||||
SOURCE_DYNAMIC_LATENCY = 0x0040U,
|
SOURCE_DYNAMIC_LATENCY = 0x0040U,
|
||||||
SOURCE_FLAT_VOLUME = 0x0080U,
|
SOURCE_FLAT_VOLUME = 0x0080U,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *port_types[] = {
|
||||||
|
"unknown",
|
||||||
|
"aux",
|
||||||
|
"speaker",
|
||||||
|
"headphones",
|
||||||
|
"line",
|
||||||
|
"mic",
|
||||||
|
"headset",
|
||||||
|
"handset",
|
||||||
|
"earpiece",
|
||||||
|
"spdif",
|
||||||
|
"hdmi",
|
||||||
|
"tv",
|
||||||
|
"radio",
|
||||||
|
"video",
|
||||||
|
"usb",
|
||||||
|
"bluetooth",
|
||||||
|
"portable",
|
||||||
|
"handsfree",
|
||||||
|
"car",
|
||||||
|
"hifi",
|
||||||
|
"phone",
|
||||||
|
"network",
|
||||||
|
"analog",
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t port_type_value(const char *port_type)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < SPA_N_ELEMENTS(port_types); i++) {
|
||||||
|
if (strcmp(port_types[i], port_type) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2803,9 +2803,9 @@ static int fill_card_info(struct client *client, struct message *m,
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
|
|
||||||
spa_list_for_each(p, &o->param_list, link) {
|
spa_list_for_each(p, &o->param_list, link) {
|
||||||
uint32_t id, priority, *pr = NULL, n_pr = 0;
|
uint32_t id, priority, *pr = NULL, n_pr = 0, port_type = 0;
|
||||||
enum spa_direction direction;
|
enum spa_direction direction;
|
||||||
const char *name = NULL, *description = NULL;
|
const char *name = NULL, *description = NULL, *availability_group = NULL;
|
||||||
enum spa_param_availability available = SPA_PARAM_AVAILABILITY_unknown;
|
enum spa_param_availability available = SPA_PARAM_AVAILABILITY_unknown;
|
||||||
struct spa_pod *profiles = NULL, *info = NULL, *devices = NULL;
|
struct spa_pod *profiles = NULL, *info = NULL, *devices = NULL;
|
||||||
struct spa_dict dict, *pdict = NULL;
|
struct spa_dict dict, *pdict = NULL;
|
||||||
|
|
@ -2844,6 +2844,10 @@ static int fill_card_info(struct client *client, struct message *m,
|
||||||
SPA_POD_String(&items[n].value),
|
SPA_POD_String(&items[n].value),
|
||||||
NULL) < 0)
|
NULL) < 0)
|
||||||
break;
|
break;
|
||||||
|
if (strcmp(items[n].key, "port.availability-group") == 0)
|
||||||
|
availability_group = items[n].value;
|
||||||
|
else if (strcmp(items[n].key, "port.type") == 0)
|
||||||
|
port_type = port_type_value(items[n].value);
|
||||||
}
|
}
|
||||||
spa_pod_parser_pop(&prs, &f[0]);
|
spa_pod_parser_pop(&prs, &f[0]);
|
||||||
dict = SPA_DICT_INIT(items, n);
|
dict = SPA_DICT_INIT(items, n);
|
||||||
|
|
@ -2879,8 +2883,8 @@ static int fill_card_info(struct client *client, struct message *m,
|
||||||
}
|
}
|
||||||
if (client->version >= 34) {
|
if (client->version >= 34) {
|
||||||
message_put(m,
|
message_put(m,
|
||||||
TAG_STRING, NULL, /* available group */
|
TAG_STRING, availability_group, /* available group */
|
||||||
TAG_U32, 0, /* port type */
|
TAG_U32, port_type, /* port type */
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2970,7 +2974,7 @@ struct port_info {
|
||||||
const char *description;
|
const char *description;
|
||||||
uint32_t priority;
|
uint32_t priority;
|
||||||
uint32_t available;
|
uint32_t available;
|
||||||
const char *available_group;
|
const char *availability_group;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2986,7 +2990,7 @@ static uint32_t collect_port_info(struct pw_manager_object *card, struct device_
|
||||||
n = 0;
|
n = 0;
|
||||||
spa_list_for_each(p, &card->param_list, link) {
|
spa_list_for_each(p, &card->param_list, link) {
|
||||||
uint32_t id, direction;
|
uint32_t id, direction;
|
||||||
struct spa_pod *devices = NULL, *profiles = NULL;
|
struct spa_pod *devices = NULL, *profiles = NULL, *info = NULL;
|
||||||
struct port_info *pi;
|
struct port_info *pi;
|
||||||
|
|
||||||
if (p->id != SPA_PARAM_EnumRoute)
|
if (p->id != SPA_PARAM_EnumRoute)
|
||||||
|
|
@ -3003,6 +3007,7 @@ static uint32_t collect_port_info(struct pw_manager_object *card, struct device_
|
||||||
SPA_PARAM_ROUTE_description, SPA_POD_OPT_String(&pi->description),
|
SPA_PARAM_ROUTE_description, SPA_POD_OPT_String(&pi->description),
|
||||||
SPA_PARAM_ROUTE_priority, SPA_POD_OPT_Int(&pi->priority),
|
SPA_PARAM_ROUTE_priority, SPA_POD_OPT_Int(&pi->priority),
|
||||||
SPA_PARAM_ROUTE_available, SPA_POD_OPT_Id(&pi->available),
|
SPA_PARAM_ROUTE_available, SPA_POD_OPT_Id(&pi->available),
|
||||||
|
SPA_PARAM_ROUTE_info, SPA_POD_OPT_Pod(&info),
|
||||||
SPA_PARAM_ROUTE_devices, SPA_POD_OPT_Pod(&devices),
|
SPA_PARAM_ROUTE_devices, SPA_POD_OPT_Pod(&devices),
|
||||||
SPA_PARAM_ROUTE_profiles, SPA_POD_OPT_Pod(&profiles)) < 0)
|
SPA_PARAM_ROUTE_profiles, SPA_POD_OPT_Pod(&profiles)) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3015,6 +3020,32 @@ static uint32_t collect_port_info(struct pw_manager_object *card, struct device_
|
||||||
continue;
|
continue;
|
||||||
if (id == dev_info->active_port)
|
if (id == dev_info->active_port)
|
||||||
dev_info->active_port_name = pi->name;
|
dev_info->active_port_name = pi->name;
|
||||||
|
|
||||||
|
while (info != NULL) {
|
||||||
|
struct spa_pod_parser prs;
|
||||||
|
struct spa_pod_frame f[1];
|
||||||
|
int32_t n, n_items;
|
||||||
|
const char *key, *value;
|
||||||
|
|
||||||
|
spa_pod_parser_pod(&prs, info);
|
||||||
|
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
|
||||||
|
spa_pod_parser_get_int(&prs, &n_items) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (n = 0; n < n_items; n++) {
|
||||||
|
if (spa_pod_parser_get(&prs,
|
||||||
|
SPA_POD_String(&key),
|
||||||
|
SPA_POD_String(&value),
|
||||||
|
NULL) < 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(key, "port.availability-group") == 0)
|
||||||
|
pi->availability_group = value;
|
||||||
|
else if (strcmp(key, "port.type") == 0)
|
||||||
|
pi->type = port_type_value(value);
|
||||||
|
}
|
||||||
|
spa_pod_parser_pop(&prs, &f[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -3143,7 +3174,7 @@ static int fill_sink_info(struct client *client, struct message *m,
|
||||||
}
|
}
|
||||||
if (client->version >= 34) {
|
if (client->version >= 34) {
|
||||||
message_put(m,
|
message_put(m,
|
||||||
TAG_STRING, pi->available_group, /* availability_group */
|
TAG_STRING, pi->availability_group, /* availability_group */
|
||||||
TAG_U32, pi->type, /* type */
|
TAG_U32, pi->type, /* type */
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
}
|
}
|
||||||
|
|
@ -3296,7 +3327,7 @@ static int fill_source_info(struct client *client, struct message *m,
|
||||||
}
|
}
|
||||||
if (client->version >= 34) {
|
if (client->version >= 34) {
|
||||||
message_put(m,
|
message_put(m,
|
||||||
TAG_STRING, pi->available_group, /* availability_group */
|
TAG_STRING, pi->availability_group, /* availability_group */
|
||||||
TAG_U32, pi->type, /* type */
|
TAG_U32, pi->type, /* type */
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue