mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
node: make port for_each more powerful
Make an int return from pw_node_for_each_port() so that we can return errors or early exit. Add pw_port_for_each_param() to iterate params. And use this to collect the formats.
This commit is contained in:
parent
425073afd8
commit
91a3670610
6 changed files with 81 additions and 47 deletions
|
|
@ -234,10 +234,10 @@ static void node_port_removed(void *data, struct pw_port *port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool on_node_port_added(void *data, struct pw_port *port)
|
static int on_node_port_added(void *data, struct pw_port *port)
|
||||||
{
|
{
|
||||||
node_port_added(data, port);
|
node_port_added(data, port);
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_node_created(struct pw_node *node, struct node_info *info)
|
static void on_node_created(struct pw_node *node, struct node_info *info)
|
||||||
|
|
|
||||||
|
|
@ -1067,16 +1067,16 @@ struct find_data {
|
||||||
struct pw_jack_port *result;
|
struct pw_jack_port *result;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool find_port(void *data, struct pw_port *port)
|
static int find_port(void *data, struct pw_port *port)
|
||||||
{
|
{
|
||||||
struct find_data *d = data;
|
struct find_data *d = data;
|
||||||
struct port_data *pd = pw_port_get_user_data(port);
|
struct port_data *pd = pw_port_get_user_data(port);
|
||||||
|
|
||||||
if (pd->port.port_id == d->port_id) {
|
if (pd->port.port_id == d->port_id) {
|
||||||
d->result = &pd->port;
|
d->result = &pd->port;
|
||||||
return false;
|
return 1;
|
||||||
}
|
}
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pw_jack_port *
|
struct pw_jack_port *
|
||||||
|
|
@ -1085,7 +1085,7 @@ pw_jack_node_find_port(struct pw_jack_node *node,
|
||||||
jack_port_id_t port_id)
|
jack_port_id_t port_id)
|
||||||
{
|
{
|
||||||
struct find_data data = { port_id, };
|
struct find_data data = { port_id, };
|
||||||
if (!pw_node_for_each_port(node->node, direction, find_port, &data))
|
if (pw_node_for_each_port(node->node, direction, find_port, &data) == 1)
|
||||||
return data.result;
|
return data.result;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,49 +219,43 @@ static int update_port_ids(struct pw_node *node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int collect_params(struct pw_port *port, uint32_t param_id, struct spa_pod ***result)
|
struct param_array {
|
||||||
|
struct spa_pod **params;
|
||||||
|
uint32_t n_params;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int add_param(void *data, struct spa_pod *param)
|
||||||
{
|
{
|
||||||
int res;
|
struct param_array *arr = data;
|
||||||
uint8_t buffer[4096];
|
uint32_t idx = arr->n_params++;
|
||||||
struct spa_pod_builder b = { 0 };
|
|
||||||
uint32_t state = 0;
|
|
||||||
|
|
||||||
for (res = 0;; res++) {
|
arr->params = realloc(arr->params, sizeof(struct spa_pod *) * arr->n_params);
|
||||||
struct spa_pod *fmt;
|
arr->params[idx] = pw_spa_pod_copy(param);
|
||||||
|
return 0;
|
||||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
|
||||||
if (spa_node_port_enum_params(port->node->node,
|
|
||||||
port->direction, port->port_id,
|
|
||||||
param_id, &state,
|
|
||||||
NULL, &fmt, &b) <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*result = realloc(*result, sizeof(struct spa_pod *) * (res + 1));
|
|
||||||
(*result)[res] = pw_spa_pod_copy(fmt);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_info(struct pw_node *this)
|
update_info(struct pw_node *this)
|
||||||
{
|
{
|
||||||
struct pw_type *t = &this->core->type;
|
struct pw_type *t = &this->core->type;
|
||||||
|
struct param_array params;
|
||||||
|
struct pw_port *port;
|
||||||
|
|
||||||
this->info.input_params = NULL;
|
params = (struct param_array) { NULL };
|
||||||
if (!spa_list_is_empty(&this->input_ports)) {
|
if (!spa_list_is_empty(&this->input_ports)) {
|
||||||
struct pw_port *port = spa_list_first(&this->input_ports, struct pw_port, link);
|
port = spa_list_first(&this->input_ports, struct pw_port, link);
|
||||||
this->info.n_input_params = collect_params(port,
|
pw_port_for_each_param(port, t->param.idEnumFormat, NULL, add_param, ¶ms);
|
||||||
t->param.idEnumFormat,
|
|
||||||
&this->info.input_params);
|
|
||||||
}
|
}
|
||||||
|
this->info.input_params = params.params;
|
||||||
|
this->info.n_input_params = params.n_params;
|
||||||
|
|
||||||
this->info.output_params = NULL;
|
params = (struct param_array) { NULL };
|
||||||
if (!spa_list_is_empty(&this->output_ports)) {
|
if (!spa_list_is_empty(&this->output_ports)) {
|
||||||
struct pw_port *port = spa_list_first(&this->output_ports, struct pw_port, link);
|
port = spa_list_first(&this->output_ports, struct pw_port, link);
|
||||||
this->info.n_output_params = collect_params(port,
|
pw_port_for_each_param(port, t->param.idEnumFormat, NULL, add_param, ¶ms);
|
||||||
t->param.idEnumFormat,
|
|
||||||
&this->info.output_params);
|
|
||||||
}
|
}
|
||||||
|
this->info.output_params = params.params;
|
||||||
|
this->info.n_output_params = params.n_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -614,13 +608,14 @@ void pw_node_destroy(struct pw_node *node)
|
||||||
free(impl);
|
free(impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pw_node_for_each_port(struct pw_node *node,
|
int pw_node_for_each_port(struct pw_node *node,
|
||||||
enum pw_direction direction,
|
enum pw_direction direction,
|
||||||
bool (*callback) (void *data, struct pw_port *port),
|
int (*callback) (void *data, struct pw_port *port),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct spa_list *ports;
|
struct spa_list *ports;
|
||||||
struct pw_port *p, *t;
|
struct pw_port *p, *t;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (direction == PW_DIRECTION_INPUT)
|
if (direction == PW_DIRECTION_INPUT)
|
||||||
ports = &node->input_ports;
|
ports = &node->input_ports;
|
||||||
|
|
@ -628,9 +623,9 @@ bool pw_node_for_each_port(struct pw_node *node,
|
||||||
ports = &node->output_ports;
|
ports = &node->output_ports;
|
||||||
|
|
||||||
spa_list_for_each_safe(p, t, ports, link)
|
spa_list_for_each_safe(p, t, ports, link)
|
||||||
if (!callback(data, p))
|
if ((res = callback(data, p)) != 0)
|
||||||
return false;
|
return res;
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pw_port *
|
struct pw_port *
|
||||||
|
|
|
||||||
|
|
@ -138,11 +138,14 @@ void pw_node_add_listener(struct pw_node *node,
|
||||||
const struct pw_node_events *events,
|
const struct pw_node_events *events,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
/** iterate the ports in the given direction */
|
/** Iterate the ports in the given direction. The callback should return
|
||||||
bool pw_node_for_each_port(struct pw_node *node,
|
* 0 to fetch the next item, any other value stops the iteration and returns
|
||||||
enum pw_direction direction,
|
* the value. When all callbacks return 0, this function returns 0 when all
|
||||||
bool (*callback) (void *data, struct pw_port *port),
|
* items are iterated. */
|
||||||
void *data);
|
int pw_node_for_each_port(struct pw_node *node,
|
||||||
|
enum pw_direction direction,
|
||||||
|
int (*callback) (void *data, struct pw_port *port),
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
|
||||||
/** Find the port with direction and port_id or NULL when not found */
|
/** Find the port with direction and port_id or NULL when not found */
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,33 @@ int pw_port_pause(struct pw_port *port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pw_port_for_each_param(struct pw_port *port,
|
||||||
|
uint32_t param_id,
|
||||||
|
const struct spa_pod *filter,
|
||||||
|
int (*callback) (void *data, struct spa_pod *param),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
uint8_t buffer[4096];
|
||||||
|
struct spa_pod_builder b = { 0 };
|
||||||
|
uint32_t state;
|
||||||
|
struct spa_pod *param;
|
||||||
|
|
||||||
|
for (state = 0;;) {
|
||||||
|
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||||
|
if ((res = spa_node_port_enum_params(port->node->node,
|
||||||
|
port->direction,
|
||||||
|
port->port_id,
|
||||||
|
param_id, &state,
|
||||||
|
filter, ¶m, &b)) <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((res = callback(data, param)) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
|
int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
|
||||||
const struct spa_pod *param)
|
const struct spa_pod *param)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -429,6 +429,15 @@ bool pw_port_add(struct pw_port *port, struct pw_node *node);
|
||||||
/** Destroy a port \memberof pw_port */
|
/** Destroy a port \memberof pw_port */
|
||||||
void pw_port_destroy(struct pw_port *port);
|
void pw_port_destroy(struct pw_port *port);
|
||||||
|
|
||||||
|
/** Iterate the params of the given port. The callback should return
|
||||||
|
* 1 to fetch the next item, 0 to stop iteration or <0 on error.
|
||||||
|
* The function returns 0 on success or the error returned by the callback. */
|
||||||
|
int pw_port_for_each_param(struct pw_port *port,
|
||||||
|
uint32_t param_id,
|
||||||
|
const struct spa_pod *filter,
|
||||||
|
int (*callback) (void *data, struct spa_pod *param),
|
||||||
|
void *data);
|
||||||
|
|
||||||
/** Set a param on a port \memberof pw_port */
|
/** Set a param on a port \memberof pw_port */
|
||||||
int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
|
int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
|
||||||
const struct spa_pod *param);
|
const struct spa_pod *param);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue