mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	client-node: remove transport area
We don't need the area anymore
This commit is contained in:
		
							parent
							
								
									10fff4b2f8
								
							
						
					
					
						commit
						03b914405d
					
				
					 8 changed files with 18 additions and 475 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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', ],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,261 +0,0 @@
 | 
			
		|||
/* PipeWire
 | 
			
		||||
 * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * 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 <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/utils/ringbuffer.h>
 | 
			
		||||
#include <spa/node/io.h>
 | 
			
		||||
#include <pipewire/log.h>
 | 
			
		||||
#include <extensions/client-node.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
/* PipeWire
 | 
			
		||||
 * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * 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 <string.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/utils/defs.h>
 | 
			
		||||
 | 
			
		||||
#include <pipewire/mem.h>
 | 
			
		||||
 | 
			
		||||
/** 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__ */
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue