client-node: add more generic set_io method

Replace the set_position method with set_io that allows us to share
other types of state with the client.
This commit is contained in:
Wim Taymans 2018-07-12 15:33:07 +02:00
parent 5a3eee9cac
commit cc542935ea
5 changed files with 127 additions and 81 deletions

View file

@ -44,6 +44,8 @@ struct pw_client_node_buffer {
struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */ struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */
}; };
#define PW_TYPE_CLIENT_NODE_IO__Position SPA_TYPE_IO_BASE "ClientNode:Position"
struct pw_client_node_position { struct pw_client_node_position {
#define PW_VERSION_CLIENT_NODE_POSITION 0 #define PW_VERSION_CLIENT_NODE_POSITION 0
uint32_t version; uint32_t version;
@ -184,15 +186,15 @@ pw_client_node_proxy_destroy(struct pw_client_node_proxy *p)
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 0 #define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 0
#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 1 #define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 1
#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 2 #define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 2
#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 3 #define PW_CLIENT_NODE_PROXY_EVENT_SET_IO 3
#define PW_CLIENT_NODE_PROXY_EVENT_COMMAND 4 #define PW_CLIENT_NODE_PROXY_EVENT_EVENT 4
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 5 #define PW_CLIENT_NODE_PROXY_EVENT_COMMAND 5
#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 6 #define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 6
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM 7 #define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 7
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS 8 #define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM 8
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 9 #define PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS 9
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO 10 #define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 10
#define PW_CLIENT_NODE_PROXY_EVENT_SET_POSITION 11 #define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO 11
#define PW_CLIENT_NODE_PROXY_EVENT_NUM 12 #define PW_CLIENT_NODE_PROXY_EVENT_NUM 12
/** \ref pw_client_node events */ /** \ref pw_client_node events */
@ -248,6 +250,22 @@ struct pw_client_node_proxy_events {
void (*set_param) (void *object, uint32_t seq, void (*set_param) (void *object, uint32_t seq,
uint32_t id, uint32_t flags, uint32_t id, uint32_t flags,
const struct spa_pod *param); const struct spa_pod *param);
/**
* Configure an IO area for the client
*
* IO areas are identified with an id and are used to
* exchange state between client and server
*
* \param id the id of the io area
* \param mem_id the id of the memory to use
* \param offset offset of io area in memory
* \param size size of the io area
*/
void (*set_io) (void *object,
uint32_t id,
uint32_t mem_id,
uint32_t offset,
uint32_t size);
/** /**
* Receive an event from the client node * Receive an event from the client node
* \param event the received event */ * \param event the received event */
@ -350,11 +368,6 @@ struct pw_client_node_proxy_events {
uint32_t mem_id, uint32_t mem_id,
uint32_t offset, uint32_t offset,
uint32_t size); uint32_t size);
void (*set_position) (void *object,
uint32_t mem_id,
uint32_t offset,
uint32_t size);
}; };
static inline void static inline void
@ -372,6 +385,8 @@ pw_client_node_proxy_add_listener(struct pw_client_node_proxy *p,
pw_resource_notify(r,struct pw_client_node_proxy_events,transport,__VA_ARGS__) pw_resource_notify(r,struct pw_client_node_proxy_events,transport,__VA_ARGS__)
#define pw_client_node_resource_set_param(r,...) \ #define pw_client_node_resource_set_param(r,...) \
pw_resource_notify(r,struct pw_client_node_proxy_events,set_param,__VA_ARGS__) pw_resource_notify(r,struct pw_client_node_proxy_events,set_param,__VA_ARGS__)
#define pw_client_node_resource_set_io(r,...) \
pw_resource_notify(r,struct pw_client_node_proxy_events,set_io,__VA_ARGS__)
#define pw_client_node_resource_event(r,...) \ #define pw_client_node_resource_event(r,...) \
pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__) pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__)
#define pw_client_node_resource_command(r,...) \ #define pw_client_node_resource_command(r,...) \
@ -388,8 +403,6 @@ pw_client_node_proxy_add_listener(struct pw_client_node_proxy *p,
pw_resource_notify(r,struct pw_client_node_proxy_events,port_command,__VA_ARGS__) pw_resource_notify(r,struct pw_client_node_proxy_events,port_command,__VA_ARGS__)
#define pw_client_node_resource_port_set_io(r,...) \ #define pw_client_node_resource_port_set_io(r,...) \
pw_resource_notify(r,struct pw_client_node_proxy_events,port_set_io,__VA_ARGS__) pw_resource_notify(r,struct pw_client_node_proxy_events,port_set_io,__VA_ARGS__)
#define pw_client_node_resource_set_position(r,...) \
pw_resource_notify(r,struct pw_client_node_proxy_events,set_position,__VA_ARGS__)
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View file

@ -64,6 +64,15 @@
#define CHECK_PORT_BUFFER(this,b,p) (b < p->n_buffers) #define CHECK_PORT_BUFFER(this,b,p) (b < p->n_buffers)
struct type {
uint32_t client_node_position;
};
static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->client_node_position = spa_type_map_get_id(map, PW_TYPE_CLIENT_NODE_IO__Position);
}
struct mem { struct mem {
uint32_t id; uint32_t id;
int ref; int ref;
@ -135,6 +144,8 @@ struct node {
struct impl { struct impl {
struct pw_client_node this; struct pw_client_node this;
struct type type;
struct pw_core *core; struct pw_core *core;
struct pw_type *t; struct pw_type *t;
@ -323,7 +334,6 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
{ {
struct node *this; struct node *this;
int res = 0; int res = 0;
struct pw_type *t;
if (node == NULL || command == NULL) if (node == NULL || command == NULL)
return -EINVAL; return -EINVAL;
@ -333,8 +343,6 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
if (this->resource == NULL) if (this->resource == NULL)
return 0; return 0;
t = this->impl->t;
pw_client_node_resource_command(this->resource, this->seq, command); pw_client_node_resource_command(this->resource, this->seq, command);
res = SPA_RESULT_RETURN_ASYNC(this->seq++); res = SPA_RESULT_RETURN_ASYNC(this->seq++);
@ -1202,7 +1210,8 @@ static void node_initialized(void *data)
m = ensure_mem(impl, impl->io_areas->fd, t->data.MemFd, impl->io_areas->flags); m = ensure_mem(impl, impl->io_areas->fd, t->data.MemFd, impl->io_areas->flags);
pw_log_debug("client-node %p: io areas %p", node, impl->io_areas->ptr); pw_log_debug("client-node %p: io areas %p", node, impl->io_areas->ptr);
pw_client_node_resource_set_position(this->resource, pw_client_node_resource_set_io(this->resource,
impl->type.client_node_position,
m->id, m->id,
area_size, area_size,
sizeof(struct pw_client_node_position)); sizeof(struct pw_client_node_position));
@ -1358,8 +1367,9 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
impl->fds[0] = impl->fds[1] = -1; impl->fds[0] = impl->fds[1] = -1;
pw_log_debug("client-node %p: new", impl); pw_log_debug("client-node %p: new", impl);
support = pw_core_get_support(impl->core, &n_support); init_type(&impl->type, impl->t->map);
support = pw_core_get_support(impl->core, &n_support);
node_init(&impl->node, NULL, support, n_support); node_init(&impl->node, NULL, support, n_support);
impl->node.impl = impl; impl->node.impl = impl;

View file

@ -440,22 +440,23 @@ static int client_node_demarshal_port_set_io(void *object, void *data, size_t si
return 0; return 0;
} }
static int client_node_demarshal_set_position(void *object, void *data, size_t size) static int client_node_demarshal_set_io(void *object, void *data, size_t size)
{ {
struct pw_proxy *proxy = object; struct pw_proxy *proxy = object;
struct spa_pod_parser prs; struct spa_pod_parser prs;
uint32_t memid, off, sz; uint32_t id, memid, off, sz;
spa_pod_parser_init(&prs, data, size, 0); spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs, if (spa_pod_parser_get(&prs,
"[" "["
"I", &id,
"i", &memid, "i", &memid,
"i", &off, "i", &off,
"i", &sz, NULL) < 0) "i", &sz, NULL) < 0)
return -EINVAL; return -EINVAL;
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_position, pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_io,
memid, off, sz); id, memid, off, sz);
return 0; return 0;
} }
@ -699,7 +700,8 @@ client_node_marshal_port_set_io(void *object,
} }
static void static void
client_node_marshal_set_position(void *object, client_node_marshal_set_io(void *object,
uint32_t id,
uint32_t memid, uint32_t memid,
uint32_t offset, uint32_t offset,
uint32_t size) uint32_t size)
@ -707,8 +709,9 @@ client_node_marshal_set_position(void *object,
struct pw_resource *resource = object; struct pw_resource *resource = object;
struct spa_pod_builder *b; struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_POSITION); b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO);
spa_pod_builder_struct(b, spa_pod_builder_struct(b,
"I", id,
"i", memid, "i", memid,
"i", offset, "i", offset,
"i", size); "i", size);
@ -908,6 +911,7 @@ static const struct pw_client_node_proxy_events pw_protocol_native_client_node_e
&client_node_marshal_add_mem, &client_node_marshal_add_mem,
&client_node_marshal_transport, &client_node_marshal_transport,
&client_node_marshal_set_param, &client_node_marshal_set_param,
&client_node_marshal_set_io,
&client_node_marshal_event_event, &client_node_marshal_event_event,
&client_node_marshal_command, &client_node_marshal_command,
&client_node_marshal_add_port, &client_node_marshal_add_port,
@ -916,13 +920,13 @@ static const struct pw_client_node_proxy_events pw_protocol_native_client_node_e
&client_node_marshal_port_use_buffers, &client_node_marshal_port_use_buffers,
&client_node_marshal_port_command, &client_node_marshal_port_command,
&client_node_marshal_port_set_io, &client_node_marshal_port_set_io,
&client_node_marshal_set_position,
}; };
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_event_demarshal[] = { static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_event_demarshal[] = {
{ &client_node_demarshal_add_mem, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_add_mem, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_transport, 0 }, { &client_node_demarshal_transport, 0 },
{ &client_node_demarshal_set_param, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_set_param, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_set_io, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_event_event, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_event_event, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_command, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_command, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_add_port, 0 }, { &client_node_demarshal_add_port, 0 },
@ -931,7 +935,6 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_
{ &client_node_demarshal_port_use_buffers, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_port_use_buffers, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_port_command, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_port_command, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_port_set_io, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_port_set_io, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_set_position, PW_PROTOCOL_NATIVE_REMAP },
}; };
static const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = { static const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = {

View file

@ -42,6 +42,16 @@
#define MAX_MIX 4096 #define MAX_MIX 4096
/** \cond */ /** \cond */
struct type {
uint32_t client_node_position;
};
static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->client_node_position = spa_type_map_get_id(map, PW_TYPE_CLIENT_NODE_IO__Position);
}
struct remote { struct remote {
struct pw_remote this; struct pw_remote this;
uint32_t type_client_node; uint32_t type_client_node;
@ -88,6 +98,8 @@ struct node_data {
struct pw_core *core; struct pw_core *core;
struct pw_type *t; struct pw_type *t;
struct type type;
int rtwritefd; int rtwritefd;
struct spa_source *rtsocket_source; struct spa_source *rtsocket_source;
@ -833,6 +845,58 @@ client_node_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags,
pw_log_warn("set param not implemented"); pw_log_warn("set param not implemented");
} }
static void
client_node_set_io(void *object,
uint32_t id,
uint32_t memid,
uint32_t offset,
uint32_t size)
{
struct pw_proxy *proxy = object;
struct node_data *data = proxy->user_data;
struct pw_type *t = data->t;
struct mem *m;
void *ptr;
if (memid == SPA_ID_INVALID) {
ptr = NULL;
size = 0;
}
else {
m = find_mem(data, memid);
if (m == NULL) {
pw_log_warn("unknown memory id %u", memid);
return;
}
ptr = mem_map(data, &m->map, m->fd,
PROT_READ|PROT_WRITE, offset, size);
if (ptr == NULL)
return;
m->ref++;
}
pw_log_debug("node %p: set io %s %p", proxy,
spa_type_map_get_type(t->map, id), ptr);
if (id == data->type.client_node_position) {
if (ptr == NULL && data->position) {
m = find_mem_ptr(data, data->position);
if (m && --m->ref == 0)
clear_mem(data, m);
}
data->position = ptr;
if (ptr)
data->node->rt.quantum = SPA_MEMBER(ptr,
sizeof(struct pw_client_node_position), void);
else
data->node->rt.quantum = NULL;
}
else {
pw_log_warn("unknown io id %u", id);
}
}
static void client_node_event(void *object, const struct spa_event *event) static void client_node_event(void *object, const struct spa_event *event)
{ {
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event)); pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
@ -1184,53 +1248,12 @@ client_node_port_set_io(void *object,
} }
} }
static void
client_node_set_position(void *object,
uint32_t memid,
uint32_t offset,
uint32_t size)
{
struct pw_proxy *proxy = object;
struct node_data *data = proxy->user_data;
struct mem *m;
void *ptr;
if (memid == SPA_ID_INVALID) {
ptr = NULL;
size = 0;
}
else {
m = find_mem(data, memid);
if (m == NULL) {
pw_log_warn("unknown memory id %u", memid);
return;
}
ptr = mem_map(data, &m->map, m->fd,
PROT_READ|PROT_WRITE, offset, size);
if (ptr == NULL)
return;
m->ref++;
}
pw_log_debug("node %p: set position %p", proxy, ptr);
if (ptr == NULL && data->position) {
m = find_mem_ptr(data, data->position);
if (m && --m->ref == 0)
clear_mem(data, m);
}
data->position = ptr;
if (ptr)
data->node->rt.quantum = SPA_MEMBER(ptr,
sizeof(struct pw_client_node_position), void);
else
data->node->rt.quantum = NULL;
}
static const struct pw_client_node_proxy_events client_node_events = { static const struct pw_client_node_proxy_events client_node_events = {
PW_VERSION_CLIENT_NODE_PROXY_EVENTS, PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
.add_mem = client_node_add_mem, .add_mem = client_node_add_mem,
.transport = client_node_transport, .transport = client_node_transport,
.set_param = client_node_set_param, .set_param = client_node_set_param,
.set_io = client_node_set_io,
.event = client_node_event, .event = client_node_event,
.command = client_node_command, .command = client_node_command,
.add_port = client_node_add_port, .add_port = client_node_add_port,
@ -1239,7 +1262,6 @@ static const struct pw_client_node_proxy_events client_node_events = {
.port_use_buffers = client_node_port_use_buffers, .port_use_buffers = client_node_port_use_buffers,
.port_command = client_node_port_command, .port_command = client_node_port_command,
.port_set_io = client_node_port_set_io, .port_set_io = client_node_port_set_io,
.set_position = client_node_set_position,
}; };
static void do_node_init(struct pw_proxy *proxy) static void do_node_init(struct pw_proxy *proxy)
@ -1376,6 +1398,7 @@ struct pw_proxy *pw_remote_export(struct pw_remote *remote,
data->core = pw_node_get_core(node); data->core = pw_node_get_core(node);
data->t = pw_core_get_type(data->core); data->t = pw_core_get_type(data->core);
data->node_proxy = (struct pw_client_node_proxy *)proxy; data->node_proxy = (struct pw_client_node_proxy *)proxy;
init_type(&data->type, data->t->map);
node->exported = true; node->exported = true;

View file

@ -45,7 +45,6 @@
#define MAX_PORTS 1 #define MAX_PORTS 1
struct type { struct type {
uint32_t client_node;
uint32_t prop_volume; uint32_t prop_volume;
uint32_t io_prop_volume; uint32_t io_prop_volume;
struct spa_type_media_type media_type; struct spa_type_media_type media_type;
@ -54,8 +53,6 @@ struct type {
static inline void init_type(struct type *type, struct spa_type_map *map) static inline void init_type(struct type *type, struct spa_type_map *map)
{ {
type->client_node = spa_type_map_get_id(map, PW_TYPE_INTERFACE__ClientNode);
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume); type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume"); type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");