mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
node: improve async handling
Remove the done and error callbacks. The error callback is in an error message. The done callback is replace with spa_pending. Make enum_params take a callback and data for the results. This allows us to push the results one after another to the app and avoids ownership issues of the passed data. We can then extend this to handle the async case by doing a _wait call with a spa_pending+callback+data that will be called when the _enum_params returns and async result. Add a sync method. All methods can now return SPA_RESULT_IS_ASYNC return values and you can use spa_node_wait() to register a callback when they complete with optional extra parameters. This makes it easier to sync and handle the reply. Make helper methods to simulate the sync enum_params behaviour for sync nodes. Let the transport generate the sequence number for pw_resource_sync() and pw_proxy_sync(). That way we don't need to keep track of numbers ourselves and we can match the reply to the request easily.
This commit is contained in:
parent
b743518f78
commit
7b12212eeb
67 changed files with 1894 additions and 1209 deletions
|
|
@ -146,6 +146,8 @@ struct node {
|
|||
|
||||
uint32_t n_params;
|
||||
struct spa_pod **params;
|
||||
|
||||
struct spa_list pending_list;
|
||||
};
|
||||
|
||||
struct impl {
|
||||
|
|
@ -163,6 +165,7 @@ struct impl {
|
|||
struct spa_hook resource_listener;
|
||||
|
||||
struct pw_array mems;
|
||||
uint32_t init_seq;
|
||||
|
||||
int fds[2];
|
||||
int other_fds[2];
|
||||
|
|
@ -352,34 +355,47 @@ static void mix_clear(struct node *this, struct mix *mix)
|
|||
}
|
||||
|
||||
static int impl_node_enum_params(struct spa_node *node,
|
||||
uint32_t id, uint32_t *index,
|
||||
uint32_t id, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter,
|
||||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
spa_result_func_t func, void *data)
|
||||
{
|
||||
struct node *this;
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
struct spa_result_node_enum_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
spa_return_val_if_fail(func != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
|
||||
result.next = start;
|
||||
|
||||
while (true) {
|
||||
struct spa_pod *param;
|
||||
|
||||
if (*index >= this->n_params)
|
||||
if (result.next >= this->n_params)
|
||||
return 0;
|
||||
|
||||
param = this->params[(*index)++];
|
||||
param = this->params[result.next++];
|
||||
|
||||
if (param == NULL || !spa_pod_is_object_id(param, id))
|
||||
continue;
|
||||
|
||||
if (spa_pod_filter(builder, result, param, filter) == 0)
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_pod_filter(&b, &result.param, param, filter) != 0)
|
||||
continue;
|
||||
|
||||
if ((res = func(data, count, 1, &result)) != 0)
|
||||
return res;
|
||||
|
||||
if (++count != num)
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
|
||||
|
|
@ -392,7 +408,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
|
||||
if (this->resource == NULL)
|
||||
return 0;
|
||||
return -EIO;
|
||||
|
||||
return pw_client_node_resource_set_param(this->resource, id, flags, param);
|
||||
}
|
||||
|
|
@ -410,9 +426,12 @@ static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size
|
|||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
impl = this->impl;
|
||||
|
||||
if (this->resource == NULL)
|
||||
if (impl->this.flags & 1)
|
||||
return 0;
|
||||
|
||||
if (this->resource == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (data) {
|
||||
if ((mem = pw_memblock_find(data)) == NULL)
|
||||
return -EINVAL;
|
||||
|
|
@ -451,7 +470,7 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
|
||||
if (this->resource == NULL)
|
||||
return 0;
|
||||
return -EIO;
|
||||
|
||||
pw_log_debug("client-node %p: send command %d", node, SPA_COMMAND_TYPE(command));
|
||||
return pw_client_node_resource_command(this->resource, command);
|
||||
|
|
@ -460,9 +479,9 @@ 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, port->direction, port->id, &port->info);
|
||||
}
|
||||
if (this->callbacks && this->callbacks->port_info)
|
||||
this->callbacks->port_info(this->callbacks_data,
|
||||
port->direction, port->id, &port->info);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -471,6 +490,7 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
void *data)
|
||||
{
|
||||
struct node *this;
|
||||
int res = 0;
|
||||
uint32_t i;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
|
@ -479,6 +499,8 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
this->callbacks = callbacks;
|
||||
this->callbacks_data = data;
|
||||
|
||||
pw_log_debug("client-node %p: callbacks %p", this, callbacks);
|
||||
|
||||
for (i = 0; i < MAX_INPUTS; i++) {
|
||||
if (this->in_ports[i])
|
||||
emit_port_info(this, this->in_ports[i]);
|
||||
|
|
@ -487,17 +509,50 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
if (this->out_ports[i])
|
||||
emit_port_info(this, this->out_ports[i]);
|
||||
}
|
||||
return 0;
|
||||
if (callbacks && this->resource)
|
||||
res = pw_resource_sync(this->resource);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_sync(struct spa_node *node, uint32_t seq)
|
||||
impl_node_sync(struct spa_node *node)
|
||||
{
|
||||
struct node *this;
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
pw_log_debug("client-node %p: sync %u", node, seq);
|
||||
return pw_resource_sync(this->resource, seq);
|
||||
pw_log_debug("client-node %p: sync", node);
|
||||
if (this->resource == NULL)
|
||||
return -EIO;
|
||||
return pw_resource_sync(this->resource);
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_wait(struct spa_node *node, int res, struct spa_pending *pending,
|
||||
spa_result_func_t func, void *data)
|
||||
{
|
||||
struct node *this;
|
||||
int seq;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(func != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(pending != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
|
||||
pw_log_debug("client-node %p: wait %d %d", node, res, SPA_RESULT_ASYNC_SEQ(res));
|
||||
if (this->resource == NULL)
|
||||
return -EIO;
|
||||
|
||||
seq = pw_resource_sync(this->resource);
|
||||
|
||||
pending->seq = seq;
|
||||
pending->res = res;
|
||||
pending->func = func;
|
||||
pending->data = data;
|
||||
spa_list_append(&this->pending_list, &pending->link);
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -520,7 +575,7 @@ do_update_port(struct node *this,
|
|||
port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod *));
|
||||
|
||||
for (i = 0; i < port->n_params; i++) {
|
||||
port->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
|
||||
port->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
|
||||
|
||||
if (port->params[i] && spa_pod_is_object_id(port->params[i], SPA_PARAM_Format))
|
||||
port->have_format = true;
|
||||
|
|
@ -608,17 +663,21 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
|
|||
static int
|
||||
impl_node_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
uint32_t id, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter,
|
||||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
spa_result_func_t func, void *data)
|
||||
{
|
||||
struct node *this;
|
||||
struct port *port;
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
struct spa_result_node_enum_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
spa_return_val_if_fail(func != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
|
||||
|
|
@ -629,21 +688,30 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
pw_log_debug("client-node %p: port %d.%d", this,
|
||||
direction, port_id);
|
||||
|
||||
result.next = start;
|
||||
|
||||
while (true) {
|
||||
struct spa_pod *param;
|
||||
|
||||
if (*index >= port->n_params)
|
||||
if (result.next >= port->n_params)
|
||||
return 0;
|
||||
|
||||
param = port->params[(*index)++];
|
||||
param = port->params[result.next++];
|
||||
|
||||
if (param == NULL || !spa_pod_is_object_id(param, id))
|
||||
continue;
|
||||
|
||||
if (spa_pod_filter(builder, result, param, filter) == 0)
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
continue;
|
||||
|
||||
if ((res = func(data, count, 1, &result)) != 0)
|
||||
return res;
|
||||
|
||||
if (++count != num)
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -661,7 +729,7 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (this->resource == NULL)
|
||||
return 0;
|
||||
return -EIO;
|
||||
|
||||
pw_log_debug("node %p: port %d.%d add param %s %d", this,
|
||||
direction, port_id,
|
||||
|
|
@ -692,7 +760,7 @@ static int do_port_set_io(struct impl *impl,
|
|||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (this->resource == NULL)
|
||||
return 0;
|
||||
return -EIO;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
|
|
@ -781,7 +849,7 @@ do_port_use_buffers(struct impl *impl,
|
|||
mix->n_buffers = n_buffers;
|
||||
|
||||
if (this->resource == NULL)
|
||||
return 0;
|
||||
return -EIO;
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
struct buffer *b = &mix->buffers[i];
|
||||
|
|
@ -963,7 +1031,7 @@ client_node_update(void *data,
|
|||
this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod *));
|
||||
|
||||
for (i = 0; i < this->n_params; i++)
|
||||
this->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
|
||||
this->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
|
||||
}
|
||||
if (change_mask & PW_CLIENT_NODE_UPDATE_PROPS) {
|
||||
pw_node_update_properties(impl->this.node, props);
|
||||
|
|
@ -1068,6 +1136,7 @@ static const struct spa_node impl_node = {
|
|||
NULL,
|
||||
.set_callbacks = impl_node_set_callbacks,
|
||||
.sync = impl_node_sync,
|
||||
.wait = impl_node_wait,
|
||||
.enum_params = impl_node_enum_params,
|
||||
.set_param = impl_node_set_param,
|
||||
.set_io = impl_node_set_io,
|
||||
|
|
@ -1109,6 +1178,7 @@ node_init(struct node *this,
|
|||
}
|
||||
|
||||
this->node = impl_node;
|
||||
spa_list_init(&this->pending_list);
|
||||
|
||||
init_ios(this->ios);
|
||||
|
||||
|
|
@ -1174,18 +1244,24 @@ static void client_node_resource_error(void *data, int res, const char *message)
|
|||
struct impl *impl = data;
|
||||
struct node *this = &impl->node;
|
||||
pw_log_error("client-node %p: error %d: %s", this, res, message);
|
||||
if (this->callbacks && this->callbacks->error)
|
||||
this->callbacks->error(this->callbacks_data, res, message);
|
||||
}
|
||||
|
||||
static void client_node_resource_done(void *data, uint32_t seq)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct node *this = &impl->node;
|
||||
struct spa_pending *p, *t;
|
||||
|
||||
pw_log_debug("client-node %p: done %d", this, seq);
|
||||
if (this->callbacks && this->callbacks->done)
|
||||
this->callbacks->done(this->callbacks_data, SPA_RESULT_ASYNC_SEQ(seq));
|
||||
|
||||
spa_list_for_each_safe(p, t, &this->pending_list, link) {
|
||||
pw_log_debug("client-node %p: check %d", this, p->seq);
|
||||
if (p->seq == (int) seq) {
|
||||
pw_log_debug("client-node %p: found %d", this, p->res);
|
||||
p->func(p->data, p->res, 0, NULL);
|
||||
spa_list_remove(&p->link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pw_client_node_registered(struct pw_client_node *this, uint32_t node_id)
|
||||
|
|
@ -1318,14 +1394,13 @@ static const struct pw_port_implementation port_impl = {
|
|||
static int
|
||||
impl_mix_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
uint32_t id, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter,
|
||||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
spa_result_func_t func, void *data)
|
||||
{
|
||||
struct port *port = SPA_CONTAINER_OF(node, struct port, mix_node);
|
||||
return impl_node_port_enum_params(&port->node->node, direction, port->id,
|
||||
id, index, filter, result, builder);
|
||||
id, start, num, filter, func, data);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1597,6 +1672,8 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
|
|||
support = pw_core_get_support(impl->core, &n_support);
|
||||
node_init(&impl->node, NULL, support, n_support);
|
||||
impl->node.impl = impl;
|
||||
impl->node.resource = resource;
|
||||
this->flags = do_register ? 0 : 1;
|
||||
|
||||
pw_map_init(&impl->io_map, 64, 64);
|
||||
pw_array_init(&impl->mems, 64);
|
||||
|
|
@ -1610,7 +1687,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
|
|||
pw_resource_get_client(this->resource),
|
||||
parent,
|
||||
name,
|
||||
PW_SPA_NODE_FLAG_ASYNC |
|
||||
(do_register ? 0 : PW_SPA_NODE_FLAG_NO_REGISTER),
|
||||
&impl->node.node,
|
||||
NULL,
|
||||
|
|
@ -1619,6 +1695,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
|
|||
goto error_no_node;
|
||||
|
||||
this->node->remote = true;
|
||||
this->flags = 0;
|
||||
|
||||
spa_graph_node_set_callbacks(&this->node->rt.root, &root_impl, this);
|
||||
|
||||
|
|
@ -1630,13 +1707,10 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
|
|||
&client_node_methods,
|
||||
impl);
|
||||
|
||||
impl->node.resource = this->resource;
|
||||
this->node->port_user_data_size = sizeof(struct port);
|
||||
|
||||
pw_node_add_listener(this->node, &impl->node_listener, &node_events, impl);
|
||||
|
||||
pw_resource_sync(this->resource, 0);
|
||||
|
||||
return this;
|
||||
|
||||
error_no_node:
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct pw_client_node {
|
|||
|
||||
struct pw_resource *resource;
|
||||
struct pw_global *parent;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct pw_client_node *
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <sys/eventfd.h>
|
||||
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/utils.h>
|
||||
#include <spa/buffer/alloc.h>
|
||||
#include <spa/pod/parser.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
|
@ -68,8 +69,6 @@ struct node {
|
|||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
|
||||
uint32_t seq;
|
||||
};
|
||||
|
||||
struct impl {
|
||||
|
|
@ -83,7 +82,6 @@ struct impl {
|
|||
|
||||
struct spa_hook node_listener;
|
||||
struct spa_hook client_node_listener;
|
||||
struct spa_hook resource_listener;
|
||||
|
||||
enum spa_direction direction;
|
||||
|
||||
|
|
@ -110,24 +108,28 @@ struct impl {
|
|||
/** \endcond */
|
||||
|
||||
static int impl_node_enum_params(struct spa_node *node,
|
||||
uint32_t id, uint32_t *index,
|
||||
uint32_t id, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter,
|
||||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
spa_result_func_t func, void *data)
|
||||
{
|
||||
struct node *this;
|
||||
struct impl *impl;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_result_node_enum_params result;
|
||||
uint32_t count = 0;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
spa_return_val_if_fail(func != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
impl = this->impl;
|
||||
|
||||
result.next = start;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
|
|
@ -138,10 +140,10 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
SPA_PARAM_EnumFormat,
|
||||
SPA_PARAM_Format };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
if (result.next < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
|
|
@ -149,8 +151,7 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
case SPA_PARAM_Props:
|
||||
if (impl->adapter != impl->cnode) {
|
||||
return spa_node_enum_params(impl->adapter,
|
||||
id, index,
|
||||
filter, result, builder);
|
||||
id, start, num, filter, func, data);
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
|
@ -158,18 +159,24 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
case SPA_PARAM_Format:
|
||||
return spa_node_port_enum_params(impl->cnode,
|
||||
impl->direction, 0,
|
||||
id, index,
|
||||
filter, result, builder);
|
||||
id, start, num,
|
||||
filter, func, data);
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
(*index)++;
|
||||
result.next++;
|
||||
|
||||
if (spa_pod_filter(builder, result, param, filter) < 0)
|
||||
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
|
||||
goto next;
|
||||
|
||||
return 1;
|
||||
if ((res = func(data, count, 1, &result)) != 0)
|
||||
return res;
|
||||
|
||||
if (++count != num)
|
||||
goto next;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void try_link_controls(struct impl *impl)
|
||||
|
|
@ -323,11 +330,11 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
if (this->callbacks && impl->adapter && impl->adapter != impl->cnode)
|
||||
spa_node_set_callbacks(impl->adapter, &adapter_node_callbacks, impl);
|
||||
|
||||
return 0;
|
||||
return spa_node_sync(impl->cnode);
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_sync(struct spa_node *node, uint32_t seq)
|
||||
impl_node_sync(struct spa_node *node)
|
||||
{
|
||||
struct node *this;
|
||||
struct impl *impl;
|
||||
|
|
@ -337,7 +344,22 @@ impl_node_sync(struct spa_node *node, uint32_t seq)
|
|||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
impl = this->impl;
|
||||
|
||||
return spa_node_sync(impl->cnode, seq);
|
||||
return spa_node_sync(impl->cnode);
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_wait(struct spa_node *node, int seq, struct spa_pending *pending,
|
||||
spa_result_func_t func, 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;
|
||||
|
||||
return spa_node_wait(impl->cnode, seq, pending, func, data);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -389,17 +411,16 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
|
|||
static int
|
||||
impl_node_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
uint32_t id, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter,
|
||||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
spa_result_func_t func, void *data)
|
||||
{
|
||||
struct node *this;
|
||||
struct impl *impl;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||
spa_return_val_if_fail(func != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct node, node);
|
||||
impl = this->impl;
|
||||
|
|
@ -408,7 +429,7 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return -EINVAL;
|
||||
|
||||
return spa_node_port_enum_params(impl->adapter, direction, port_id, id,
|
||||
index, filter, result, builder);
|
||||
start, num, filter, func, data);
|
||||
}
|
||||
|
||||
static int debug_params(struct impl *impl, struct spa_node *node,
|
||||
|
|
@ -426,11 +447,11 @@ static int debug_params(struct impl *impl, struct spa_node *node,
|
|||
state = 0;
|
||||
while (true) {
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
res = spa_node_port_enum_params(node,
|
||||
res = spa_node_port_enum_params_sync(node,
|
||||
direction, port_id,
|
||||
id, &state,
|
||||
NULL, ¶m, &b);
|
||||
if (res <= 0) {
|
||||
if (res != 1) {
|
||||
if (res < 0)
|
||||
spa_log_error(this->log, " error: %s", spa_strerror(res));
|
||||
break;
|
||||
|
|
@ -460,11 +481,11 @@ static int negotiate_format(struct impl *impl)
|
|||
spa_log_debug(this->log, NAME "%p: negiotiate", impl);
|
||||
|
||||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(impl->adapter_mix,
|
||||
if ((res = spa_node_port_enum_params_sync(impl->adapter_mix,
|
||||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
NULL, &format, &b)) <= 0) {
|
||||
NULL, &format, &b)) != 1) {
|
||||
debug_params(impl, impl->adapter_mix,
|
||||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
|
|
@ -473,10 +494,10 @@ static int negotiate_format(struct impl *impl)
|
|||
}
|
||||
|
||||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(impl->cnode,
|
||||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
format, &format, &b)) <= 0) {
|
||||
format, &format, &b)) != 1) {
|
||||
debug_params(impl, impl->cnode, impl->direction, 0,
|
||||
SPA_PARAM_EnumFormat, format);
|
||||
return -ENOTSUP;
|
||||
|
|
@ -524,22 +545,22 @@ static int negotiate_buffers(struct impl *impl)
|
|||
return 0;
|
||||
|
||||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(impl->adapter_mix,
|
||||
if ((res = spa_node_port_enum_params_sync(impl->adapter_mix,
|
||||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
SPA_PARAM_Buffers, &state,
|
||||
param, ¶m, &b)) <= 0) {
|
||||
param, ¶m, &b)) < 0) {
|
||||
debug_params(impl, impl->adapter_mix,
|
||||
SPA_DIRECTION_REVERSE(impl->direction),
|
||||
impl->adapter_mix_port,
|
||||
SPA_PARAM_Buffers, param);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (res == 0)
|
||||
if (res != 1)
|
||||
param = NULL;
|
||||
|
||||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(impl->cnode,
|
||||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
SPA_PARAM_Buffers, &state,
|
||||
param, ¶m, &b)) < 0) {
|
||||
|
|
@ -833,6 +854,7 @@ static const struct spa_node impl_node = {
|
|||
SPA_VERSION_NODE,
|
||||
.set_callbacks = impl_node_set_callbacks,
|
||||
.sync = impl_node_sync,
|
||||
.wait = impl_node_wait,
|
||||
.enum_params = impl_node_enum_params,
|
||||
.set_param = impl_node_set_param,
|
||||
.set_io = impl_node_set_io,
|
||||
|
|
@ -861,10 +883,7 @@ node_init(struct node *this,
|
|||
this->log = support[i].data;
|
||||
}
|
||||
this->node = impl_node;
|
||||
|
||||
this->seq = 1;
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC(this->seq++);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_port_info(void *data, struct pw_port *port)
|
||||
|
|
@ -957,10 +976,10 @@ static void client_node_initialized(void *data)
|
|||
|
||||
state = 0;
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if ((res = spa_node_port_enum_params(impl->cnode,
|
||||
if ((res = spa_node_port_enum_params_sync(impl->cnode,
|
||||
impl->direction, 0,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
NULL, &format, &b)) <= 0) {
|
||||
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;
|
||||
|
|
@ -1049,15 +1068,6 @@ static void client_node_initialized(void *data)
|
|||
|
||||
items[0] = SPA_DICT_ITEM_INIT("media.class", media_class);
|
||||
pw_node_update_properties(impl->this.node, &SPA_DICT_INIT(items, 1));
|
||||
|
||||
pw_node_register(impl->this.node,
|
||||
pw_resource_get_client(impl->client_node->resource),
|
||||
impl->client_node->parent,
|
||||
NULL);
|
||||
|
||||
pw_log_debug("client-stream %p: activating", &impl->this);
|
||||
|
||||
pw_node_set_active(impl->this.node, true);
|
||||
}
|
||||
|
||||
static void cleanup(struct impl *impl)
|
||||
|
|
@ -1087,15 +1097,6 @@ static void client_node_destroy(void *data)
|
|||
cleanup(impl);
|
||||
}
|
||||
|
||||
static void client_node_async_complete(void *data, uint32_t seq, int res)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct node *node = &impl->node;
|
||||
|
||||
pw_log_debug("client-stream %p: async complete %d %d", &impl->this, seq, res);
|
||||
node->callbacks->done(node->callbacks_data, seq);
|
||||
}
|
||||
|
||||
static void client_node_active_changed(void *data, bool active)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
|
|
@ -1118,7 +1119,6 @@ static const struct pw_node_events client_node_events = {
|
|||
PW_VERSION_NODE_EVENTS,
|
||||
.destroy = client_node_destroy,
|
||||
.initialized = client_node_initialized,
|
||||
.async_complete = client_node_async_complete,
|
||||
.active_changed = client_node_active_changed,
|
||||
.info_changed = client_node_info_changed,
|
||||
};
|
||||
|
|
@ -1225,7 +1225,7 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
|
|||
client,
|
||||
parent,
|
||||
name,
|
||||
PW_SPA_NODE_FLAG_ASYNC,
|
||||
PW_SPA_NODE_FLAG_ACTIVATE,
|
||||
&impl->node.node,
|
||||
NULL,
|
||||
properties, 0);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ client_node_marshal_update(void *object,
|
|||
struct spa_pod_frame f;
|
||||
uint32_t i;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE);
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b,
|
||||
|
|
@ -93,7 +93,7 @@ client_node_marshal_port_update(void *object,
|
|||
struct spa_pod_frame f[2];
|
||||
uint32_t i, n_items;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE);
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f[0]);
|
||||
spa_pod_builder_add(b,
|
||||
|
|
@ -134,7 +134,7 @@ static int client_node_marshal_set_active(void *object, bool active)
|
|||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE);
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Bool(active));
|
||||
|
|
@ -147,7 +147,7 @@ static int client_node_marshal_event_method(void *object, struct spa_event *even
|
|||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT);
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Pod(event));
|
||||
|
|
@ -472,7 +472,7 @@ client_node_marshal_add_mem(void *object,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Int(mem_id),
|
||||
|
|
@ -488,7 +488,7 @@ static int client_node_marshal_transport(void *object, uint32_t node_id, int rea
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Int(node_id),
|
||||
|
|
@ -505,7 +505,7 @@ client_node_marshal_set_param(void *object, uint32_t id, uint32_t flags,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Id(id),
|
||||
|
|
@ -520,7 +520,7 @@ static int client_node_marshal_event_event(void *object, const struct spa_event
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Pod(event));
|
||||
|
|
@ -534,7 +534,7 @@ client_node_marshal_command(void *object, const struct spa_command *command)
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Pod(command));
|
||||
|
|
@ -551,7 +551,7 @@ client_node_marshal_add_port(void *object,
|
|||
struct spa_pod_builder *b;
|
||||
struct spa_pod_frame f;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b,
|
||||
|
|
@ -570,7 +570,7 @@ client_node_marshal_remove_port(void *object,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Int(direction),
|
||||
|
|
@ -590,7 +590,7 @@ client_node_marshal_port_set_param(void *object,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Int(direction),
|
||||
|
|
@ -614,7 +614,7 @@ client_node_marshal_port_use_buffers(void *object,
|
|||
struct spa_pod_frame f;
|
||||
uint32_t i, j;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b,
|
||||
|
|
@ -668,7 +668,7 @@ client_node_marshal_port_set_io(void *object,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Int(direction),
|
||||
|
|
@ -693,7 +693,7 @@ client_node_marshal_set_activation(void *object,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Int(node_id),
|
||||
|
|
@ -715,7 +715,7 @@ client_node_marshal_set_io(void *object,
|
|||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO, NULL);
|
||||
spa_pod_builder_add_struct(b,
|
||||
SPA_POD_Id(id),
|
||||
SPA_POD_Int(memid),
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include <spa/pod/parser.h>
|
||||
#include <spa/node/utils.h>
|
||||
#include <spa/debug/types.h>
|
||||
|
||||
#include "pipewire/pipewire.h"
|
||||
|
|
@ -413,10 +414,10 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
|
|||
struct spa_pod *param;
|
||||
|
||||
spa_pod_builder_init(&b, buf, sizeof(buf));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
if (spa_node_port_enum_params_sync(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
SPA_PARAM_List, &idx1,
|
||||
NULL, ¶m, &b) <= 0)
|
||||
NULL, ¶m, &b) != 1)
|
||||
break;
|
||||
|
||||
spa_pod_parse_object(param,
|
||||
|
|
@ -424,18 +425,18 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
|
|||
SPA_PARAM_LIST_id, SPA_POD_Id(&id));
|
||||
|
||||
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
|
||||
params[n_params++] = pw_spa_pod_copy(param);
|
||||
params[n_params++] = spa_pod_copy(param);
|
||||
|
||||
for (idx2 = 0;;) {
|
||||
spa_pod_builder_init(&b, buf, sizeof(buf));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
if (spa_node_port_enum_params_sync(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
id, &idx2,
|
||||
NULL, ¶m, &b) <= 0)
|
||||
NULL, ¶m, &b) != 1)
|
||||
break;
|
||||
|
||||
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
|
||||
params[n_params++] = pw_spa_pod_copy(param);
|
||||
params[n_params++] = spa_pod_copy(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue