From bba8c5daa361c18c789fa2b9348eb5067d65035c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 3 Aug 2021 17:36:11 +0200 Subject: [PATCH] client-node: add port_set_mix_info Add a new client-node port_set_mix_info event. bump the interface version to 4 and the event version to 1. The event is used to send information about the peer object to the port mixer. This can be used to track what buffers belong to what peer. --- src/modules/module-client-node/client-node.c | 9 +++ .../module-client-node/protocol-native.c | 64 ++++++++++++++++++- src/pipewire/extensions/client-node.h | 35 +++++++++- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index f42a6fae8..c15191f05 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -83,6 +83,7 @@ struct mix { unsigned int valid:1; uint32_t id; struct port *port; + uint32_t peer_id; uint32_t n_buffers; struct buffer buffers[MAX_BUFFERS]; }; @@ -188,6 +189,8 @@ struct impl { pw_client_node_resource(r,port_set_io,0,__VA_ARGS__) #define pw_client_node_resource_set_activation(r,...) \ pw_client_node_resource(r,set_activation,0,__VA_ARGS__) +#define pw_client_node_resource_port_set_mix_info(r,...) \ + pw_client_node_resource(r,port_set_mix_info,1,__VA_ARGS__) static int do_port_use_buffers(struct impl *impl, @@ -866,6 +869,10 @@ do_port_use_buffers(struct impl *impl, } mix->n_buffers = n_buffers; + if (this->resource->version >= 4) + pw_client_node_resource_port_set_mix_info(this->resource, + direction, port_id, mix_id, + mix->peer_id, NULL); return pw_client_node_resource_port_use_buffers(this->resource, direction, port_id, mix_id, flags, n_buffers, mb); @@ -1376,6 +1383,8 @@ static int port_init_mix(void *data, struct pw_impl_port_mix *mix) mix->id * sizeof(struct spa_io_buffers), void); *mix->io = SPA_IO_BUFFERS_INIT; + m->peer_id = mix->peer_id; + pw_log_debug(NAME " %p: init mix id:%d io:%p base:%p", impl, mix->id, mix->io, impl->io_areas->map->ptr); diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index 550e7683a..f1ece54da 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -574,6 +574,39 @@ static int client_node_demarshal_set_activation(void *object, const struct pw_pr return 0; } +static int client_node_demarshal_port_set_mix_info(void *object, const struct pw_protocol_native_message *msg) +{ + struct pw_proxy *proxy = object; + struct spa_pod_parser prs; + uint32_t direction, port_id, mix_id, peer_id; + struct spa_pod_frame f[2]; + struct spa_dict props = SPA_DICT_INIT(NULL, 0); + + spa_pod_parser_init(&prs, msg->data, msg->size); + if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || + spa_pod_parser_get(&prs, + SPA_POD_Int(&direction), + SPA_POD_Int(&port_id), + SPA_POD_Int(&mix_id), + SPA_POD_Int(&peer_id), NULL) < 0) + return -EINVAL; + + if (spa_pod_parser_push_struct(&prs, &f[1]) < 0) + return -EINVAL; + if (spa_pod_parser_get(&prs, + SPA_POD_Int(&props.n_items), NULL) < 0) + return -EINVAL; + + props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); + if (parse_dict(&prs, &props) < 0) + return -EINVAL; + + pw_proxy_notify(proxy, struct pw_client_node_events, port_set_mix_info, 1, + direction, port_id, mix_id, + peer_id, &props); + return 0; +} + static int client_node_demarshal_set_io(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; @@ -841,6 +874,33 @@ client_node_marshal_set_io(void *object, return pw_protocol_native_end_resource(resource, b); } +static int +client_node_marshal_port_set_mix_info(void *object, + uint32_t direction, + uint32_t port_id, + uint32_t mix_id, + uint32_t peer_id, + const struct spa_dict *props) +{ + struct pw_resource *resource = object; + struct spa_pod_builder *b; + struct spa_pod_frame f; + + b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_PORT_SET_MIX_INFO, NULL); + + spa_pod_builder_push_struct(b, &f); + spa_pod_builder_add(b, + SPA_POD_Int(direction), + SPA_POD_Int(port_id), + SPA_POD_Int(mix_id), + SPA_POD_Int(peer_id), NULL); + push_dict(b, props); + spa_pod_builder_pop(b, &f); + + return pw_protocol_native_end_resource(resource, b); +} + + static int client_node_demarshal_get_node(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; @@ -1128,6 +1188,7 @@ static const struct pw_client_node_events pw_protocol_native_client_node_event_m .port_use_buffers = &client_node_marshal_port_use_buffers, .port_set_io = &client_node_marshal_port_set_io, .set_activation = &client_node_marshal_set_activation, + .port_set_mix_info = &client_node_marshal_port_set_mix_info, }; static const struct pw_protocol_native_demarshal @@ -1143,7 +1204,8 @@ pw_protocol_native_client_node_event_demarshal[PW_CLIENT_NODE_EVENT_NUM] = [PW_CLIENT_NODE_EVENT_PORT_SET_PARAM] = { &client_node_demarshal_port_set_param, 0 }, [PW_CLIENT_NODE_EVENT_PORT_USE_BUFFERS] = { &client_node_demarshal_port_use_buffers, 0 }, [PW_CLIENT_NODE_EVENT_PORT_SET_IO] = { &client_node_demarshal_port_set_io, 0 }, - [PW_CLIENT_NODE_EVENT_SET_ACTIVATION] = { &client_node_demarshal_set_activation, 0 } + [PW_CLIENT_NODE_EVENT_SET_ACTIVATION] = { &client_node_demarshal_set_activation, 0 }, + [PW_CLIENT_NODE_EVENT_PORT_SET_MIX_INFO] = { &client_node_demarshal_port_set_mix_info, 0 } }; static const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = { diff --git a/src/pipewire/extensions/client-node.h b/src/pipewire/extensions/client-node.h index 3e4511b6f..1efd13389 100644 --- a/src/pipewire/extensions/client-node.h +++ b/src/pipewire/extensions/client-node.h @@ -34,7 +34,7 @@ extern "C" { #define PW_TYPE_INTERFACE_ClientNode PW_TYPE_INFO_INTERFACE_BASE "ClientNode" -#define PW_VERSION_CLIENT_NODE 3 +#define PW_VERSION_CLIENT_NODE 4 struct pw_client_node; #define PW_EXTENSION_MODULE_CLIENT_NODE PIPEWIRE_MODULE_PREFIX "module-client-node" @@ -58,11 +58,12 @@ struct pw_client_node_buffer { #define PW_CLIENT_NODE_EVENT_PORT_USE_BUFFERS 8 #define PW_CLIENT_NODE_EVENT_PORT_SET_IO 9 #define PW_CLIENT_NODE_EVENT_SET_ACTIVATION 10 -#define PW_CLIENT_NODE_EVENT_NUM 11 +#define PW_CLIENT_NODE_EVENT_PORT_SET_MIX_INFO 11 +#define PW_CLIENT_NODE_EVENT_NUM 12 /** \ref pw_client_node events */ struct pw_client_node_events { -#define PW_VERSION_CLIENT_NODE_EVENTS 0 +#define PW_VERSION_CLIENT_NODE_EVENTS 1 uint32_t version; /** * Notify of a new transport area @@ -193,12 +194,40 @@ struct pw_client_node_events { uint32_t offset, uint32_t size); + /** + * Notify the activation record of the next + * node to trigger + * + * \param node_id the peer node id + * \param signalfd the fd to wake up the peer + * \param mem_id the mem id of the memory + * \param the offset in \a mem_id to map + * \param the size of \a mem_id to map + */ int (*set_activation) (void *object, uint32_t node_id, int signalfd, uint32_t mem_id, uint32_t offset, uint32_t size); + + /** + * Notify about the peer of mix_id + * + * \param direction the direction of the port + * \param port_id the port id + * \param mix_id the mix id + * \param peer_id the id of the peer port + * \param props extra properties + * + * Since version 4:1 + */ + int (*port_set_mix_info) (void *object, + enum spa_direction direction, + uint32_t port_id, + uint32_t mix_id, + uint32_t peer_id, + const struct spa_dict *props); }; #define PW_CLIENT_NODE_METHOD_ADD_LISTENER 0