mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-07 13:30:09 -05:00
node: add port and node params
Add a new struct spa_param_info that lists the available params on a node/port and if they are readable/writable/updated. We can use this to replace and improve the PARAM_List and also to notify property change and updates. Update elements and code to deal with this new param stuff. Add port and node info to most elements and signal changes. Use async enum_params in -inspect and use the param info to know which ones to enumerate. Use the port info to know what parameters to update in the remote-node.
This commit is contained in:
parent
3d25adc598
commit
499dd3ff22
52 changed files with 1979 additions and 1461 deletions
|
|
@ -553,6 +553,7 @@ static void info_module(struct proxy_data *pd)
|
|||
static void info_node(struct proxy_data *pd)
|
||||
{
|
||||
struct pw_node_info *info = pd->info;
|
||||
uint32_t i;
|
||||
|
||||
info_global(pd);
|
||||
fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
|
||||
|
|
@ -566,17 +567,26 @@ static void info_node(struct proxy_data *pd)
|
|||
else
|
||||
fprintf(stdout, "\n");
|
||||
print_properties(info->props, MARK_CHANGE(4), true);
|
||||
fprintf(stdout, "%c\tenum_params\n", MARK_CHANGE(5));
|
||||
fprintf(stdout, "%c\tparams\n", MARK_CHANGE(5));
|
||||
for (i = 0; i < info->n_params; i++) {
|
||||
fprintf(stdout, "%c\t %d (%s)\n", MARK_CHANGE(5), info->params[i].id,
|
||||
spa_debug_type_find_name(spa_type_param, info->params[i].id));
|
||||
}
|
||||
info->change_mask = 0;
|
||||
}
|
||||
|
||||
static void info_port(struct proxy_data *pd)
|
||||
{
|
||||
struct pw_port_info *info = pd->info;
|
||||
uint32_t i;
|
||||
|
||||
info_global(pd);
|
||||
print_properties(info->props, MARK_CHANGE(0), true);
|
||||
fprintf(stdout, "%c\tenum_params\n", MARK_CHANGE(1));
|
||||
fprintf(stdout, "%c\tparams\n", MARK_CHANGE(1));
|
||||
for (i = 0; i < info->n_params; i++) {
|
||||
fprintf(stdout, "%c\t %d (%s)\n", MARK_CHANGE(1), info->params[i].id,
|
||||
spa_debug_type_find_name(spa_type_param, info->params[i].id));
|
||||
}
|
||||
info->change_mask = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1182,16 +1192,14 @@ static bool do_node_params(struct data *data, const char *cmd, char *args, char
|
|||
struct global *global;
|
||||
|
||||
n = pw_split_ip(args, WHITESPACE, 2, a);
|
||||
if (n < 1) {
|
||||
asprintf(error, "%s <object-id> [<param-id-name>]", cmd);
|
||||
if (n < 2) {
|
||||
asprintf(error, "%s <object-id> <param-id>", cmd);
|
||||
return false;
|
||||
}
|
||||
if (n < 2)
|
||||
param_id = SPA_PARAM_List;
|
||||
else
|
||||
param_id = atoi(a[1]);
|
||||
|
||||
id = atoi(a[0]);
|
||||
param_id = atoi(a[1]);
|
||||
|
||||
global = pw_map_lookup(&rd->globals, id);
|
||||
if (global == NULL) {
|
||||
asprintf(error, "%s: unknown global %d", cmd, id);
|
||||
|
|
@ -1221,16 +1229,14 @@ static bool do_port_params(struct data *data, const char *cmd, char *args, char
|
|||
struct global *global;
|
||||
|
||||
n = pw_split_ip(args, WHITESPACE, 2, a);
|
||||
if (n < 1) {
|
||||
asprintf(error, "%s <object-id> [<param-id-name>]", cmd);
|
||||
if (n < 2) {
|
||||
asprintf(error, "%s <object-id> <param-id>", cmd);
|
||||
return false;
|
||||
}
|
||||
if (n < 2)
|
||||
param_id = SPA_PARAM_List;
|
||||
else
|
||||
param_id = atoi(a[1]);
|
||||
|
||||
id = atoi(a[0]);
|
||||
param_id = atoi(a[1]);
|
||||
|
||||
global = pw_map_lookup(&rd->globals, id);
|
||||
if (global == NULL) {
|
||||
asprintf(error, "%s: unknown global %d", cmd, id);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@ struct proxy_data;
|
|||
|
||||
typedef void (*print_func_t) (struct proxy_data *data);
|
||||
|
||||
struct param {
|
||||
struct spa_list link;
|
||||
uint32_t id;
|
||||
struct spa_pod *param;
|
||||
};
|
||||
|
||||
struct data {
|
||||
struct pw_main_loop *loop;
|
||||
struct pw_core *core;
|
||||
|
|
@ -71,15 +77,16 @@ struct proxy_data {
|
|||
int pending_seq;
|
||||
struct spa_list pending_link;
|
||||
print_func_t print_func;
|
||||
uint32_t n_params;
|
||||
struct spa_pod **params;
|
||||
struct spa_list param_list;
|
||||
};
|
||||
|
||||
static void add_pending(struct proxy_data *pd)
|
||||
{
|
||||
struct data *d = pd->data;
|
||||
|
||||
spa_list_append(&d->pending_list, &pd->pending_link);
|
||||
if (pd->pending_seq == 0) {
|
||||
spa_list_append(&d->pending_list, &pd->pending_link);
|
||||
}
|
||||
pd->pending_seq = pw_core_proxy_sync(d->core_proxy, 0, pd->pending_seq);
|
||||
}
|
||||
|
||||
|
|
@ -107,27 +114,52 @@ static int on_core_done(void *data, uint32_t id, int seq)
|
|||
|
||||
static void clear_params(struct proxy_data *data)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < data->n_params; i++)
|
||||
free(data->params[i]);
|
||||
free(data->params);
|
||||
|
||||
data->n_params = 0;
|
||||
data->params = NULL;
|
||||
struct param *p;
|
||||
spa_list_consume(p, &data->param_list, link) {
|
||||
spa_list_remove(&p->link);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
static int add_param(struct proxy_data *data, const struct spa_pod *param)
|
||||
static void remove_params(struct proxy_data *data, uint32_t id)
|
||||
{
|
||||
uint32_t idx = data->n_params++;
|
||||
struct param *p, *t;
|
||||
spa_list_for_each_safe(p, t, &data->param_list, link) {
|
||||
if (p->id == id) {
|
||||
spa_list_remove(&p->link);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->params = realloc(data->params, sizeof(struct spa_pod *) * data->n_params);
|
||||
if (data->params == NULL)
|
||||
static int add_param(struct proxy_data *data, uint32_t id, const struct spa_pod *param)
|
||||
{
|
||||
struct param *p;
|
||||
|
||||
p = malloc(sizeof(struct param) + SPA_POD_SIZE(param));
|
||||
if (p == NULL)
|
||||
return -ENOMEM;
|
||||
data->params[idx] = spa_pod_copy(param);
|
||||
|
||||
p->id = id;
|
||||
p->param = SPA_MEMBER(p, sizeof(struct param), struct spa_pod);
|
||||
memcpy(p->param, param, SPA_POD_SIZE(param));
|
||||
spa_list_append(&data->param_list, &p->link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_params(struct proxy_data *data, char mark)
|
||||
{
|
||||
struct param *p;
|
||||
|
||||
printf("%c\tparams:\n", mark);
|
||||
spa_list_for_each(p, &data->param_list, link) {
|
||||
if (spa_pod_is_object_type(p->param, SPA_TYPE_OBJECT_Format))
|
||||
spa_debug_format(10, NULL, p->param);
|
||||
else
|
||||
spa_debug_pod(10, NULL, p->param);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_properties(const struct spa_dict *props, char mark)
|
||||
{
|
||||
const struct spa_dict_item *item;
|
||||
|
|
@ -226,16 +258,8 @@ static void print_node(struct proxy_data *data)
|
|||
printf("\ttype: %s (version %d)\n",
|
||||
spa_debug_type_find_name(pw_type_info(), data->type), data->version);
|
||||
if (print_all) {
|
||||
uint32_t i;
|
||||
|
||||
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
|
||||
printf("%c\tparams:\n", MARK_CHANGE(5));
|
||||
for (i = 0; i < data->n_params; i++) {
|
||||
if (spa_pod_is_object_type(data->params[i], SPA_TYPE_OBJECT_Format))
|
||||
spa_debug_format(10, NULL, data->params[i]);
|
||||
else
|
||||
spa_debug_pod(10, NULL, data->params[i]);
|
||||
}
|
||||
print_params(data, MARK_CHANGE(5));
|
||||
printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(1),
|
||||
info->n_input_ports, info->max_input_ports);
|
||||
printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(2),
|
||||
|
|
@ -254,15 +278,23 @@ static void print_node(struct proxy_data *data)
|
|||
static int node_event_info(void *object, const struct pw_node_info *info)
|
||||
{
|
||||
struct proxy_data *data = object;
|
||||
bool is_new = data->info == NULL;
|
||||
struct pw_node_info *old = data->info;
|
||||
uint32_t i;
|
||||
|
||||
data->info = pw_node_info_update(data->info, info);
|
||||
|
||||
if (is_new) {
|
||||
pw_node_proxy_enum_params((struct pw_node_proxy*)data->proxy,
|
||||
0, SPA_PARAM_List, 0, 0, NULL);
|
||||
if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS) {
|
||||
for (i = 0; i < info->n_params; i++) {
|
||||
if (old != NULL && info->params[i].flags == old->params[i].flags)
|
||||
continue;
|
||||
remove_params(data, info->params[i].id);
|
||||
if (!SPA_FLAG_CHECK(info->params[i].flags, SPA_PARAM_INFO_READ))
|
||||
continue;
|
||||
pw_node_proxy_enum_params((struct pw_node_proxy*)data->proxy,
|
||||
0, info->params[i].id, 0, 0, NULL);
|
||||
}
|
||||
add_pending(data);
|
||||
}
|
||||
data->info = pw_node_info_update(data->info, info);
|
||||
|
||||
if (data->pending_seq == 0)
|
||||
data->print_func(data);
|
||||
return 0;
|
||||
|
|
@ -272,7 +304,7 @@ static int node_event_param(void *object, int seq, uint32_t id,
|
|||
uint32_t index, uint32_t next, const struct spa_pod *param)
|
||||
{
|
||||
struct proxy_data *data = object;
|
||||
return add_param(data, param);
|
||||
return add_param(data, id, param);
|
||||
}
|
||||
|
||||
static const struct pw_node_proxy_events node_events = {
|
||||
|
|
@ -305,16 +337,9 @@ static void print_port(struct proxy_data *data)
|
|||
printf("\ttype: %s (version %d)\n",
|
||||
spa_debug_type_find_name(pw_type_info(), data->type), data->version);
|
||||
if (print_all) {
|
||||
uint32_t i;
|
||||
printf(" \tdirection: \"%s\"\n", pw_direction_as_string(info->direction));
|
||||
printf("%c\tparams:\n", MARK_CHANGE(2));
|
||||
for (i = 0; i < data->n_params; i++) {
|
||||
if (spa_pod_is_object_type(data->params[i], SPA_TYPE_OBJECT_Format))
|
||||
spa_debug_format(12, NULL, data->params[i]);
|
||||
else
|
||||
spa_debug_pod(12, NULL, data->params[i]);
|
||||
}
|
||||
print_properties(info->props, MARK_CHANGE(1));
|
||||
print_params(data, MARK_CHANGE(1));
|
||||
print_properties(info->props, MARK_CHANGE(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,15 +347,23 @@ static int port_event_info(void *object, const struct pw_port_info *info)
|
|||
{
|
||||
|
||||
struct proxy_data *data = object;
|
||||
bool is_new = data->info == NULL;
|
||||
struct pw_port_info *old = data->info;
|
||||
uint32_t i;
|
||||
|
||||
data->info = pw_port_info_update(data->info, info);
|
||||
|
||||
if (is_new) {
|
||||
pw_port_proxy_enum_params((struct pw_port_proxy*)data->proxy,
|
||||
0, SPA_PARAM_EnumFormat, 0, 0, NULL);
|
||||
if (info->change_mask & PW_PORT_CHANGE_MASK_PARAMS) {
|
||||
for (i = 0; i < info->n_params; i++) {
|
||||
if (old != NULL && info->params[i].flags == old->params[i].flags)
|
||||
continue;
|
||||
remove_params(data, info->params[i].id);
|
||||
if (!SPA_FLAG_CHECK(info->params[i].flags, SPA_PARAM_INFO_READ))
|
||||
continue;
|
||||
pw_port_proxy_enum_params((struct pw_port_proxy*)data->proxy,
|
||||
0, info->params[i].id, 0, 0, NULL);
|
||||
}
|
||||
add_pending(data);
|
||||
}
|
||||
data->info = pw_port_info_update(data->info, info);
|
||||
|
||||
if (data->pending_seq == 0)
|
||||
data->print_func(data);
|
||||
return 0;
|
||||
|
|
@ -340,7 +373,7 @@ static int port_event_param(void *object, int seq, uint32_t id,
|
|||
uint32_t index, uint32_t next, const struct spa_pod *param)
|
||||
{
|
||||
struct proxy_data *data = object;
|
||||
return add_param(data, param);
|
||||
return add_param(data, id, param);
|
||||
}
|
||||
|
||||
static const struct pw_port_proxy_events port_events = {
|
||||
|
|
@ -606,6 +639,7 @@ static int registry_event_global(void *data, uint32_t id, uint32_t parent_id,
|
|||
pd->destroy = destroy;
|
||||
pd->pending_seq = 0;
|
||||
pd->print_func = print_func;
|
||||
spa_list_init(&pd->param_list);
|
||||
pw_proxy_add_proxy_listener(proxy, &pd->proxy_proxy_listener, events, pd);
|
||||
pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue