diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h index 66480d983..fc552a4e5 100644 --- a/src/extensions/client-node.h +++ b/src/extensions/client-node.h @@ -44,6 +44,8 @@ struct pw_client_node_buffer { 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 { #define PW_VERSION_CLIENT_NODE_POSITION 0 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_TRANSPORT 1 #define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 2 -#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 3 -#define PW_CLIENT_NODE_PROXY_EVENT_COMMAND 4 -#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 5 -#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 6 -#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM 7 -#define PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS 8 -#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 9 -#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO 10 -#define PW_CLIENT_NODE_PROXY_EVENT_SET_POSITION 11 +#define PW_CLIENT_NODE_PROXY_EVENT_SET_IO 3 +#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 4 +#define PW_CLIENT_NODE_PROXY_EVENT_COMMAND 5 +#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 6 +#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 7 +#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM 8 +#define PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS 9 +#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 10 +#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO 11 #define PW_CLIENT_NODE_PROXY_EVENT_NUM 12 /** \ref pw_client_node events */ @@ -248,6 +250,22 @@ struct pw_client_node_proxy_events { void (*set_param) (void *object, uint32_t seq, uint32_t id, uint32_t flags, 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 * \param event the received event */ @@ -350,11 +368,6 @@ struct pw_client_node_proxy_events { uint32_t mem_id, uint32_t offset, uint32_t size); - - void (*set_position) (void *object, - uint32_t mem_id, - uint32_t offset, - uint32_t size); }; 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__) #define pw_client_node_resource_set_param(r,...) \ 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,...) \ pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__) #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__) #define pw_client_node_resource_port_set_io(r,...) \ 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 } /* extern "C" */ diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 49ee6308b..647d2e986 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -64,6 +64,15 @@ #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 { uint32_t id; int ref; @@ -135,6 +144,8 @@ struct node { struct impl { struct pw_client_node this; + struct type type; + struct pw_core *core; 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; int res = 0; - struct pw_type *t; if (node == NULL || command == NULL) return -EINVAL; @@ -333,8 +343,6 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman if (this->resource == NULL) return 0; - t = this->impl->t; - pw_client_node_resource_command(this->resource, this->seq, command); res = SPA_RESULT_RETURN_ASYNC(this->seq++); @@ -1202,10 +1210,11 @@ static void node_initialized(void *data) 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_client_node_resource_set_position(this->resource, - m->id, - area_size, - sizeof(struct pw_client_node_position)); + pw_client_node_resource_set_io(this->resource, + impl->type.client_node_position, + m->id, + area_size, + sizeof(struct pw_client_node_position)); if ((global = pw_node_get_global(node)) != NULL) pw_client_node_registered(this, pw_global_get_id(global)); @@ -1358,8 +1367,9 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, impl->fds[0] = impl->fds[1] = -1; 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); impl->node.impl = impl; diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index a4aa49090..13cd32c42 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -440,22 +440,23 @@ static int client_node_demarshal_port_set_io(void *object, void *data, size_t si 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 spa_pod_parser prs; - uint32_t memid, off, sz; + uint32_t id, memid, off, sz; spa_pod_parser_init(&prs, data, size, 0); if (spa_pod_parser_get(&prs, "[" + "I", &id, "i", &memid, "i", &off, "i", &sz, NULL) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_position, - memid, off, sz); + pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_io, + id, memid, off, sz); return 0; } @@ -699,16 +700,18 @@ client_node_marshal_port_set_io(void *object, } static void -client_node_marshal_set_position(void *object, - uint32_t memid, - uint32_t offset, - uint32_t size) +client_node_marshal_set_io(void *object, + uint32_t id, + uint32_t memid, + uint32_t offset, + uint32_t size) { struct pw_resource *resource = object; 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, + "I", id, "i", memid, "i", offset, "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_transport, &client_node_marshal_set_param, + &client_node_marshal_set_io, &client_node_marshal_event_event, &client_node_marshal_command, &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_command, &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[] = { { &client_node_demarshal_add_mem, PW_PROTOCOL_NATIVE_REMAP }, { &client_node_demarshal_transport, 0 }, { &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_command, PW_PROTOCOL_NATIVE_REMAP }, { &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_command, 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 = { diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index a910f94da..6cc1356f9 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -42,6 +42,16 @@ #define MAX_MIX 4096 /** \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 pw_remote this; uint32_t type_client_node; @@ -88,6 +98,8 @@ struct node_data { struct pw_core *core; struct pw_type *t; + struct type type; + int rtwritefd; 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"); } + +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) { 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 = { PW_VERSION_CLIENT_NODE_PROXY_EVENTS, .add_mem = client_node_add_mem, .transport = client_node_transport, .set_param = client_node_set_param, + .set_io = client_node_set_io, .event = client_node_event, .command = client_node_command, .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_command = client_node_port_command, .port_set_io = client_node_port_set_io, - .set_position = client_node_set_position, }; 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->t = pw_core_get_type(data->core); data->node_proxy = (struct pw_client_node_proxy *)proxy; + init_type(&data->type, data->t->map); node->exported = true; diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 6b70aa6ad..aa4faa391 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -45,7 +45,6 @@ #define MAX_PORTS 1 struct type { - uint32_t client_node; uint32_t prop_volume; uint32_t io_prop_volume; 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) { - 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->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");