mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-14 06:59:57 -05:00
node: make add_listener method
Make struct spa_node_events for events emited from the main thread and keep the spa_node_callbacks for the data thread callbacks. The add_listener method installs the events and it's possible to install multiple handles. Adding a listener first emits the info and port_info events when installed, similar to how the PipeWire proxy bind works. This removes the need for the spa_pending_queue and makes it easier to implement the _sync versions. Add some helpers to make it easier for plugins to emit all the info to new listeners. Use the listeners for devices as well.
This commit is contained in:
parent
61ce4e77f6
commit
0390969228
53 changed files with 1774 additions and 1307 deletions
|
|
@ -74,8 +74,7 @@ struct data {
|
|||
struct spa_hook remote_listener;
|
||||
|
||||
struct spa_node impl_node;
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
struct spa_hook_list hooks;
|
||||
struct spa_io_buffers *io;
|
||||
struct spa_io_sequence *io_notify;
|
||||
uint32_t io_notify_size;
|
||||
|
|
@ -132,32 +131,40 @@ static int impl_send_command(struct spa_node *node, const struct spa_command *co
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int impl_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[5];
|
||||
struct spa_hook_list save;
|
||||
|
||||
spa_hook_list_isolate(&d->hooks, &save, listener, events, data);
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
info.params = params;
|
||||
info.n_params = 5;
|
||||
|
||||
spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_INPUT, 0, &info);
|
||||
|
||||
spa_hook_list_join(&d->hooks, &save);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_set_callbacks(struct spa_node *node,
|
||||
const struct spa_node_callbacks *callbacks, void *data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
d->callbacks = callbacks;
|
||||
d->callbacks_data = data;
|
||||
|
||||
if (d->callbacks && d->callbacks->port_info) {
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[5];
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
info.params = params;
|
||||
info.n_params = 5;
|
||||
|
||||
d->callbacks->port_info(d->callbacks_data, SPA_DIRECTION_INPUT, 0, &info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +205,6 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
uint8_t buffer[1024];
|
||||
struct spa_result_node_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
result.id = id;
|
||||
result.next = start;
|
||||
|
|
@ -282,8 +288,7 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
goto next;
|
||||
|
||||
if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&d->hooks, seq, 0, &result);
|
||||
|
||||
if (++count != num)
|
||||
goto next;
|
||||
|
|
@ -437,6 +442,7 @@ static int impl_node_process(struct spa_node *node)
|
|||
|
||||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
.add_listener = impl_add_listener,
|
||||
.set_callbacks = impl_set_callbacks,
|
||||
.set_io = impl_set_io,
|
||||
.send_command = impl_send_command,
|
||||
|
|
@ -513,6 +519,8 @@ int main(int argc, char *argv[])
|
|||
data.remote = pw_remote_new(data.core, NULL, 0);
|
||||
data.path = argc > 1 ? argv[1] : NULL;
|
||||
|
||||
spa_hook_list_init(&data.hooks);
|
||||
|
||||
reset_props(&data.props);
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ struct data {
|
|||
struct spa_hook remote_listener;
|
||||
|
||||
struct spa_node impl_node;
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
struct spa_hook_list hooks;
|
||||
struct spa_io_buffers *io;
|
||||
struct spa_io_control *io_notify;
|
||||
uint32_t io_notify_size;
|
||||
|
|
@ -101,35 +100,43 @@ static int impl_send_command(struct spa_node *node, const struct spa_command *co
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int impl_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_port_info info;
|
||||
struct spa_dict_item items[1];
|
||||
struct spa_param_info params[5];
|
||||
struct spa_hook_list save;
|
||||
|
||||
spa_hook_list_isolate(&d->hooks, &save, listener, events, data);
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||
items[0] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
info.props = &SPA_DICT_INIT_ARRAY(items);
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
info.params = params;
|
||||
info.n_params = 5;
|
||||
|
||||
spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_OUTPUT, 0, &info);
|
||||
|
||||
spa_hook_list_join(&d->hooks, &save);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_set_callbacks(struct spa_node *node,
|
||||
const struct spa_node_callbacks *callbacks, void *data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
d->callbacks = callbacks;
|
||||
d->callbacks_data = data;
|
||||
|
||||
if (d->callbacks && d->callbacks->port_info) {
|
||||
struct spa_port_info info;
|
||||
struct spa_dict_item items[1];
|
||||
struct spa_param_info params[5];
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||
items[0] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
info.props = &SPA_DICT_INIT_ARRAY(items);
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
info.params = params;
|
||||
info.n_params = 5;
|
||||
|
||||
d->callbacks->port_info(d->callbacks_data, SPA_DIRECTION_OUTPUT, 0, &info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +176,6 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
uint8_t buffer[1024];
|
||||
struct spa_result_node_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
result.id = id;
|
||||
result.next = start;
|
||||
|
|
@ -255,8 +261,7 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
goto next;
|
||||
|
||||
if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&d->hooks, seq, 0, &result);
|
||||
|
||||
if (++count != num)
|
||||
goto next;
|
||||
|
|
@ -444,6 +449,7 @@ static int impl_node_process(struct spa_node *node)
|
|||
|
||||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
.add_listener = impl_add_listener,
|
||||
.set_callbacks = impl_set_callbacks,
|
||||
.set_io = impl_set_io,
|
||||
.send_command = impl_send_command,
|
||||
|
|
@ -510,6 +516,7 @@ int main(int argc, char *argv[])
|
|||
data.path = argc > 1 ? argv[1] : NULL;
|
||||
|
||||
spa_list_init(&data.empty);
|
||||
spa_hook_list_init(&data.hooks);
|
||||
|
||||
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ struct data {
|
|||
struct spa_node impl_node;
|
||||
struct spa_io_buffers *io;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
struct spa_hook_list hooks;
|
||||
|
||||
struct spa_video_info_raw format;
|
||||
int32_t stride;
|
||||
|
|
@ -90,22 +89,31 @@ static int impl_send_command(struct spa_node *node, const struct spa_command *co
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int impl_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_port_info info;
|
||||
struct spa_hook_list save;
|
||||
|
||||
spa_hook_list_isolate(&d->hooks, &save, listener, events, data);
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
|
||||
spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_INPUT, 0, &info);
|
||||
|
||||
spa_hook_list_join(&d->hooks, &save);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_set_callbacks(struct spa_node *node,
|
||||
const struct spa_node_callbacks *callbacks, void *data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
d->callbacks = callbacks;
|
||||
d->callbacks_data = data;
|
||||
|
||||
if (d->callbacks && d->callbacks->port_info) {
|
||||
struct spa_port_info info;
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
|
||||
d->callbacks->port_info(d->callbacks_data, SPA_DIRECTION_INPUT, 0, &info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +141,6 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
uint8_t buffer[1024];
|
||||
struct spa_result_node_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
result.id = id;
|
||||
result.next = start;
|
||||
|
|
@ -184,8 +191,7 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
goto next;
|
||||
|
||||
if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&d->hooks, seq, 0, &result);
|
||||
|
||||
if (++count != num)
|
||||
goto next;
|
||||
|
|
@ -315,9 +321,10 @@ static int impl_node_process(struct spa_node *node)
|
|||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
NULL,
|
||||
.add_listener = impl_add_listener,
|
||||
.set_callbacks = impl_set_callbacks,
|
||||
.set_io = impl_set_io,
|
||||
.send_command = impl_send_command,
|
||||
.set_callbacks = impl_set_callbacks,
|
||||
.port_set_io = impl_port_set_io,
|
||||
.port_enum_params = impl_port_enum_params,
|
||||
.port_set_param = impl_port_set_param,
|
||||
|
|
@ -367,6 +374,8 @@ int main(int argc, char *argv[])
|
|||
data.loop = pw_main_loop_new(NULL);
|
||||
data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0);
|
||||
|
||||
spa_hook_list_init(&data.hooks);
|
||||
|
||||
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL, NULL, NULL);
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ struct port {
|
|||
struct spa_io_buffers *io;
|
||||
struct spa_io_range *range;
|
||||
|
||||
uint64_t info_all;
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
|
|
@ -95,11 +96,11 @@ struct impl {
|
|||
|
||||
struct spa_log *log;
|
||||
|
||||
uint64_t info_all;
|
||||
struct spa_node_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *user_data;
|
||||
struct spa_hook_list hooks;
|
||||
|
||||
uint32_t port_count;
|
||||
uint32_t last_port;
|
||||
|
|
@ -163,43 +164,58 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void emit_node_info(struct impl *this)
|
||||
static void emit_node_info(struct impl *this, bool full)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info && this->info.change_mask) {
|
||||
this->callbacks->info(this->user_data, &this->info);
|
||||
if (full)
|
||||
this->info.change_mask = this->info_all;
|
||||
if (this->info.change_mask) {
|
||||
spa_node_emit_info(&this->hooks, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_port_info(struct impl *this, struct port *port)
|
||||
static void emit_port_info(struct impl *this, struct port *port, bool full)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->port_info && port->info.change_mask) {
|
||||
this->callbacks->port_info(this->user_data, port->direction, port->id, &port->info);
|
||||
if (full)
|
||||
port->info.change_mask = port->info_all;
|
||||
if (port->info.change_mask) {
|
||||
spa_node_emit_port_info(&this->hooks,
|
||||
port->direction, port->id, &port->info);
|
||||
port->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int impl_node_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct impl *this;
|
||||
struct spa_hook_list save;
|
||||
uint32_t i;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
|
||||
|
||||
emit_node_info(this, true);
|
||||
emit_port_info(this, GET_OUT_PORT(this, 0), true);
|
||||
for (i = 0; i < this->last_port; i++) {
|
||||
if (this->in_ports[i].valid)
|
||||
emit_port_info(this, GET_IN_PORT(this, i), true);
|
||||
}
|
||||
|
||||
spa_hook_list_join(&this->hooks, &save);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_set_callbacks(struct spa_node *node,
|
||||
const struct spa_node_callbacks *callbacks,
|
||||
void *user_data)
|
||||
{
|
||||
struct impl *this;
|
||||
uint32_t i;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
this->callbacks = callbacks;
|
||||
this->user_data = user_data;
|
||||
|
||||
emit_node_info(this);
|
||||
emit_port_info(this, GET_OUT_PORT(this, 0));
|
||||
for (i = 0; i < this->last_port; i++) {
|
||||
if (this->in_ports[i].valid)
|
||||
emit_port_info(this, GET_IN_PORT(this, i));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -222,13 +238,13 @@ static int impl_node_add_port(struct spa_node *node, enum spa_direction directio
|
|||
port_props_reset(&port->props);
|
||||
|
||||
spa_list_init(&port->queue);
|
||||
port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
|
||||
SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS |
|
||||
SPA_PORT_FLAG_REMOVABLE |
|
||||
SPA_PORT_FLAG_OPTIONAL |
|
||||
SPA_PORT_FLAG_IN_PLACE;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
port->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
port->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
port->params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
|
|
@ -243,7 +259,7 @@ static int impl_node_add_port(struct spa_node *node, enum spa_direction directio
|
|||
port->valid = true;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: add port %d %d", this, port_id, this->last_port);
|
||||
emit_port_info(this, port);
|
||||
emit_port_info(this, port, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -281,8 +297,7 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
|
|||
}
|
||||
spa_log_info(this->log, NAME " %p: remove port %d %d", this, port_id, this->last_port);
|
||||
|
||||
if (this->callbacks && this->callbacks->port_info)
|
||||
this->callbacks->port_info(this->user_data, direction, port_id, NULL);
|
||||
spa_node_emit_port_info(&this->hooks, direction, port_id, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -335,7 +350,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -425,8 +439,7 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
goto next;
|
||||
|
||||
if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&this->hooks, seq, 0, &result);
|
||||
|
||||
if (++count != num)
|
||||
goto next;
|
||||
|
|
@ -521,16 +534,15 @@ static int port_set_format(struct spa_node *node,
|
|||
this, direction, port_id);
|
||||
}
|
||||
}
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
if (port->have_format) {
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
} else {
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
}
|
||||
emit_port_info(this, port);
|
||||
emit_port_info(this, port, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -830,11 +842,12 @@ static int impl_node_process(struct spa_node *node)
|
|||
|
||||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
.add_listener = impl_node_add_listener,
|
||||
.set_callbacks = impl_node_set_callbacks,
|
||||
.enum_params = impl_node_enum_params,
|
||||
.set_param = impl_node_set_param,
|
||||
.set_io = impl_node_set_io,
|
||||
.send_command = impl_node_send_command,
|
||||
.set_callbacks = impl_node_set_callbacks,
|
||||
.add_port = impl_node_add_port,
|
||||
.remove_port = impl_node_remove_port,
|
||||
.port_enum_params = impl_node_port_enum_params,
|
||||
|
|
@ -899,6 +912,8 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this->log = support[i].data;
|
||||
}
|
||||
|
||||
spa_hook_list_init(&this->hooks);
|
||||
|
||||
this->node = impl_node;
|
||||
this->info = SPA_NODE_INFO_INIT();
|
||||
this->info.max_input_ports = MAX_PORTS;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ struct node {
|
|||
struct spa_log *log;
|
||||
struct spa_loop *data_loop;
|
||||
|
||||
struct spa_hook_list hooks;
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
struct io ios[MAX_IO];
|
||||
|
|
@ -363,13 +364,11 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
struct spa_pod_builder b = { 0 };
|
||||
struct spa_result_node_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
|
||||
|
||||
result.id = id;
|
||||
result.next = start;
|
||||
|
|
@ -391,8 +390,7 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
continue;
|
||||
|
||||
pw_log_debug("client-node %p: %d param %u", this, seq, result.index);
|
||||
if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&this->hooks, seq, 0, &result);
|
||||
|
||||
if (++count == num)
|
||||
break;
|
||||
|
|
@ -481,27 +479,24 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
static void emit_port_info(struct node *this, struct port *port)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->port_info)
|
||||
this->callbacks->port_info(this->callbacks_data,
|
||||
spa_node_emit_port_info(&this->hooks,
|
||||
port->direction, port->id, &port->info);
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_set_callbacks(struct spa_node *node,
|
||||
const struct spa_node_callbacks *callbacks,
|
||||
void *data)
|
||||
static int impl_node_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct node *this;
|
||||
struct spa_hook_list save;
|
||||
uint32_t i;
|
||||
int res = 0;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
this->callbacks = callbacks;
|
||||
this->callbacks_data = data;
|
||||
|
||||
pw_log_debug("client-node %p: callbacks %p", this, callbacks);
|
||||
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
|
||||
|
||||
for (i = 0; i < MAX_INPUTS; i++) {
|
||||
if (this->in_ports[i])
|
||||
|
|
@ -511,12 +506,30 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
if (this->out_ports[i])
|
||||
emit_port_info(this, this->out_ports[i]);
|
||||
}
|
||||
if (callbacks && this->resource)
|
||||
if (this->resource)
|
||||
res = pw_resource_sync(this->resource, 0);
|
||||
|
||||
spa_hook_list_join(&this->hooks, &save);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_set_callbacks(struct spa_node *node,
|
||||
const struct spa_node_callbacks *callbacks,
|
||||
void *data)
|
||||
{
|
||||
struct node *this;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
this->callbacks = callbacks;
|
||||
this->callbacks_data = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_sync(struct spa_node *node, int seq)
|
||||
{
|
||||
|
|
@ -561,6 +574,8 @@ do_update_port(struct node *this,
|
|||
pw_properties_free(port->properties);
|
||||
port->properties = NULL;
|
||||
port->info.props = NULL;
|
||||
port->info.n_params = 0;
|
||||
port->info.params = NULL;
|
||||
|
||||
if (info) {
|
||||
port->info = *info;
|
||||
|
|
@ -603,8 +618,7 @@ clear_port(struct node *this, struct port *port)
|
|||
this->n_outputs--;
|
||||
}
|
||||
}
|
||||
if (this->callbacks && this->callbacks->port_info)
|
||||
this->callbacks->port_info(this->callbacks_data, port->direction, port->id, NULL);
|
||||
spa_node_emit_port_info(&this->hooks, port->direction, port->id, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -646,13 +660,11 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
struct spa_pod_builder b = { 0 };
|
||||
struct spa_result_node_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -681,8 +693,7 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
continue;
|
||||
|
||||
pw_log_debug("client-node %p: %d param %u", this, seq, result.index);
|
||||
if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&this->hooks, seq, 0, &result);
|
||||
|
||||
if (++count == num)
|
||||
break;
|
||||
|
|
@ -1056,9 +1067,8 @@ client_node_port_update(void *data,
|
|||
n_params, params,
|
||||
info);
|
||||
|
||||
if (this->callbacks && this->callbacks->port_info &&
|
||||
info && (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO))
|
||||
this->callbacks->port_info(this->callbacks_data, direction, port_id, info);
|
||||
if (info && (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO))
|
||||
spa_node_emit_port_info(&this->hooks, direction, port_id, info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1073,8 +1083,7 @@ static int client_node_event(void *data, struct spa_event *event)
|
|||
{
|
||||
struct impl *impl = data;
|
||||
struct node *this = &impl->node;
|
||||
if (this->callbacks && this->callbacks->event)
|
||||
this->callbacks->event(this->callbacks_data, event);
|
||||
spa_node_emit_event(&this->hooks, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1110,6 +1119,7 @@ static void node_on_data_fd_events(struct spa_source *source)
|
|||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
NULL,
|
||||
.add_listener = impl_node_add_listener,
|
||||
.set_callbacks = impl_node_set_callbacks,
|
||||
.sync = impl_node_sync,
|
||||
.enum_params = impl_node_enum_params,
|
||||
|
|
@ -1153,6 +1163,7 @@ node_init(struct node *this,
|
|||
}
|
||||
|
||||
this->node = impl_node;
|
||||
spa_hook_list_init(&this->hooks);
|
||||
spa_list_init(&this->pending_list);
|
||||
|
||||
init_ios(this->ios);
|
||||
|
|
@ -1222,7 +1233,7 @@ static void client_node_resource_error(void *data, int seq, int res, const char
|
|||
|
||||
pw_log_error("client-node %p: error seq:%d %d (%s)", this, seq, res, message);
|
||||
result.message = message;
|
||||
this->callbacks->result(this->callbacks_data, seq, res, &result);
|
||||
spa_node_emit_result(&this->hooks, seq, res, &result);
|
||||
}
|
||||
|
||||
static void client_node_resource_done(void *data, int seq)
|
||||
|
|
@ -1231,7 +1242,7 @@ static void client_node_resource_done(void *data, int seq)
|
|||
struct node *this = &impl->node;
|
||||
|
||||
pw_log_debug("client-node %p: emit result %d", this, seq);
|
||||
this->callbacks->result(this->callbacks_data, seq, 0, NULL);
|
||||
spa_node_emit_result(&this->hooks, seq, 0, NULL);
|
||||
}
|
||||
|
||||
void pw_client_node_registered(struct pw_client_node *this, uint32_t node_id)
|
||||
|
|
|
|||
|
|
@ -67,8 +67,7 @@ struct node {
|
|||
|
||||
struct spa_log *log;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
struct spa_hook_list hooks;
|
||||
};
|
||||
|
||||
struct impl {
|
||||
|
|
@ -87,6 +86,7 @@ struct impl {
|
|||
|
||||
struct spa_node *cnode;
|
||||
struct spa_node *adapter;
|
||||
struct spa_hook adapter_listener;
|
||||
struct spa_node *adapter_mix;
|
||||
uint32_t adapter_mix_flags;
|
||||
uint32_t adapter_mix_port;
|
||||
|
|
@ -103,8 +103,6 @@ struct impl {
|
|||
struct spa_buffer **buffers;
|
||||
uint32_t n_buffers;
|
||||
struct pw_memblock *mem;
|
||||
|
||||
struct spa_pending client_node_pending;
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
|
|
@ -126,7 +124,6 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
|
||||
impl = this->impl;
|
||||
|
||||
result.id = id;
|
||||
|
|
@ -142,8 +139,7 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
return 0;
|
||||
|
||||
if ((res = spa_node_enum_params_sync(impl->adapter,
|
||||
id, &start, filter, ¶m, &b,
|
||||
impl->this.node->pending)) != 1)
|
||||
id, &start, filter, ¶m, &b)) != 1)
|
||||
return res;
|
||||
break;
|
||||
|
||||
|
|
@ -151,8 +147,7 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
case SPA_PARAM_Format:
|
||||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
id, &start, filter, ¶m, &b,
|
||||
impl->client_node->node->pending)) != 1)
|
||||
id, &start, filter, ¶m, &b)) != 1)
|
||||
return res;
|
||||
break;
|
||||
|
||||
|
|
@ -163,8 +158,7 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
goto next;
|
||||
|
||||
if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&this->hooks, seq, 0, &result);
|
||||
|
||||
if (++count != num)
|
||||
goto next;
|
||||
|
|
@ -221,7 +215,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
if (impl->started)
|
||||
return -EIO;
|
||||
pw_log_debug("set profile %d", id);
|
||||
if (impl->adapter != impl->cnode) {
|
||||
if (impl->adapter && impl->adapter != impl->cnode) {
|
||||
if ((res = spa_node_set_param(impl->adapter, id, flags, param)) < 0)
|
||||
return res;
|
||||
|
||||
|
|
@ -229,7 +223,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
}
|
||||
break;
|
||||
case SPA_PARAM_Props:
|
||||
if (impl->adapter != impl->cnode) {
|
||||
if (impl->adapter && impl->adapter != impl->cnode) {
|
||||
if ((res = spa_node_set_param(impl->adapter, id, flags, param)) < 0)
|
||||
return res;
|
||||
}
|
||||
|
|
@ -292,44 +286,73 @@ static int adapter_port_info(void *data,
|
|||
struct impl *impl = data;
|
||||
struct node *this = &impl->node;
|
||||
|
||||
if (this->callbacks && this->callbacks->port_info) {
|
||||
if (direction == impl->direction) {
|
||||
this->callbacks->port_info(this->callbacks_data, direction, port_id, info);
|
||||
}
|
||||
}
|
||||
if (direction == impl->direction)
|
||||
spa_node_emit_port_info(&this->hooks, direction, port_id, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int adapter_result(void *data, int seq, int res, const void *result)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct node *this = &impl->node;
|
||||
return this->callbacks->result(this->callbacks_data, seq, res, result);
|
||||
pw_log_debug("%p: result %d %d", this, seq, res);
|
||||
spa_node_emit_result(&this->hooks, seq, res, result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_node_callbacks adapter_node_callbacks = {
|
||||
SPA_VERSION_NODE_CALLBACKS,
|
||||
static const struct spa_node_events adapter_node_events = {
|
||||
SPA_VERSION_NODE_EVENTS,
|
||||
.port_info = adapter_port_info,
|
||||
.result = adapter_result,
|
||||
};
|
||||
|
||||
static void emit_node_info(struct node *this)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info) {
|
||||
struct spa_node_info info;
|
||||
struct spa_param_info params[4];
|
||||
struct spa_node_info info;
|
||||
struct spa_param_info params[4];
|
||||
|
||||
info = SPA_NODE_INFO_INIT();
|
||||
info.max_input_ports = 0;
|
||||
info.max_output_ports = 0;
|
||||
info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Profile, SPA_PARAM_INFO_WRITE);
|
||||
info.params = params;
|
||||
info.n_params = 4;
|
||||
this->callbacks->info(this->callbacks_data, &info);
|
||||
info = SPA_NODE_INFO_INIT();
|
||||
info.max_input_ports = 0;
|
||||
info.max_output_ports = 0;
|
||||
info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Profile, SPA_PARAM_INFO_WRITE);
|
||||
info.params = params;
|
||||
info.n_params = 4;
|
||||
spa_node_emit_info(&this->hooks, &info);
|
||||
}
|
||||
|
||||
static int impl_node_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct node *this;
|
||||
struct impl *impl;
|
||||
struct spa_hook l;
|
||||
struct spa_hook_list save;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
impl = this->impl;
|
||||
|
||||
pw_log_debug("%p: add listener %p", this, listener);
|
||||
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
|
||||
|
||||
emit_node_info(this);
|
||||
|
||||
if (impl->adapter && impl->adapter != impl->cnode) {
|
||||
spa_zero(l);
|
||||
spa_node_add_listener(impl->adapter, &l, &adapter_node_events, impl);
|
||||
spa_hook_remove(&l);
|
||||
}
|
||||
|
||||
spa_hook_list_join(&this->hooks, &save);
|
||||
|
||||
return spa_node_sync(impl->cnode, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -337,23 +360,7 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
const struct spa_node_callbacks *callbacks,
|
||||
void *data)
|
||||
{
|
||||
struct node *this;
|
||||
struct impl *impl;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
impl = this->impl;
|
||||
|
||||
this->callbacks = callbacks;
|
||||
this->callbacks_data = data;
|
||||
|
||||
emit_node_info(this);
|
||||
|
||||
if (this->callbacks && impl->adapter && impl->adapter != impl->cnode)
|
||||
spa_node_set_callbacks(impl->adapter, &adapter_node_callbacks, impl);
|
||||
|
||||
return spa_node_sync(impl->cnode, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -429,7 +436,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
|
||||
impl = this->impl;
|
||||
|
||||
if (direction != impl->direction)
|
||||
|
|
@ -459,8 +465,7 @@ static int debug_params(struct impl *impl, struct spa_node *node,
|
|||
res = spa_node_port_enum_params_sync(node,
|
||||
direction, port_id,
|
||||
id, &state,
|
||||
NULL, ¶m, &b,
|
||||
impl->this.node->pending);
|
||||
NULL, ¶m, &b);
|
||||
if (res != 1) {
|
||||
if (res < 0)
|
||||
spa_log_error(this->log, " error: %s", spa_strerror(res));
|
||||
|
|
@ -495,8 +500,7 @@ static int negotiate_format(struct impl *impl)
|
|||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
NULL, &format, &b,
|
||||
impl->this.node->pending)) != 1) {
|
||||
NULL, &format, &b)) != 1) {
|
||||
debug_params(impl, impl->adapter_mix,
|
||||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
|
|
@ -508,8 +512,7 @@ static int negotiate_format(struct impl *impl)
|
|||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
format, &format, &b,
|
||||
impl->client_node->node->pending)) != 1) {
|
||||
format, &format, &b)) != 1) {
|
||||
debug_params(impl, impl->cnode, impl->direction, 0,
|
||||
SPA_PARAM_EnumFormat, format);
|
||||
return -ENOTSUP;
|
||||
|
|
@ -561,8 +564,7 @@ static int negotiate_buffers(struct impl *impl)
|
|||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
SPA_PARAM_Buffers, &state,
|
||||
param, ¶m, &b,
|
||||
impl->this.node->pending)) != 1) {
|
||||
param, ¶m, &b)) != 1) {
|
||||
debug_params(impl, impl->adapter_mix,
|
||||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
|
|
@ -576,8 +578,7 @@ static int negotiate_buffers(struct impl *impl)
|
|||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
SPA_PARAM_Buffers, &state,
|
||||
param, ¶m, &b,
|
||||
impl->client_node->node->pending)) < 0) {
|
||||
param, ¶m, &b)) < 0) {
|
||||
debug_params(impl, impl->cnode, impl->direction, 0,
|
||||
SPA_PARAM_Buffers, param);
|
||||
return res;
|
||||
|
|
@ -866,6 +867,7 @@ static int impl_node_process(struct spa_node *node)
|
|||
|
||||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
.add_listener = impl_node_add_listener,
|
||||
.set_callbacks = impl_node_set_callbacks,
|
||||
.sync = impl_node_sync,
|
||||
.enum_params = impl_node_enum_params,
|
||||
|
|
@ -896,6 +898,8 @@ node_init(struct node *this,
|
|||
this->log = support[i].data;
|
||||
}
|
||||
this->node = impl_node;
|
||||
spa_hook_list_init(&this->hooks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -910,21 +914,16 @@ static int do_port_info(void *data, struct pw_port *port)
|
|||
info.flags = port->spa_flags;
|
||||
info.props = &port->properties->dict;
|
||||
|
||||
node->callbacks->port_info(node->callbacks_data,
|
||||
spa_node_emit_port_info(&node->hooks,
|
||||
impl->direction, port->port_id, &info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emit_port_info(struct impl *impl)
|
||||
{
|
||||
struct node *node = &impl->node;
|
||||
|
||||
if (node->callbacks && node->callbacks->port_info) {
|
||||
pw_node_for_each_port(impl->client_node->node,
|
||||
impl->direction,
|
||||
do_port_info,
|
||||
impl);
|
||||
}
|
||||
pw_node_for_each_port(impl->client_node->node,
|
||||
impl->direction,
|
||||
do_port_info, impl);
|
||||
}
|
||||
|
||||
static void client_node_initialized(void *data)
|
||||
|
|
@ -992,8 +991,7 @@ static void client_node_initialized(void *data)
|
|||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
NULL, &format, &b,
|
||||
impl->client_node->node->pending)) != 1) {
|
||||
NULL, &format, &b)) != 1) {
|
||||
pw_log_warn("client-stream %p: no format given", &impl->this);
|
||||
impl->adapter = impl->cnode;
|
||||
impl->adapter_mix = impl->client_port->mix;
|
||||
|
|
@ -1038,8 +1036,8 @@ static void client_node_initialized(void *data)
|
|||
impl->adapter_mix = impl->adapter;
|
||||
impl->adapter_mix_port = 0;
|
||||
impl->use_converter = true;
|
||||
if (impl->node.callbacks != NULL)
|
||||
spa_node_set_callbacks(impl->adapter, &adapter_node_callbacks, impl);
|
||||
spa_node_add_listener(impl->adapter, &impl->adapter_listener,
|
||||
&adapter_node_events, impl);
|
||||
}
|
||||
else {
|
||||
impl->adapter = impl->cnode;
|
||||
|
|
@ -1116,7 +1114,7 @@ static void client_node_result(void *data, int seq, int res, const void *result)
|
|||
struct impl *impl = data;
|
||||
struct node *node = &impl->node;
|
||||
pw_log_debug("client-stream %p: result %d %d", &impl->this, seq, res);
|
||||
node->callbacks->result(node->callbacks_data, seq, res, result);
|
||||
spa_node_emit_result(&node->hooks, seq, res, result);
|
||||
}
|
||||
|
||||
static void client_node_active_changed(void *data, bool active)
|
||||
|
|
|
|||
|
|
@ -420,8 +420,7 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
|
|||
if (spa_node_port_enum_params_sync(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
id, &idx2,
|
||||
NULL, ¶m, &b,
|
||||
port->node->pending) != 1)
|
||||
NULL, ¶m, &b) != 1)
|
||||
break;
|
||||
|
||||
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
|
||||
|
|
@ -434,7 +433,7 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
|
|||
SPA_PORT_CHANGE_MASK_RATE |
|
||||
SPA_PORT_CHANGE_MASK_PROPS;
|
||||
pi.flags = port->spa_flags;
|
||||
pi.rate = 0;
|
||||
pi.rate = SPA_FRACTION(0, 1);
|
||||
pi.props = &port->properties->dict;
|
||||
pi.flags &= ~SPA_PORT_FLAG_CAN_ALLOC_BUFFERS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,17 +170,6 @@ void *pw_spa_node_get_user_data(struct pw_node *node)
|
|||
return impl->user_data;
|
||||
}
|
||||
|
||||
static int on_node_result(void *data, int seq, int res, const void *result)
|
||||
{
|
||||
struct spa_pending_queue *pending = data;
|
||||
return spa_pending_queue_complete(pending, seq, res, result);
|
||||
}
|
||||
|
||||
static const struct spa_node_callbacks node_callbacks = {
|
||||
SPA_VERSION_NODE_CALLBACKS,
|
||||
.result = on_node_result,
|
||||
};
|
||||
|
||||
static int
|
||||
setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_properties *pw_props)
|
||||
{
|
||||
|
|
@ -192,15 +181,11 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
|
|||
uint8_t buf[2048];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
|
||||
const struct spa_pod_prop *prop = NULL;
|
||||
struct spa_pending_queue pending;
|
||||
|
||||
spa_pending_queue_init(&pending);
|
||||
|
||||
spa_node_set_callbacks(spa_node, &node_callbacks, &pending);
|
||||
|
||||
if ((res = spa_node_enum_params_sync(spa_node,
|
||||
res = spa_node_enum_params_sync(spa_node,
|
||||
SPA_PARAM_Props, &index, NULL, &props,
|
||||
&b, &pending)) != 1) {
|
||||
&b);
|
||||
if (res != 1) {
|
||||
if (res < 0)
|
||||
pw_log_debug("spa_node_get_props failed: %d", res);
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -836,8 +836,7 @@ int pw_core_find_format(struct pw_core *core,
|
|||
if ((res = spa_node_port_enum_params_sync(output->node->node,
|
||||
output->direction, output->port_id,
|
||||
SPA_PARAM_Format, &oidx,
|
||||
NULL, format, builder,
|
||||
output->node->pending)) != 1) {
|
||||
NULL, format, builder)) != 1) {
|
||||
if (res == 0)
|
||||
res = -EBADF;
|
||||
asprintf(error, "error get output format: %s", spa_strerror(res));
|
||||
|
|
@ -851,8 +850,7 @@ int pw_core_find_format(struct pw_core *core,
|
|||
if ((res = spa_node_port_enum_params_sync(input->node->node,
|
||||
input->direction, input->port_id,
|
||||
SPA_PARAM_Format, &iidx,
|
||||
NULL, format, builder,
|
||||
input->node->pending)) != 1) {
|
||||
NULL, format, builder)) != 1) {
|
||||
if (res == 0)
|
||||
res = -EBADF;
|
||||
asprintf(error, "error get input format: %s", spa_strerror(res));
|
||||
|
|
@ -872,8 +870,7 @@ int pw_core_find_format(struct pw_core *core,
|
|||
if ((res = spa_node_port_enum_params_sync(input->node->node,
|
||||
input->direction, input->port_id,
|
||||
SPA_PARAM_EnumFormat, &iidx,
|
||||
NULL, &filter, &fb,
|
||||
input->node->pending)) != 1) {
|
||||
NULL, &filter, &fb)) != 1) {
|
||||
if (res == 0 && iidx == 0) {
|
||||
asprintf(error, "error input enum formats: %s", spa_strerror(res));
|
||||
goto error;
|
||||
|
|
@ -888,8 +885,7 @@ int pw_core_find_format(struct pw_core *core,
|
|||
if ((res = spa_node_port_enum_params_sync(output->node->node,
|
||||
output->direction, output->port_id,
|
||||
SPA_PARAM_EnumFormat, &oidx,
|
||||
filter, format, builder,
|
||||
output->node->pending)) != 1) {
|
||||
filter, format, builder)) != 1) {
|
||||
if (res == 0) {
|
||||
oidx = 0;
|
||||
goto again;
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@
|
|||
|
||||
struct impl {
|
||||
struct pw_device this;
|
||||
|
||||
struct spa_pending_queue pending;
|
||||
};
|
||||
|
||||
struct resource_data {
|
||||
|
|
@ -65,8 +63,6 @@ struct pw_device *pw_device_new(struct pw_core *core,
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
spa_pending_queue_init(&impl->pending);
|
||||
|
||||
this = &impl->this;
|
||||
|
||||
if (properties == NULL)
|
||||
|
|
@ -138,12 +134,12 @@ struct result_device_params_data {
|
|||
struct spa_pod *param);
|
||||
};
|
||||
|
||||
static int result_device_params(struct spa_pending *pending, const void *result)
|
||||
static int result_device_params(void *data, int seq, int res, const void *result)
|
||||
{
|
||||
struct result_device_params_data *d = pending->data;
|
||||
struct result_device_params_data *d = data;
|
||||
const struct spa_result_device_params *r =
|
||||
(const struct spa_result_device_params *)result;
|
||||
d->callback(d->data, pending->seq, r->id, r->index, r->next, r->param);
|
||||
d->callback(d->data, seq, r->id, r->index, r->next, r->param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -157,21 +153,27 @@ int pw_device_for_each_param(struct pw_device *device,
|
|||
struct spa_pod *param),
|
||||
void *data)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(device, struct impl, this);
|
||||
int res;
|
||||
struct result_device_params_data user_data = { data, callback };
|
||||
struct spa_pending pending;
|
||||
struct spa_hook listener;
|
||||
static const struct spa_device_events device_events = {
|
||||
SPA_VERSION_DEVICE_EVENTS,
|
||||
.result = result_device_params,
|
||||
};
|
||||
|
||||
if (max == 0)
|
||||
max = UINT32_MAX;
|
||||
|
||||
spa_pending_queue_add(&impl->pending, seq, &pending,
|
||||
result_device_params, &user_data);
|
||||
pw_log_debug("device %p: params %s %u %u", device,
|
||||
spa_debug_type_find_name(spa_type_param, param_id),
|
||||
index, max);
|
||||
|
||||
spa_zero(listener);
|
||||
spa_node_add_listener(device->implementation, &listener,
|
||||
&device_events, &user_data);
|
||||
res = spa_device_enum_params(device->implementation, seq,
|
||||
param_id, index, max, filter);
|
||||
|
||||
spa_pending_remove(&pending);
|
||||
spa_hook_remove(&listener);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -274,6 +276,7 @@ int pw_device_register(struct pw_device *device,
|
|||
struct pw_properties *properties)
|
||||
{
|
||||
struct pw_core *core = device->core;
|
||||
struct node_data *nd;
|
||||
const char *str;
|
||||
|
||||
if (properties == NULL)
|
||||
|
|
@ -296,10 +299,14 @@ int pw_device_register(struct pw_device *device,
|
|||
if (device->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
device->info.id = device->global->id;
|
||||
pw_global_add_listener(device->global, &device->global_listener, &global_events, device);
|
||||
pw_global_register(device->global, owner, parent);
|
||||
device->info.id = device->global->id;
|
||||
|
||||
spa_list_for_each(nd, &device->node_list, link) {
|
||||
pw_node_register(nd->node, NULL, device->global, NULL);
|
||||
pw_node_set_active(nd->node, true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -412,9 +419,11 @@ static void device_add(struct pw_device *device, uint32_t id,
|
|||
}
|
||||
|
||||
pw_node_set_implementation(node, iface);
|
||||
pw_node_register(node, NULL, device->global, NULL);
|
||||
pw_node_set_active(node, true);
|
||||
|
||||
if (device->global) {
|
||||
pw_node_register(node, NULL, device->global, NULL);
|
||||
pw_node_set_active(node, true);
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
|
|
@ -459,25 +468,27 @@ static int device_object_info(void *data, uint32_t id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int device_result(void *data, int seq, int res, const void *result)
|
||||
{
|
||||
struct pw_device *device = data;
|
||||
struct impl *impl = SPA_CONTAINER_OF(device, struct impl, this);
|
||||
return spa_pending_queue_complete(&impl->pending, seq, res, result);
|
||||
}
|
||||
|
||||
static const struct spa_device_callbacks device_callbacks = {
|
||||
SPA_VERSION_DEVICE_CALLBACKS,
|
||||
static const struct spa_device_events device_events = {
|
||||
SPA_VERSION_DEVICE_EVENTS,
|
||||
.info = device_info,
|
||||
.object_info = device_object_info,
|
||||
.result = device_result,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
void pw_device_set_implementation(struct pw_device *device, struct spa_device *spa_device)
|
||||
int pw_device_set_implementation(struct pw_device *device, struct spa_device *spa_device)
|
||||
{
|
||||
pw_log_debug("device %p: implementation %p", device, spa_device);
|
||||
|
||||
if (device->implementation) {
|
||||
pw_log_error("device %p: implementation existed %p",
|
||||
device, device->implementation);
|
||||
return -EEXIST;
|
||||
}
|
||||
device->implementation = spa_device;
|
||||
spa_device_set_callbacks(device->implementation, &device_callbacks, device);
|
||||
spa_device_add_listener(device->implementation,
|
||||
&device->listener, &device_events, device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ void pw_device_destroy(struct pw_device *device);
|
|||
void *pw_device_get_user_data(struct pw_device *device);
|
||||
|
||||
/** Set the device implementation */
|
||||
void pw_device_set_implementation(struct pw_device *device, struct spa_device *spa_device);
|
||||
int pw_device_set_implementation(struct pw_device *device, struct spa_device *spa_device);
|
||||
/** Get the device implementation */
|
||||
struct spa_device *pw_device_get_implementation(struct pw_device *device);
|
||||
|
||||
|
|
|
|||
|
|
@ -385,11 +385,22 @@ struct pw_device_info *pw_device_info_update(struct pw_device_info *info,
|
|||
info->name = update->name ? strdup(update->name) : NULL;
|
||||
info->change_mask = update->change_mask;
|
||||
|
||||
if (update->change_mask & PW_CLIENT_CHANGE_MASK_PROPS) {
|
||||
if (update->change_mask & PW_DEVICE_CHANGE_MASK_PROPS) {
|
||||
if (info->props)
|
||||
pw_spa_dict_destroy(info->props);
|
||||
info->props = pw_spa_dict_copy(update->props);
|
||||
}
|
||||
if (update->change_mask & PW_DEVICE_CHANGE_MASK_PARAMS) {
|
||||
info->n_params = update->n_params;
|
||||
free((void *) info->params);
|
||||
if (update->params) {
|
||||
size_t size = info->n_params * sizeof(struct spa_param_info);
|
||||
info->params = malloc(size);
|
||||
memcpy(info->params, update->params, size);
|
||||
}
|
||||
else
|
||||
info->params = NULL;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -399,6 +410,7 @@ void pw_device_info_free(struct pw_device_info *info)
|
|||
free((void *) info->name);
|
||||
if (info->props)
|
||||
pw_spa_dict_destroy(info->props);
|
||||
free((void *) info->params);
|
||||
free(info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,8 +225,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
res = spa_node_port_enum_params_sync(output->node->node,
|
||||
output->direction, output->port_id,
|
||||
SPA_PARAM_Format, &index,
|
||||
NULL, ¤t, &b,
|
||||
output->node->pending);
|
||||
NULL, ¤t, &b);
|
||||
switch (res) {
|
||||
case -EIO:
|
||||
current = NULL;
|
||||
|
|
@ -261,8 +260,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
res = spa_node_port_enum_params_sync(input->node->node,
|
||||
input->direction, input->port_id,
|
||||
SPA_PARAM_Format, &index,
|
||||
NULL, ¤t, &b,
|
||||
input->node->pending);
|
||||
NULL, ¤t, &b);
|
||||
switch (res) {
|
||||
case -EIO:
|
||||
current = NULL;
|
||||
|
|
@ -458,8 +456,7 @@ param_filter(struct pw_link *this,
|
|||
pw_log_debug("iparam %d", iidx);
|
||||
if ((res = spa_node_port_enum_params_sync(in_port->node->node,
|
||||
in_port->direction, in_port->port_id,
|
||||
id, &iidx, NULL, &iparam, &ib,
|
||||
in_port->node->pending)) < 0)
|
||||
id, &iidx, NULL, &iparam, &ib)) < 0)
|
||||
break;
|
||||
|
||||
if (res != 1) {
|
||||
|
|
@ -475,8 +472,7 @@ param_filter(struct pw_link *this,
|
|||
pw_log_debug("oparam %d", oidx);
|
||||
if (spa_node_port_enum_params_sync(out_port->node->node,
|
||||
out_port->direction, out_port->port_id,
|
||||
id, &oidx, iparam, &oparam, result,
|
||||
out_port->node->pending) != 1) {
|
||||
id, &oidx, iparam, &oparam, result) != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ struct impl {
|
|||
uint32_t next_position;
|
||||
int last_error;
|
||||
|
||||
struct spa_pending_queue pending;
|
||||
int pause_on_idle:1;
|
||||
};
|
||||
|
||||
|
|
@ -373,22 +372,8 @@ static void global_destroy(void *data)
|
|||
pw_node_destroy(this);
|
||||
}
|
||||
|
||||
static void global_registering(void *data)
|
||||
{
|
||||
struct pw_node *this = data;
|
||||
struct pw_port *port;
|
||||
|
||||
spa_list_for_each(port, &this->input_ports, link)
|
||||
pw_port_register(port, this->global->owner, this->global,
|
||||
pw_properties_copy(port->properties));
|
||||
spa_list_for_each(port, &this->output_ports, link)
|
||||
pw_port_register(port, this->global->owner, this->global,
|
||||
pw_properties_copy(port->properties));
|
||||
}
|
||||
|
||||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.registering = global_registering,
|
||||
.destroy = global_destroy,
|
||||
};
|
||||
|
||||
|
|
@ -399,6 +384,7 @@ int pw_node_register(struct pw_node *this,
|
|||
struct pw_properties *properties)
|
||||
{
|
||||
struct pw_core *core = this->core;
|
||||
struct pw_port *port;
|
||||
const char *str;
|
||||
|
||||
pw_log_debug("node %p: register", this);
|
||||
|
|
@ -437,6 +423,13 @@ int pw_node_register(struct pw_node *this,
|
|||
pw_global_add_listener(this->global, &this->global_listener, &global_events, this);
|
||||
pw_global_register(this->global, owner, parent);
|
||||
|
||||
spa_list_for_each(port, &this->input_ports, link)
|
||||
pw_port_register(port, this->global->owner, this->global,
|
||||
pw_properties_copy(port->properties));
|
||||
spa_list_for_each(port, &this->output_ports, link)
|
||||
pw_port_register(port, this->global->owner, this->global,
|
||||
pw_properties_copy(port->properties));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -688,9 +681,6 @@ struct pw_node *pw_node_new(struct pw_core *core,
|
|||
&this->activation) < 0)
|
||||
goto clean_impl;
|
||||
|
||||
spa_pending_queue_init(&impl->pending);
|
||||
this->pending = &impl->pending;
|
||||
|
||||
impl->work = pw_work_queue_new(this->core->main_loop);
|
||||
if (impl->work == NULL)
|
||||
goto clean_impl;
|
||||
|
|
@ -810,6 +800,10 @@ static int node_info(void *data, const struct spa_node_info *info)
|
|||
node->info.max_input_ports = info->max_input_ports;
|
||||
node->info.max_output_ports = info->max_output_ports;
|
||||
|
||||
pw_log_debug("node %p: change_mask %08lx max_in:%u max_out:%u",
|
||||
node, info->change_mask, info->max_input_ports,
|
||||
info->max_output_ports);
|
||||
|
||||
if (info->change_mask & SPA_NODE_CHANGE_MASK_PROPS) {
|
||||
update_properties(node, info->props);
|
||||
}
|
||||
|
|
@ -868,7 +862,6 @@ static int node_result(void *data, int seq, int res, const void *result)
|
|||
|
||||
pw_log_trace("node %p: result seq:%d res:%d", node, seq, res);
|
||||
impl->last_error = res;
|
||||
spa_pending_queue_complete(&impl->pending, seq, res, result);
|
||||
|
||||
if (SPA_RESULT_IS_ASYNC(seq))
|
||||
pw_work_queue_complete(impl->work, &impl->this, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
|
|
@ -933,12 +926,16 @@ static int node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_node_callbacks node_callbacks = {
|
||||
SPA_VERSION_NODE_CALLBACKS,
|
||||
static const struct spa_node_events node_events = {
|
||||
SPA_VERSION_NODE_EVENTS,
|
||||
.info = node_info,
|
||||
.port_info = node_port_info,
|
||||
.result = node_result,
|
||||
.event = node_event,
|
||||
};
|
||||
|
||||
static const struct spa_node_callbacks node_callbacks = {
|
||||
SPA_VERSION_NODE_CALLBACKS,
|
||||
.ready = node_ready,
|
||||
.reuse_buffer = node_reuse_buffer,
|
||||
};
|
||||
|
|
@ -949,10 +946,17 @@ int pw_node_set_implementation(struct pw_node *node,
|
|||
{
|
||||
int res;
|
||||
|
||||
node->node = spa_node;
|
||||
pw_log_debug("node %p: implementation %p", node, spa_node);
|
||||
|
||||
if (node->node) {
|
||||
pw_log_error("node %p: implementation existed %p", node, node->node);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
node->node = spa_node;
|
||||
spa_graph_node_set_callbacks(&node->rt.node, &spa_graph_node_impl_default, spa_node);
|
||||
res = spa_node_set_callbacks(node->node, &node_callbacks, node);
|
||||
spa_node_set_callbacks(node->node, &node_callbacks, node);
|
||||
res = spa_node_add_listener(node->node, &node->listener, &node_events, node);
|
||||
|
||||
if (spa_node_set_io(node->node,
|
||||
SPA_IO_Position,
|
||||
|
|
@ -1086,12 +1090,11 @@ struct result_node_params_data {
|
|||
struct spa_pod *param);
|
||||
};
|
||||
|
||||
static int result_node_params(struct spa_pending *pending, const void *result)
|
||||
static int result_node_params(void *data, int seq, int res, const void *result)
|
||||
{
|
||||
struct result_node_params_data *d = pending->data;
|
||||
const struct spa_result_node_params *r =
|
||||
(const struct spa_result_node_params *)result;
|
||||
d->callback(d->data, pending->seq, r->id, r->index, r->next, r->param);
|
||||
struct result_node_params_data *d = data;
|
||||
const struct spa_result_node_params *r = result;
|
||||
d->callback(d->data, seq, r->id, r->index, r->next, r->param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1105,24 +1108,27 @@ int pw_node_for_each_param(struct pw_node *node,
|
|||
struct spa_pod *param),
|
||||
void *data)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
|
||||
int res;
|
||||
struct result_node_params_data user_data = { data, callback };
|
||||
struct spa_pending pending;
|
||||
struct spa_hook listener;
|
||||
static const struct spa_node_events node_events = {
|
||||
SPA_VERSION_NODE_EVENTS,
|
||||
.result = result_node_params,
|
||||
};
|
||||
|
||||
if (max == 0)
|
||||
max = UINT32_MAX;
|
||||
|
||||
pw_log_debug("node %p: params %s %u %u", impl,
|
||||
pw_log_debug("node %p: params %s %u %u", node,
|
||||
spa_debug_type_find_name(spa_type_param, param_id),
|
||||
index, max);
|
||||
|
||||
spa_pending_queue_add(&impl->pending, seq, &pending,
|
||||
result_node_params, &user_data);
|
||||
spa_zero(listener);
|
||||
spa_node_add_listener(node->node, &listener, &node_events, &user_data);
|
||||
res = spa_node_enum_params(node->node, seq,
|
||||
param_id, index, max,
|
||||
filter);
|
||||
spa_pending_remove(&pending);
|
||||
spa_hook_remove(&listener);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -798,12 +798,11 @@ struct result_port_params_data {
|
|||
struct spa_pod *param);
|
||||
};
|
||||
|
||||
static int result_port_params(struct spa_pending *pending, const void *result)
|
||||
static int result_port_params(void *data, int seq, int res, const void *result)
|
||||
{
|
||||
struct result_port_params_data *d = pending->data;
|
||||
const struct spa_result_node_params *r =
|
||||
(const struct spa_result_node_params *)result;
|
||||
d->callback(d->data, pending->seq, r->id, r->index, r->next, r->param);
|
||||
struct result_port_params_data *d = data;
|
||||
const struct spa_result_node_params *r = result;
|
||||
d->callback(d->data, seq, r->id, r->index, r->next, r->param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -820,7 +819,11 @@ int pw_port_for_each_param(struct pw_port *port,
|
|||
int res;
|
||||
struct pw_node *node = port->node;
|
||||
struct result_port_params_data user_data = { data, callback };
|
||||
struct spa_pending pending;
|
||||
struct spa_hook listener;
|
||||
static const struct spa_node_events node_events = {
|
||||
SPA_VERSION_NODE_EVENTS,
|
||||
.result = result_port_params,
|
||||
};
|
||||
|
||||
if (max == 0)
|
||||
max = UINT32_MAX;
|
||||
|
|
@ -829,14 +832,13 @@ int pw_port_for_each_param(struct pw_port *port,
|
|||
spa_debug_type_find_name(spa_type_param, param_id),
|
||||
index, max);
|
||||
|
||||
spa_pending_queue_add(node->pending, seq, &pending,
|
||||
result_port_params, &user_data);
|
||||
|
||||
spa_zero(listener);
|
||||
spa_node_add_listener(node->node, &listener, &node_events, &user_data);
|
||||
res = spa_node_port_enum_params(node->node, seq,
|
||||
port->direction, port->port_id,
|
||||
param_id, index, max,
|
||||
filter);
|
||||
spa_pending_remove(&pending);
|
||||
spa_hook_remove(&listener);
|
||||
|
||||
pw_log_debug("port %p: res %d: (%s)", port, res, spa_strerror(res));
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -265,6 +265,7 @@ struct pw_device {
|
|||
struct spa_param_info params[32];
|
||||
|
||||
struct spa_device *implementation; /**< implementation */
|
||||
struct spa_hook listener;
|
||||
struct spa_hook_list listener_list;
|
||||
|
||||
struct spa_list node_list;
|
||||
|
|
@ -353,6 +354,7 @@ struct pw_node {
|
|||
struct spa_list driver_link;
|
||||
|
||||
struct spa_node *node; /**< SPA node implementation */
|
||||
struct spa_hook listener;
|
||||
|
||||
struct spa_list input_ports; /**< list of input ports */
|
||||
struct pw_map input_port_map; /**< map from port_id to port */
|
||||
|
|
@ -371,8 +373,6 @@ struct pw_node {
|
|||
|
||||
struct pw_loop *data_loop; /**< the data loop for this node */
|
||||
|
||||
struct spa_pending_queue *pending;
|
||||
|
||||
uint32_t quantum_size; /**< desired quantum */
|
||||
struct spa_source source; /**< source to remotely trigger this node */
|
||||
struct pw_memblock *activation;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ struct stream {
|
|||
struct spa_port_info port_info;
|
||||
|
||||
struct spa_node impl_node;
|
||||
struct spa_hook_list hooks;
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
struct spa_io_buffers *io;
|
||||
|
|
@ -315,40 +316,56 @@ static int impl_send_command(struct spa_node *node, const struct spa_command *co
|
|||
|
||||
static void emit_node_info(struct stream *d)
|
||||
{
|
||||
if (d->callbacks && d->callbacks->info) {
|
||||
struct spa_node_info info;
|
||||
info = SPA_NODE_INFO_INIT();
|
||||
if (d->direction == SPA_DIRECTION_INPUT) {
|
||||
info.max_input_ports = 1;
|
||||
info.max_output_ports = 0;
|
||||
} else {
|
||||
info.max_input_ports = 0;
|
||||
info.max_output_ports = 1;
|
||||
}
|
||||
info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_NODE_FLAG_RT;
|
||||
d->callbacks->info(d->callbacks_data, &info);
|
||||
struct spa_node_info info;
|
||||
|
||||
info = SPA_NODE_INFO_INIT();
|
||||
if (d->direction == SPA_DIRECTION_INPUT) {
|
||||
info.max_input_ports = 1;
|
||||
info.max_output_ports = 0;
|
||||
} else {
|
||||
info.max_input_ports = 0;
|
||||
info.max_output_ports = 1;
|
||||
}
|
||||
info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_NODE_FLAG_RT;
|
||||
spa_node_emit_info(&d->hooks, &info);
|
||||
}
|
||||
|
||||
static void emit_port_info(struct stream *d)
|
||||
{
|
||||
if (d->callbacks && d->callbacks->port_info) {
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[5];
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[5];
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
info.params = params;
|
||||
info.n_params = 5;
|
||||
d->callbacks->port_info(d->callbacks_data, d->direction, 0, &info);
|
||||
}
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
info.params = params;
|
||||
info.n_params = 5;
|
||||
spa_node_emit_port_info(&d->hooks, d->direction, 0, &info);
|
||||
}
|
||||
|
||||
static int impl_add_listener(struct spa_node *node,
|
||||
struct spa_hook *listener,
|
||||
const struct spa_node_events *events,
|
||||
void *data)
|
||||
{
|
||||
struct stream *d = SPA_CONTAINER_OF(node, struct stream, impl_node);
|
||||
struct spa_hook_list save;
|
||||
|
||||
spa_hook_list_isolate(&d->hooks, &save, listener, events, data);
|
||||
|
||||
emit_node_info(d);
|
||||
emit_port_info(d);
|
||||
|
||||
spa_hook_list_join(&d->hooks, &save);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_set_callbacks(struct spa_node *node,
|
||||
|
|
@ -359,9 +376,6 @@ static int impl_set_callbacks(struct spa_node *node,
|
|||
d->callbacks = callbacks;
|
||||
d->callbacks_data = data;
|
||||
|
||||
emit_node_info(d);
|
||||
emit_port_info(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +429,6 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
|
||||
|
|
@ -439,8 +452,7 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
|||
if (spa_pod_filter(&b, &result.param, param, filter) != 0)
|
||||
continue;
|
||||
|
||||
if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0)
|
||||
return res;
|
||||
spa_node_emit_result(&d->hooks, seq, 0, &result);
|
||||
|
||||
if (++count == num)
|
||||
break;
|
||||
|
|
@ -781,9 +793,10 @@ static int impl_node_process_output(struct spa_node *node)
|
|||
|
||||
static const struct spa_node impl_node = {
|
||||
SPA_VERSION_NODE,
|
||||
.add_listener = impl_add_listener,
|
||||
.set_callbacks = impl_set_callbacks,
|
||||
.set_io = impl_set_io,
|
||||
.send_command = impl_send_command,
|
||||
.set_callbacks = impl_set_callbacks,
|
||||
.port_set_io = impl_port_set_io,
|
||||
.port_enum_params = impl_port_enum_params,
|
||||
.port_set_param = impl_port_set_param,
|
||||
|
|
@ -928,6 +941,7 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name,
|
|||
pw_properties_set(props, "node.name", name);
|
||||
}
|
||||
|
||||
spa_hook_list_init(&impl->hooks);
|
||||
this->properties = props;
|
||||
|
||||
this->remote = remote;
|
||||
|
|
|
|||
|
|
@ -164,6 +164,25 @@ static void print_properties(struct spa_dict *props, char mark, bool header)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_params(struct spa_param_info *params, uint32_t n_params, char mark, bool header)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (header)
|
||||
fprintf(stdout, "%c\tparams: (%u)\n", mark, n_params);
|
||||
if (params == NULL || n_params == 0) {
|
||||
if (header)
|
||||
fprintf(stdout, "\t\tnone\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < n_params; i++) {
|
||||
fprintf(stdout, "%c\t %d (%s) %c%c\n", mark, params[i].id,
|
||||
spa_debug_type_find_name(spa_type_param, params[i].id),
|
||||
params[i].flags & SPA_PARAM_INFO_READ ? 'r' : '-',
|
||||
params[i].flags & SPA_PARAM_INFO_WRITE ? 'w' : '-');
|
||||
}
|
||||
}
|
||||
|
||||
static bool do_not_implemented(struct data *data, const char *cmd, char *args, char **error)
|
||||
{
|
||||
asprintf(error, "Command \"%s\" not yet implemented", cmd);
|
||||
|
|
@ -182,8 +201,7 @@ static bool do_create_node(struct data *data, const char *cmd, char *args, char
|
|||
static bool do_destroy(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_create_link(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_export_node(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_node_params(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_port_params(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_enum_params(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_permissions(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_get_permissions(struct data *data, const char *cmd, char *args, char **error);
|
||||
|
||||
|
|
@ -201,8 +219,7 @@ static struct command command_list[] = {
|
|||
{ "destroy", "Destroy a global object. <object-id>", do_destroy },
|
||||
{ "create-link", "Create a link between nodes. <node-id> <port-id> <node-id> <port-id> [<properties>]", do_create_link },
|
||||
{ "export-node", "Export a local node to the current remote. <node-id> [remote-var]", do_export_node },
|
||||
{ "node-params", "Enumerate params of a node <node-id> [<param-id-name>]", do_node_params },
|
||||
{ "port-params", "Enumerate params of a port <port-id> [<param-id-name>]", do_port_params },
|
||||
{ "enum-params", "Enumerate params of an object <object-id> [<param-id-name>]", do_enum_params },
|
||||
{ "permissions", "Set permissions for a client <client-id> <permissions>", do_permissions },
|
||||
{ "get-permissions", "Get permissions of a client <client-id>", do_get_permissions },
|
||||
};
|
||||
|
|
@ -553,7 +570,6 @@ 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);
|
||||
|
|
@ -567,26 +583,17 @@ static void info_node(struct proxy_data *pd)
|
|||
else
|
||||
fprintf(stdout, "\n");
|
||||
print_properties(info->props, MARK_CHANGE(4), true);
|
||||
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));
|
||||
}
|
||||
print_params(info->params, info->n_params, MARK_CHANGE(5), true);
|
||||
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\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));
|
||||
}
|
||||
print_params(info->params, info->n_params, MARK_CHANGE(1), true);
|
||||
info->change_mask = 0;
|
||||
}
|
||||
|
||||
|
|
@ -635,6 +642,7 @@ static void info_device(struct proxy_data *pd)
|
|||
info_global(pd);
|
||||
fprintf(stdout, "\tname: \"%s\"\n", info->name);
|
||||
print_properties(info->props, MARK_CHANGE(0), true);
|
||||
print_params(info->params, info->n_params, MARK_CHANGE(1), true);
|
||||
info->change_mask = 0;
|
||||
}
|
||||
|
||||
|
|
@ -697,13 +705,13 @@ static int node_event_info(void *object, const struct pw_node_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int node_event_param(void *object, int seq, uint32_t id,
|
||||
static int 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;
|
||||
struct remote_data *rd = data->rd;
|
||||
|
||||
fprintf(stdout, "remote %d node %d param %d index %d\n",
|
||||
fprintf(stdout, "remote %d object %d param %d index %d\n",
|
||||
rd->id, data->global->id, id, index);
|
||||
|
||||
if (spa_pod_is_object_type(param, SPA_TYPE_OBJECT_Format))
|
||||
|
|
@ -716,7 +724,7 @@ static int node_event_param(void *object, int seq, uint32_t id,
|
|||
static const struct pw_node_proxy_events node_events = {
|
||||
PW_VERSION_NODE_PROXY_EVENTS,
|
||||
.info = node_event_info,
|
||||
.param = node_event_param
|
||||
.param = event_param
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -736,26 +744,10 @@ static int port_event_info(void *object, const struct pw_port_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
struct remote_data *rd = data->rd;
|
||||
|
||||
fprintf(stdout, "remote %d port %d param %d index %d\n",
|
||||
rd->id, data->global->id, id, index);
|
||||
|
||||
if (spa_pod_is_object_type(param, SPA_TYPE_OBJECT_Format))
|
||||
spa_debug_format(2, NULL, param);
|
||||
else
|
||||
spa_debug_pod(2, NULL, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pw_port_proxy_events port_events = {
|
||||
PW_VERSION_PORT_PROXY_EVENTS,
|
||||
.info = port_event_info,
|
||||
.param = port_event_param
|
||||
.param = event_param
|
||||
};
|
||||
|
||||
static int factory_event_info(void *object, const struct pw_factory_info *info)
|
||||
|
|
@ -861,7 +853,8 @@ static int device_event_info(void *object, const struct pw_device_info *info)
|
|||
|
||||
static const struct pw_device_proxy_events device_events = {
|
||||
PW_VERSION_DEVICE_PROXY_EVENTS,
|
||||
.info = device_event_info
|
||||
.info = device_event_info,
|
||||
.param = event_param
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -1183,7 +1176,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool do_node_params(struct data *data, const char *cmd, char *args, char **error)
|
||||
static bool do_enum_params(struct data *data, const char *cmd, char *args, char **error)
|
||||
{
|
||||
struct remote_data *rd = data->current;
|
||||
char *a[2];
|
||||
|
|
@ -1205,55 +1198,28 @@ static bool do_node_params(struct data *data, const char *cmd, char *args, char
|
|||
asprintf(error, "%s: unknown global %d", cmd, id);
|
||||
return false;
|
||||
}
|
||||
if (global->type != PW_TYPE_INTERFACE_Node) {
|
||||
asprintf(error, "object %d is not a node", atoi(a[0]));
|
||||
return false;
|
||||
}
|
||||
if (global->proxy == NULL) {
|
||||
if (!bind_global(rd, global, error))
|
||||
return false;
|
||||
}
|
||||
|
||||
pw_node_proxy_enum_params((struct pw_node_proxy*)global->proxy, 0,
|
||||
switch (global->type) {
|
||||
case PW_TYPE_INTERFACE_Node:
|
||||
pw_node_proxy_enum_params((struct pw_node_proxy*)global->proxy, 0,
|
||||
param_id, 0, 0, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_port_params(struct data *data, const char *cmd, char *args, char **error)
|
||||
{
|
||||
struct remote_data *rd = data->current;
|
||||
char *a[2];
|
||||
int n;
|
||||
uint32_t id, param_id;
|
||||
struct global *global;
|
||||
|
||||
n = pw_split_ip(args, WHITESPACE, 2, a);
|
||||
if (n < 2) {
|
||||
asprintf(error, "%s <object-id> <param-id>", cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
if (global->type != PW_TYPE_INTERFACE_Port) {
|
||||
asprintf(error, "object %d is not a port", atoi(a[0]));
|
||||
return false;
|
||||
}
|
||||
if (global->proxy == NULL) {
|
||||
if (!bind_global(rd, global, error))
|
||||
return false;
|
||||
}
|
||||
|
||||
pw_port_proxy_enum_params((struct pw_port_proxy*)global->proxy, 0,
|
||||
break;
|
||||
case PW_TYPE_INTERFACE_Port:
|
||||
pw_port_proxy_enum_params((struct pw_port_proxy*)global->proxy, 0,
|
||||
param_id, 0, 0, NULL);
|
||||
|
||||
break;
|
||||
case PW_TYPE_INTERFACE_Device:
|
||||
pw_device_proxy_enum_params((struct pw_device_proxy*)global->proxy, 0,
|
||||
param_id, 0, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
asprintf(error, "enum-params not implemented on object %d", atoi(a[0]));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,13 @@ static int add_param(struct proxy_data *data, uint32_t id, const struct spa_pod
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int 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, id, param);
|
||||
}
|
||||
|
||||
static void print_params(struct proxy_data *data, char mark)
|
||||
{
|
||||
struct param *p;
|
||||
|
|
@ -300,17 +307,10 @@ static int node_event_info(void *object, const struct pw_node_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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, id, param);
|
||||
}
|
||||
|
||||
static const struct pw_node_proxy_events node_events = {
|
||||
PW_VERSION_NODE_PROXY_EVENTS,
|
||||
.info = node_event_info,
|
||||
.param = node_event_param
|
||||
.param = event_param
|
||||
};
|
||||
|
||||
static void print_port(struct proxy_data *data)
|
||||
|
|
@ -369,17 +369,10 @@ static int port_event_info(void *object, const struct pw_port_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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, id, param);
|
||||
}
|
||||
|
||||
static const struct pw_port_proxy_events port_events = {
|
||||
PW_VERSION_PORT_PROXY_EVENTS,
|
||||
.info = port_event_info,
|
||||
.param = port_event_param
|
||||
.param = event_param
|
||||
};
|
||||
|
||||
static int factory_event_info(void *object, const struct pw_factory_info *info)
|
||||
|
|
@ -503,23 +496,22 @@ static const struct pw_link_proxy_events link_events = {
|
|||
.info = link_event_info
|
||||
};
|
||||
|
||||
static int device_event_info(void *object, const struct pw_device_info *info)
|
||||
static void print_device(struct proxy_data *data)
|
||||
{
|
||||
struct proxy_data *data = object;
|
||||
struct pw_device_info *info = data->info;
|
||||
bool print_all, print_mark;
|
||||
|
||||
print_all = true;
|
||||
if (data->info == NULL) {
|
||||
if (data->first) {
|
||||
printf("added:\n");
|
||||
print_mark = false;
|
||||
data->first = false;
|
||||
}
|
||||
else {
|
||||
printf("changed:\n");
|
||||
print_mark = true;
|
||||
}
|
||||
|
||||
info = data->info = pw_device_info_update(data->info, info);
|
||||
|
||||
printf("\tid: %d\n", data->id);
|
||||
printf("\tparent_id: %d\n", data->parent_id);
|
||||
printf("\tpermissions: %c%c%c\n", data->permissions & PW_PERM_R ? 'r' : '-',
|
||||
|
|
@ -528,14 +520,43 @@ static int device_event_info(void *object, const struct pw_device_info *info)
|
|||
printf("\ttype: %s (version %d)\n",
|
||||
spa_debug_type_find_name(pw_type_info(), data->type), data->version);
|
||||
if (print_all) {
|
||||
print_params(data, MARK_CHANGE(1));
|
||||
print_properties(info->props, MARK_CHANGE(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int device_event_info(void *object, const struct pw_device_info *info)
|
||||
{
|
||||
struct proxy_data *data = object;
|
||||
struct pw_device_info *old = data->info;
|
||||
uint32_t i;
|
||||
|
||||
if (info->change_mask & PW_DEVICE_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_device_proxy_enum_params((struct pw_device_proxy*)data->proxy,
|
||||
0, info->params[i].id, 0, 0, NULL);
|
||||
}
|
||||
add_pending(data);
|
||||
}
|
||||
|
||||
data->info = pw_device_info_update(data->info, info);
|
||||
|
||||
if (data->pending_seq == 0)
|
||||
data->print_func(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pw_device_proxy_events device_events = {
|
||||
PW_VERSION_DEVICE_PROXY_EVENTS,
|
||||
.info = device_event_info
|
||||
.info = device_event_info,
|
||||
.param = event_param
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -593,6 +614,7 @@ static int registry_event_global(void *data, uint32_t id, uint32_t parent_id,
|
|||
events = &device_events;
|
||||
client_version = PW_VERSION_DEVICE;
|
||||
destroy = (pw_destroy_t) pw_device_info_free;
|
||||
print_func = print_device;
|
||||
break;
|
||||
case PW_TYPE_INTERFACE_Factory:
|
||||
events = &factory_events;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue