diff --git a/src/examples/audio-src.c b/src/examples/audio-src.c index 00d8fc006..66d1fa30f 100644 --- a/src/examples/audio-src.c +++ b/src/examples/audio-src.c @@ -34,7 +34,7 @@ #define M_PI_M2 ( M_PI + M_PI ) #define DEFAULT_RATE 44100 -#define DEFAULT_CHANNELS 1 +#define DEFAULT_CHANNELS 2 struct type { struct spa_type_media_type media_type; diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h index cf505a204..67ebb7c0b 100644 --- a/src/extensions/client-node.h +++ b/src/extensions/client-node.h @@ -36,108 +36,6 @@ struct pw_client_node_proxy; #define PW_VERSION_CLIENT_NODE 0 -struct pw_client_node_message; - -/** \class pw_client_node_transport - * - * \brief Transport object - * - * The transport object contains shared data and ringbuffers to exchange - * events and data between the server and the client in a low-latency and - * lockfree way. - */ -struct pw_client_node_transport { - void *input_data; /**< input memory for ringbuffer */ - struct spa_ringbuffer *input_buffer; /**< ringbuffer for input memory */ - void *output_data; /**< output memory for ringbuffer */ - struct spa_ringbuffer *output_buffer; /**< ringbuffer for output memory */ - - /** Destroy a transport - * \param trans a transport to destroy - * \memberof pw_client_node_transport - */ - void (*destroy) (struct pw_client_node_transport *trans); - - /** Add a message to the transport - * \param trans the transport to send the message on - * \param message the message to add - * \return 0 on success, < 0 on error - * - * Write \a message to the shared ringbuffer. - */ - int (*add_message) (struct pw_client_node_transport *trans, struct pw_client_node_message *message); - - /** Get next message from a transport - * \param trans the transport to get the message of - * \param[out] message the message to read - * \return < 0 on error, 1 when a message is available, - * 0 when no more messages are available. - * - * Get the skeleton next message from \a trans into \a message. This function will - * only read the head and object body of the message. - * - * After the complete size of the message has been calculated, you should call - * \ref parse_message() to read the complete message contents. - */ - int (*next_message) (struct pw_client_node_transport *trans, struct pw_client_node_message *message); - - /** Parse the complete message on transport - * \param trans the transport to read from - * \param[out] message memory that can hold the complete message - * \return 0 on success, < 0 on error - * - * Use this function after \ref next_message(). - */ - int (*parse_message) (struct pw_client_node_transport *trans, void *message); -}; - -#define pw_client_node_transport_destroy(t) ((t)->destroy((t))) -#define pw_client_node_transport_add_message(t,m) ((t)->add_message((t), (m))) -#define pw_client_node_transport_next_message(t,m) ((t)->next_message((t), (m))) -#define pw_client_node_transport_parse_message(t,m) ((t)->parse_message((t), (m))) - -enum pw_client_node_message_type { - PW_CLIENT_NODE_MESSAGE_PROCESS, /*< instruct the node to process */ - PW_CLIENT_NODE_MESSAGE_PORT_REUSE_BUFFER, /*< reuse a buffer */ -}; - -struct pw_client_node_message_body { - struct spa_pod_int type SPA_ALIGNED(8); /*< one of enum pw_client_node_message_type */ -}; - -struct pw_client_node_message { - struct spa_pod_struct pod; - struct pw_client_node_message_body body; -}; - -struct pw_client_node_message_port_reuse_buffer_body { - struct spa_pod_int type SPA_ALIGNED(8); /*< PW_CLIENT_NODE_MESSAGE_PORT_REUSE_BUFFER */ - struct spa_pod_int port_id SPA_ALIGNED(8); /*< port id */ - struct spa_pod_int buffer_id SPA_ALIGNED(8); /*< buffer id to reuse */ -}; - -struct pw_client_node_message_port_reuse_buffer { - struct spa_pod_struct pod; - struct pw_client_node_message_port_reuse_buffer_body body; -}; - -#define PW_CLIENT_NODE_MESSAGE_TYPE(message) (((struct pw_client_node_message*)(message))->body.type.value) - -#define PW_CLIENT_NODE_MESSAGE_INIT(message) (struct pw_client_node_message) \ - { { { sizeof(struct pw_client_node_message_body), SPA_POD_TYPE_STRUCT } }, \ - { SPA_POD_INT_INIT(message) } } - -#define PW_CLIENT_NODE_MESSAGE_INIT_FULL(type,size,message,...) (type) \ - { { { size, SPA_POD_TYPE_STRUCT } }, \ - { SPA_POD_INT_INIT(message), ##__VA_ARGS__ } } \ - -#define PW_CLIENT_NODE_MESSAGE_PORT_REUSE_BUFFER_INIT(port_id,buffer_id) \ - PW_CLIENT_NODE_MESSAGE_INIT_FULL(struct pw_client_node_message_port_reuse_buffer, \ - sizeof(struct pw_client_node_message_port_reuse_buffer_body), \ - PW_CLIENT_NODE_MESSAGE_PORT_REUSE_BUFFER, \ - SPA_POD_INT_INIT(port_id), \ - SPA_POD_INT_INIT(buffer_id)) - /** information about a buffer */ struct pw_client_node_buffer { uint32_t mem_id; /**< the memory id for the metadata */ @@ -316,19 +214,16 @@ struct pw_client_node_proxy_events { /** * Notify of a new transport area * - * The transport area is used to exchange real-time commands between - * the client and the server. + * The transport area is used to signal the client and the server. * * \param node_id the node id created for this client node * \param readfd fd for signal data can be read * \param writefd fd for signal data can be written - * \param transport the shared transport area */ void (*transport) (void *object, uint32_t node_id, int readfd, - int writefd, - struct pw_client_node_transport *transport); + int writefd); /** * Notify of a property change * diff --git a/src/modules/meson.build b/src/modules/meson.build index 33db36407..d931573f3 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -47,7 +47,6 @@ pipewire_module_mixer = shared_library('pipewire-module-mixer', pipewire_module_client_node = shared_library('pipewire-module-client-node', [ 'module-client-node.c', 'module-client-node/client-node.c', - 'module-client-node/transport.c', 'module-client-node/protocol-native.c', 'module-protocol-native/connection.c', 'spa/spa-node.c', ], diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 96b9b1c5a..38b7ced59 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -38,7 +38,6 @@ #include "pipewire/core.h" #include "modules/spa/spa-node.h" #include "client-node.h" -#include "transport.h" /** \cond */ @@ -141,8 +140,6 @@ struct impl { struct node node; - struct pw_client_node_transport *transport; - struct pw_map io_map; struct pw_memblock *io_areas; @@ -855,21 +852,15 @@ static int impl_node_port_reuse_buffer(struct spa_node *node, uint32_t port_id, uint32_t buffer_id) { struct node *this; - struct impl *impl; this = SPA_CONTAINER_OF(node, struct node, node); - impl = this->impl; if (!CHECK_OUT_PORT(this, SPA_DIRECTION_OUTPUT, port_id)) return -EINVAL; spa_log_trace(this->log, "reuse buffer %d", buffer_id); - pw_client_node_transport_add_message(impl->transport, (struct pw_client_node_message *) - &PW_CLIENT_NODE_MESSAGE_PORT_REUSE_BUFFER_INIT(port_id, buffer_id)); - //send_process(this); - - return 0; + return -ENOTSUP; } static int @@ -915,9 +906,6 @@ client_node_done(void *data, int seq, int res) struct impl *impl = data; struct node *this = &impl->node; - if (seq == 0 && res == 0 && impl->transport == NULL) - impl->transport = pw_client_node_transport_new(); - this->callbacks->done(this->callbacks_data, seq, res); } @@ -1176,8 +1164,7 @@ static void node_initialized(void *data) pw_client_node_resource_transport(this->resource, pw_global_get_id(pw_node_get_global(node)), impl->other_fds[0], - impl->other_fds[1], - impl->transport); + impl->other_fds[1]); } static void node_free(void *data) @@ -1187,9 +1174,6 @@ static void node_free(void *data) pw_log_debug("client-node %p: free", &impl->this); node_clear(&impl->node); - if (impl->transport) - pw_client_node_transport_destroy(impl->transport); - spa_hook_remove(&impl->node_listener); pw_array_clear(&impl->mems); diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index e69d733cb..3929bc371 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -29,8 +29,6 @@ #include "extensions/protocol-native.h" #include "extensions/client-node.h" -#include "transport.h" - static void client_node_marshal_done(void *object, int seq, int res) { @@ -188,33 +186,25 @@ static int client_node_demarshal_transport(void *object, void *data, size_t size { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t node_id, ridx, widx, memfd_idx; + uint32_t node_id, ridx, widx; int readfd, writefd; - struct pw_client_node_transport_info info; - struct pw_client_node_transport *transport; spa_pod_parser_init(&prs, data, size, 0); if (spa_pod_parser_get(&prs, "[" "i", &node_id, "i", &ridx, - "i", &widx, - "i", &memfd_idx, - "i", &info.offset, - "i", &info.size, NULL) < 0) + "i", &widx, NULL) < 0) return -EINVAL; readfd = pw_protocol_native_get_proxy_fd(proxy, ridx); writefd = pw_protocol_native_get_proxy_fd(proxy, widx); - info.memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx); - if (readfd == -1 || writefd == -1 || info.memfd == -1) + if (readfd == -1 || writefd == -1) return -EINVAL; - transport = pw_client_node_transport_new_from_info(&info); - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, transport, node_id, - readfd, writefd, transport); + readfd, writefd); return 0; } @@ -462,24 +452,17 @@ client_node_marshal_add_mem(void *object, pw_protocol_native_end_resource(resource, b); } -static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd, - struct pw_client_node_transport *transport) +static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct pw_client_node_transport_info info; - - pw_client_node_transport_get_info(transport, &info); b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT); spa_pod_builder_struct(b, "i", node_id, "i", pw_protocol_native_add_resource_fd(resource, readfd), - "i", pw_protocol_native_add_resource_fd(resource, writefd), - "i", pw_protocol_native_add_resource_fd(resource, info.memfd), - "i", info.offset, - "i", info.size); + "i", pw_protocol_native_add_resource_fd(resource, writefd)); pw_protocol_native_end_resource(resource, b); } diff --git a/src/modules/module-client-node/transport.c b/src/modules/module-client-node/transport.c deleted file mode 100644 index 01736b28a..000000000 --- a/src/modules/module-client-node/transport.c +++ /dev/null @@ -1,261 +0,0 @@ -/* PipeWire - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "transport.h" - -/** \cond */ - -#define INPUT_BUFFER_SIZE (1<<12) -#define OUTPUT_BUFFER_SIZE (1<<12) - -struct transport { - struct pw_client_node_transport trans; - - struct pw_memblock *mem; - size_t offset; - - struct pw_client_node_message current; - uint32_t current_index; -}; -/** \endcond */ - -static size_t area_get_size(void) -{ - size_t size; - size = sizeof(struct spa_ringbuffer); - size += INPUT_BUFFER_SIZE; - size += sizeof(struct spa_ringbuffer); - size += OUTPUT_BUFFER_SIZE; - return size; -} - -static void transport_setup_area(void *p, struct pw_client_node_transport *trans) -{ - trans->input_buffer = p; - p = SPA_MEMBER(p, sizeof(struct spa_ringbuffer), void); - - trans->input_data = p; - p = SPA_MEMBER(p, INPUT_BUFFER_SIZE, void); - - trans->output_buffer = p; - p = SPA_MEMBER(p, sizeof(struct spa_ringbuffer), void); - - trans->output_data = p; - p = SPA_MEMBER(p, OUTPUT_BUFFER_SIZE, void); -} - -static void transport_reset_area(struct pw_client_node_transport *trans) -{ - spa_ringbuffer_init(trans->input_buffer); - spa_ringbuffer_init(trans->output_buffer); -} - -static void destroy(struct pw_client_node_transport *trans) -{ - struct transport *impl = (struct transport *) trans; - - pw_log_debug("transport %p: destroy", trans); - - pw_memblock_free(impl->mem); - free(impl); -} - -static int add_message(struct pw_client_node_transport *trans, struct pw_client_node_message *message) -{ - struct transport *impl = (struct transport *) trans; - int32_t filled, avail; - uint32_t size, index; - - if (impl == NULL || message == NULL) - return -EINVAL; - - filled = spa_ringbuffer_get_write_index(trans->output_buffer, &index); - avail = OUTPUT_BUFFER_SIZE - filled; - size = SPA_POD_SIZE(message); - if (avail < size) - return -ENOSPC; - - spa_ringbuffer_write_data(trans->output_buffer, - trans->output_data, OUTPUT_BUFFER_SIZE, - index & (OUTPUT_BUFFER_SIZE - 1), message, size); - spa_ringbuffer_write_update(trans->output_buffer, index + size); - - return 0; -} - -static int next_message(struct pw_client_node_transport *trans, struct pw_client_node_message *message) -{ - struct transport *impl = (struct transport *) trans; - int32_t avail; - - if (impl == NULL || message == NULL) - return -EINVAL; - - avail = spa_ringbuffer_get_read_index(trans->input_buffer, &impl->current_index); - if (avail < sizeof(struct pw_client_node_message)) - return 0; - - spa_ringbuffer_read_data(trans->input_buffer, - trans->input_data, INPUT_BUFFER_SIZE, - impl->current_index & (INPUT_BUFFER_SIZE - 1), - &impl->current, sizeof(struct pw_client_node_message)); - - if (avail < SPA_POD_SIZE(&impl->current)) - return 0; - - *message = impl->current; - - return 1; -} - -static int parse_message(struct pw_client_node_transport *trans, void *message) -{ - struct transport *impl = (struct transport *) trans; - uint32_t size; - - if (impl == NULL || message == NULL) - return -EINVAL; - - size = SPA_POD_SIZE(&impl->current); - - spa_ringbuffer_read_data(trans->input_buffer, - trans->input_data, INPUT_BUFFER_SIZE, - impl->current_index & (INPUT_BUFFER_SIZE - 1), message, size); - spa_ringbuffer_read_update(trans->input_buffer, impl->current_index + size); - - return 0; -} - -/** Create a new transport - * \return a newly allocated \ref pw_client_node_transport - * \memberof pw_client_node_transport - */ -struct pw_client_node_transport * -pw_client_node_transport_new(void) -{ - struct transport *impl; - struct pw_client_node_transport *trans; - - impl = calloc(1, sizeof(struct transport)); - if (impl == NULL) - return NULL; - - pw_log_debug("transport %p: new", impl); - - trans = &impl->trans; - impl->offset = 0; - - if (pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD | - PW_MEMBLOCK_FLAG_MAP_READWRITE | - PW_MEMBLOCK_FLAG_SEAL, - area_get_size(), - &impl->mem) < 0) - return NULL; - - transport_setup_area(impl->mem->ptr, trans); - transport_reset_area(trans); - - trans->destroy = destroy; - trans->add_message = add_message; - trans->next_message = next_message; - trans->parse_message = parse_message; - - return trans; -} - -struct pw_client_node_transport * -pw_client_node_transport_new_from_info(struct pw_client_node_transport_info *info) -{ - struct transport *impl; - struct pw_client_node_transport *trans; - void *tmp; - int res; - - impl = calloc(1, sizeof(struct transport)); - if (impl == NULL) - return NULL; - - trans = &impl->trans; - pw_log_debug("transport %p: new from info", impl); - - if ((res = pw_memblock_import(PW_MEMBLOCK_FLAG_MAP_READWRITE | - PW_MEMBLOCK_FLAG_WITH_FD, - info->memfd, - info->offset, - info->size, &impl->mem)) < 0) { - pw_log_warn("transport %p: failed to map fd %d: %s", impl, info->memfd, - spa_strerror(res)); - goto mmap_failed; - } - - impl->offset = info->offset; - - transport_setup_area(impl->mem->ptr, trans); - - tmp = trans->output_buffer; - trans->output_buffer = trans->input_buffer; - trans->input_buffer = tmp; - - tmp = trans->output_data; - trans->output_data = trans->input_data; - trans->input_data = tmp; - - trans->destroy = destroy; - trans->add_message = add_message; - trans->next_message = next_message; - trans->parse_message = parse_message; - - return trans; - - mmap_failed: - free(impl); - errno = -res; - return NULL; -} - -/** Get transport info - * \param trans the transport to get info of - * \param[out] info transport info - * \return 0 on success - * - * Fill \a info with the transport info of \a trans. This information can be - * passed to the client to set up the shared transport. - * - * \memberof pw_client_node_transport - */ -int pw_client_node_transport_get_info(struct pw_client_node_transport *trans, - struct pw_client_node_transport_info *info) -{ - struct transport *impl = (struct transport *) trans; - - info->memfd = impl->mem->fd; - info->offset = impl->offset; - info->size = impl->mem->size; - - return 0; -} diff --git a/src/modules/module-client-node/transport.h b/src/modules/module-client-node/transport.h deleted file mode 100644 index 047eb2768..000000000 --- a/src/modules/module-client-node/transport.h +++ /dev/null @@ -1,54 +0,0 @@ -/* PipeWire - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __PIPEWIRE_CLIENT_NODE_TRANSPORT_H__ -#define __PIPEWIRE_CLIENT_NODE_TRANSPORT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -#include - -/** information about the transport region \memberof pw_client_node */ -struct pw_client_node_transport_info { - int memfd; /**< the memfd of the transport area */ - uint32_t offset; /**< offset to map \a memfd at */ - uint32_t size; /**< size of memfd mapping */ -}; - -struct pw_client_node_transport * -pw_client_node_transport_new(void); - -struct pw_client_node_transport * -pw_client_node_transport_new_from_info(struct pw_client_node_transport_info *info); - -int -pw_client_node_transport_get_info(struct pw_client_node_transport *trans, - struct pw_client_node_transport_info *info); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __PIPEWIRE_CLIENT_NODE_TRANSPORT_H__ */ diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 7c1e814ff..4c6609e75 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -91,7 +91,6 @@ struct node_data { int rtwritefd; struct spa_source *rtsocket_source; - struct pw_client_node_transport *trans; struct mix mix_pool[MAX_MIX]; struct spa_list mix[2]; @@ -610,7 +609,7 @@ static void clean_transport(struct node_data *data) { struct mem *m; - if (data->trans == NULL) + if (data->node_id == SPA_ID_INVALID) return; unhandle_socket(data); @@ -619,10 +618,9 @@ static void clean_transport(struct node_data *data) clear_mem(data, m); pw_array_clear(&data->mems); - pw_client_node_transport_destroy(data->trans); close(data->rtwritefd); - data->trans = NULL; + data->node_id = SPA_ID_INVALID; } static void mix_init(struct mix *mix, struct pw_port *port, uint32_t mix_id) @@ -743,8 +741,7 @@ static void client_node_add_mem(void *object, } static void client_node_transport(void *object, uint32_t node_id, - int readfd, int writefd, - struct pw_client_node_transport *transport) + int readfd, int writefd) { struct pw_proxy *proxy = object; struct node_data *data = proxy->user_data; @@ -752,10 +749,9 @@ static void client_node_transport(void *object, uint32_t node_id, clean_transport(data); data->node_id = node_id; - data->trans = transport; - pw_log_info("remote-node %p: create transport %p with fds %d %d for node %u", - proxy, data->trans, readfd, writefd, node_id); + pw_log_info("remote-node %p: create transport with fds %d %d for node %u", + proxy, readfd, writefd, node_id); data->rtwritefd = writefd; data->rtsocket_source = pw_loop_add_io(proxy->remote->core->data_loop, @@ -1280,7 +1276,7 @@ static void node_proxy_destroy(void *_data) struct node_data *data = _data; struct mix *mix, *tmp; - if (data->trans) { + if (data->node_id != SPA_ID_INVALID) { spa_list_for_each_safe(mix, tmp, &data->mix[SPA_DIRECTION_INPUT], link) clear_mix(data, mix); spa_list_for_each_safe(mix, tmp, &data->mix[SPA_DIRECTION_OUTPUT], link) @@ -1316,6 +1312,7 @@ struct pw_proxy *pw_remote_export(struct pw_remote *remote, data = pw_proxy_get_user_data(proxy); data->remote = remote; data->node = node; + data->node_id = SPA_ID_INVALID; data->core = pw_node_get_core(node); data->t = pw_core_get_type(data->core); data->node_proxy = (struct pw_client_node_proxy *)proxy;