mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
modules: remove v0 protocol support
This commit is contained in:
parent
ae7a893ce9
commit
20a4aa8cf9
14 changed files with 2 additions and 4901 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,91 +0,0 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2015 Wim Taymans <wim.taymans@gmail.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef PIPEWIRE_CLIENT_NODE0_H
|
||||
#define PIPEWIRE_CLIENT_NODE0_H
|
||||
|
||||
#include <pipewire/impl.h>
|
||||
|
||||
#include "ext-client-node.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** The state of the clock */
|
||||
enum spa_clock0_state {
|
||||
SPA_CLOCK0_STATE_STOPPED, /*< the clock is stopped */
|
||||
SPA_CLOCK0_STATE_PAUSED, /*< the clock is paused */
|
||||
SPA_CLOCK0_STATE_RUNNING, /*< the clock is running */
|
||||
};
|
||||
|
||||
struct spa_command_node0_clock_update_body {
|
||||
struct spa_pod_object_body body;
|
||||
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_TIME (1 << 0)
|
||||
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_SCALE (1 << 1)
|
||||
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_STATE (1 << 2)
|
||||
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_LATENCY (1 << 3)
|
||||
struct spa_pod_int change_mask SPA_ALIGNED(8);
|
||||
struct spa_pod_int rate SPA_ALIGNED(8);
|
||||
struct spa_pod_long ticks SPA_ALIGNED(8);
|
||||
struct spa_pod_long monotonic_time SPA_ALIGNED(8);
|
||||
struct spa_pod_long offset SPA_ALIGNED(8);
|
||||
struct spa_pod_int scale SPA_ALIGNED(8);
|
||||
struct spa_pod_int state SPA_ALIGNED(8);
|
||||
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_FLAG_LIVE (1 << 0)
|
||||
struct spa_pod_int flags SPA_ALIGNED(8);
|
||||
struct spa_pod_long latency SPA_ALIGNED(8);
|
||||
};
|
||||
|
||||
struct spa_command_node0_clock_update {
|
||||
struct spa_pod pod;
|
||||
struct spa_command_node0_clock_update_body body;
|
||||
};
|
||||
|
||||
enum spa_node0_event {
|
||||
SPA_NODE0_EVENT_START = SPA_TYPE_VENDOR_PipeWire,
|
||||
SPA_NODE0_EVENT_RequestClockUpdate,
|
||||
};
|
||||
|
||||
enum spa_node0_command {
|
||||
SPA_NODE0_COMMAND_START = SPA_TYPE_VENDOR_PipeWire,
|
||||
SPA_NODE0_COMMAND_ClockUpdate,
|
||||
};
|
||||
|
||||
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_INIT(type,change_mask,rate,ticks,monotonic_time,offset,scale,state,flags,latency) \
|
||||
SPA_COMMAND_INIT_FULL(struct spa_command_node0_clock_update, \
|
||||
sizeof(struct spa_command_node0_clock_update_body), 0, type, \
|
||||
SPA_POD_INIT_Int(change_mask), \
|
||||
SPA_POD_INIT_Int(rate), \
|
||||
SPA_POD_INIT_Long(ticks), \
|
||||
SPA_POD_INIT_Long(monotonic_time), \
|
||||
SPA_POD_INIT_Long(offset), \
|
||||
SPA_POD_INIT_Int(scale), \
|
||||
SPA_POD_INIT_Int(state), \
|
||||
SPA_POD_INIT_Int(flags), \
|
||||
SPA_POD_INIT_Long(latency))
|
||||
|
||||
|
||||
/** \class pw_impl_client_node0
|
||||
*
|
||||
* PipeWire client node interface
|
||||
*/
|
||||
struct pw_impl_client_node0 {
|
||||
struct pw_impl_node *node;
|
||||
|
||||
struct pw_resource *resource;
|
||||
};
|
||||
|
||||
struct pw_impl_client_node0 *
|
||||
pw_impl_client_node0_new(struct pw_resource *resource,
|
||||
struct pw_properties *properties);
|
||||
|
||||
void
|
||||
pw_impl_client_node0_destroy(struct pw_impl_client_node0 *node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PIPEWIRE_CLIENT_NODE0_H */
|
||||
|
|
@ -1,394 +0,0 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2016 Wim Taymans <wim.taymans@gmail.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef __PIPEWIRE_EXT_CLIENT_NODE0_H__
|
||||
#define __PIPEWIRE_EXT_CLIENT_NODE0_H__
|
||||
|
||||
#include <spa/utils/defs.h>
|
||||
#include <spa/param/param.h>
|
||||
#include <spa/node/node.h>
|
||||
|
||||
#include <pipewire/proxy.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PW_TYPE_INTERFACE_ClientNode PW_TYPE_INFO_INTERFACE_BASE "ClientNode"
|
||||
|
||||
#define PW_VERSION_CLIENT_NODE0 0
|
||||
|
||||
struct pw_client_node0_message;
|
||||
|
||||
/** Shared structure between client and server \memberof pw_client_node */
|
||||
struct pw_client_node0_area {
|
||||
uint32_t max_input_ports; /**< max input ports of the node */
|
||||
uint32_t n_input_ports; /**< number of input ports of the node */
|
||||
uint32_t max_output_ports; /**< max output ports of the node */
|
||||
uint32_t n_output_ports; /**< number of output ports of the node */
|
||||
};
|
||||
|
||||
/** \class pw_client_node0_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_node0_transport {
|
||||
struct pw_client_node0_area *area; /**< the transport area */
|
||||
struct spa_io_buffers *inputs; /**< array of buffer input io */
|
||||
struct spa_io_buffers *outputs; /**< array of buffer output io */
|
||||
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_node0_transport
|
||||
*/
|
||||
void (*destroy) (struct pw_client_node0_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_node0_transport *trans, struct pw_client_node0_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_node0_transport *trans, struct pw_client_node0_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_node0_transport *trans, void *message);
|
||||
};
|
||||
|
||||
#define pw_client_node0_transport_destroy(t) ((t)->destroy((t)))
|
||||
#define pw_client_node0_transport_add_message(t,m) ((t)->add_message((t), (m)))
|
||||
#define pw_client_node0_transport_next_message(t,m) ((t)->next_message((t), (m)))
|
||||
#define pw_client_node0_transport_parse_message(t,m) ((t)->parse_message((t), (m)))
|
||||
|
||||
enum pw_client_node0_message_type {
|
||||
PW_CLIENT_NODE0_MESSAGE_HAVE_OUTPUT, /*< signal that the node has output */
|
||||
PW_CLIENT_NODE0_MESSAGE_NEED_INPUT, /*< signal that the node needs input */
|
||||
PW_CLIENT_NODE0_MESSAGE_PROCESS_INPUT, /*< instruct the node to process input */
|
||||
PW_CLIENT_NODE0_MESSAGE_PROCESS_OUTPUT, /*< instruct the node output is processed */
|
||||
PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER, /*< reuse a buffer */
|
||||
};
|
||||
|
||||
struct pw_client_node0_message_body {
|
||||
struct spa_pod_int type SPA_ALIGNED(8); /*< one of enum pw_client_node0_message_type */
|
||||
};
|
||||
|
||||
struct pw_client_node0_message {
|
||||
struct spa_pod_struct pod;
|
||||
struct pw_client_node0_message_body body;
|
||||
};
|
||||
|
||||
struct pw_client_node0_message_port_reuse_buffer_body {
|
||||
struct spa_pod_int type SPA_ALIGNED(8); /*< PW_CLIENT_NODE0_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_node0_message_port_reuse_buffer {
|
||||
struct spa_pod_struct pod;
|
||||
struct pw_client_node0_message_port_reuse_buffer_body body;
|
||||
};
|
||||
|
||||
#define PW_CLIENT_NODE0_MESSAGE_TYPE(message) (((struct pw_client_node0_message*)(message))->body.type.value)
|
||||
|
||||
#define PW_CLIENT_NODE0_MESSAGE_INIT(message) ((struct pw_client_node0_message) \
|
||||
{ { { sizeof(struct pw_client_node0_message_body), SPA_TYPE_Struct } }, \
|
||||
{ SPA_POD_INIT_Int(message) } })
|
||||
|
||||
#define PW_CLIENT_NODE0_MESSAGE_INIT_FULL(type,size,message,...) (type) \
|
||||
{ { { size, SPA_TYPE_Struct } }, \
|
||||
{ SPA_POD_INIT_Int(message), ##__VA_ARGS__ } } \
|
||||
|
||||
#define PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER_INIT(port_id,buffer_id) \
|
||||
PW_CLIENT_NODE0_MESSAGE_INIT_FULL(struct pw_client_node0_message_port_reuse_buffer, \
|
||||
sizeof(struct pw_client_node0_message_port_reuse_buffer_body), \
|
||||
PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER, \
|
||||
SPA_POD_INIT_Int(port_id), \
|
||||
SPA_POD_INIT_Int(buffer_id))
|
||||
|
||||
/** information about a buffer */
|
||||
struct pw_client_node0_buffer {
|
||||
uint32_t mem_id; /**< the memory id for the metadata */
|
||||
uint32_t offset; /**< offset in memory */
|
||||
uint32_t size; /**< size in memory */
|
||||
struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */
|
||||
};
|
||||
|
||||
#define PW_CLIENT_NODE0_METHOD_DONE 0
|
||||
#define PW_CLIENT_NODE0_METHOD_UPDATE 1
|
||||
#define PW_CLIENT_NODE0_METHOD_PORT_UPDATE 2
|
||||
#define PW_CLIENT_NODE0_METHOD_SET_ACTIVE 3
|
||||
#define PW_CLIENT_NODE0_METHOD_EVENT 4
|
||||
#define PW_CLIENT_NODE0_METHOD_DESTROY 5
|
||||
#define PW_CLIENT_NODE0_METHOD_NUM 6
|
||||
|
||||
/** \ref pw_client_node methods */
|
||||
struct pw_client_node0_methods {
|
||||
#define PW_VERSION_CLIENT_NODE0_METHODS 0
|
||||
uint32_t version;
|
||||
|
||||
/** Complete an async operation */
|
||||
void (*done) (void *object, int seq, int res);
|
||||
|
||||
/**
|
||||
* Update the node ports and properties
|
||||
*
|
||||
* Update the maximum number of ports and the params of the
|
||||
* client node.
|
||||
* \param change_mask bitfield with changed parameters
|
||||
* \param max_input_ports new max input ports
|
||||
* \param max_output_ports new max output ports
|
||||
* \param params new params
|
||||
*/
|
||||
void (*update) (void *object,
|
||||
#define PW_CLIENT_NODE0_UPDATE_MAX_INPUTS (1 << 0)
|
||||
#define PW_CLIENT_NODE0_UPDATE_MAX_OUTPUTS (1 << 1)
|
||||
#define PW_CLIENT_NODE0_UPDATE_PARAMS (1 << 2)
|
||||
uint32_t change_mask,
|
||||
uint32_t max_input_ports,
|
||||
uint32_t max_output_ports,
|
||||
uint32_t n_params,
|
||||
const struct spa_pod **params);
|
||||
|
||||
/**
|
||||
* Update a node port
|
||||
*
|
||||
* Update the information of one port of a node.
|
||||
* \param direction the direction of the port
|
||||
* \param port_id the port id to update
|
||||
* \param change_mask a bitfield of changed items
|
||||
* \param n_params number of port parameters
|
||||
* \param params array of port parameters
|
||||
* \param info port information
|
||||
*/
|
||||
void (*port_update) (void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
#define PW_CLIENT_NODE0_PORT_UPDATE_PARAMS (1 << 0)
|
||||
#define PW_CLIENT_NODE0_PORT_UPDATE_INFO (1 << 1)
|
||||
uint32_t change_mask,
|
||||
uint32_t n_params,
|
||||
const struct spa_pod **params,
|
||||
const struct spa_port_info *info);
|
||||
/**
|
||||
* Activate or deactivate the node
|
||||
*/
|
||||
void (*set_active) (void *object, bool active);
|
||||
/**
|
||||
* Send an event to the node
|
||||
* \param event the event to send
|
||||
*/
|
||||
void (*event) (void *object, struct spa_event *event);
|
||||
/**
|
||||
* Destroy the client_node
|
||||
*/
|
||||
void (*destroy) (void *object);
|
||||
};
|
||||
|
||||
#define PW_CLIENT_NODE0_EVENT_ADD_MEM 0
|
||||
#define PW_CLIENT_NODE0_EVENT_TRANSPORT 1
|
||||
#define PW_CLIENT_NODE0_EVENT_SET_PARAM 2
|
||||
#define PW_CLIENT_NODE0_EVENT_EVENT 3
|
||||
#define PW_CLIENT_NODE0_EVENT_COMMAND 4
|
||||
#define PW_CLIENT_NODE0_EVENT_ADD_PORT 5
|
||||
#define PW_CLIENT_NODE0_EVENT_REMOVE_PORT 6
|
||||
#define PW_CLIENT_NODE0_EVENT_PORT_SET_PARAM 7
|
||||
#define PW_CLIENT_NODE0_EVENT_PORT_USE_BUFFERS 8
|
||||
#define PW_CLIENT_NODE0_EVENT_PORT_COMMAND 9
|
||||
#define PW_CLIENT_NODE0_EVENT_PORT_SET_IO 10
|
||||
#define PW_CLIENT_NODE0_EVENT_NUM 11
|
||||
|
||||
/** \ref pw_client_node events */
|
||||
struct pw_client_node0_events {
|
||||
#define PW_VERSION_CLIENT_NODE0_EVENTS 0
|
||||
uint32_t version;
|
||||
/**
|
||||
* Memory was added to a node
|
||||
*
|
||||
* \param mem_id the id of the memory
|
||||
* \param type the memory type
|
||||
* \param memfd the fd of the memory
|
||||
* \param flags flags for the \a memfd
|
||||
*/
|
||||
void (*add_mem) (void *data,
|
||||
uint32_t mem_id,
|
||||
uint32_t type,
|
||||
int memfd,
|
||||
uint32_t flags);
|
||||
/**
|
||||
* Notify of a new transport area
|
||||
*
|
||||
* The transport area is used to exchange real-time commands between
|
||||
* 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 *data,
|
||||
uint32_t node_id,
|
||||
int readfd,
|
||||
int writefd,
|
||||
struct pw_client_node0_transport *transport);
|
||||
/**
|
||||
* Notify of a property change
|
||||
*
|
||||
* When the server configures the properties on the node
|
||||
* this event is sent
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param id the id of the parameter
|
||||
* \param flags parameter flags
|
||||
* \param param the param to set
|
||||
*/
|
||||
void (*set_param) (void *data, uint32_t seq,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param);
|
||||
/**
|
||||
* Receive an event from the client node
|
||||
* \param event the received event */
|
||||
void (*event) (void *data, const struct spa_event *event);
|
||||
/**
|
||||
* Notify of a new node command
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param command the command
|
||||
*/
|
||||
void (*command) (void *data, uint32_t seq, const struct spa_command *command);
|
||||
/**
|
||||
* A new port was added to the node
|
||||
*
|
||||
* The server can at any time add a port to the node when there
|
||||
* are free ports available.
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction the direction of the port
|
||||
* \param port_id the new port id
|
||||
*/
|
||||
void (*add_port) (void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id);
|
||||
/**
|
||||
* A port was removed from the node
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction a port direction
|
||||
* \param port_id the remove port id
|
||||
*/
|
||||
void (*remove_port) (void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id);
|
||||
/**
|
||||
* A parameter was configured on the port
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction a port direction
|
||||
* \param port_id the port id
|
||||
* \param id the id of the parameter
|
||||
* \param flags flags used when setting the param
|
||||
* \param param the new param
|
||||
*/
|
||||
void (*port_set_param) (void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param);
|
||||
/**
|
||||
* Notify the port of buffers
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction a port direction
|
||||
* \param port_id the port id
|
||||
* \param n_buffer the number of buffers
|
||||
* \param buffers and array of buffer descriptions
|
||||
*/
|
||||
void (*port_use_buffers) (void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t n_buffers,
|
||||
struct pw_client_node0_buffer *buffers);
|
||||
/**
|
||||
* Notify of a new port command
|
||||
*
|
||||
* \param direction a port direction
|
||||
* \param port_id the port id
|
||||
* \param command the command
|
||||
*/
|
||||
void (*port_command) (void *data,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
const struct spa_command *command);
|
||||
|
||||
/**
|
||||
* Configure the io area with \a id of \a port_id.
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction the direction of the port
|
||||
* \param port_id the port id
|
||||
* \param id the id of the io area to set
|
||||
* \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 (*port_set_io) (void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id,
|
||||
uint32_t mem_id,
|
||||
uint32_t offset,
|
||||
uint32_t size);
|
||||
};
|
||||
#define pw_client_node0_resource(r,m,v,...) pw_resource_call(r, struct pw_client_node0_events, m, v, ##__VA_ARGS__)
|
||||
|
||||
#define pw_client_node0_resource_add_mem(r,...) pw_client_node0_resource(r,add_mem,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_transport(r,...) pw_client_node0_resource(r,transport,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_set_param(r,...) pw_client_node0_resource(r,set_param,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_event(r,...) pw_client_node0_resource(r,event,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_command(r,...) pw_client_node0_resource(r,command,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_add_port(r,...) pw_client_node0_resource(r,add_port,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_remove_port(r,...) pw_client_node0_resource(r,remove_port,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_port_set_param(r,...) pw_client_node0_resource(r,port_set_param,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_port_use_buffers(r,...) pw_client_node0_resource(r,port_use_buffers,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_port_command(r,...) pw_client_node0_resource(r,port_command,0,__VA_ARGS__)
|
||||
#define pw_client_node0_resource_port_set_io(r,...) pw_client_node0_resource(r,port_set_io,0,__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __PIPEWIRE_EXT_CLIENT_NODE0_H__ */
|
||||
|
|
@ -1,514 +0,0 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2017 Wim Taymans <wim.taymans@gmail.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <spa/pod/parser.h>
|
||||
#include <spa/pod/builder.h>
|
||||
#include <spa/utils/type-info.h>
|
||||
|
||||
#include "pipewire/impl.h"
|
||||
|
||||
#include "pipewire/extensions/protocol-native.h"
|
||||
|
||||
#include "ext-client-node.h"
|
||||
|
||||
#include "transport.h"
|
||||
|
||||
#define PW_PROTOCOL_NATIVE_FLAG_REMAP (1<<0)
|
||||
|
||||
extern uint32_t pw_protocol_native0_find_type(struct pw_impl_client *client, const char *type);
|
||||
extern int pw_protocol_native0_pod_to_v2(struct pw_impl_client *client, const struct spa_pod *pod,
|
||||
struct spa_pod_builder *b);
|
||||
extern struct spa_pod * pw_protocol_native0_pod_from_v2(struct pw_impl_client *client,
|
||||
const struct spa_pod *pod);
|
||||
extern uint32_t pw_protocol_native0_type_to_v2(struct pw_impl_client *client,
|
||||
const struct spa_type_info *info, uint32_t type);
|
||||
|
||||
static void
|
||||
client_node_marshal_add_mem(void *data,
|
||||
uint32_t mem_id,
|
||||
uint32_t type,
|
||||
int memfd, uint32_t flags)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct pw_impl_client *client = pw_resource_get_client(resource);
|
||||
struct spa_pod_builder *b;
|
||||
const char *typename;
|
||||
|
||||
switch (type) {
|
||||
case SPA_DATA_MemFd:
|
||||
typename = "Spa:Enum:DataType:Fd:MemFd";
|
||||
break;
|
||||
case SPA_DATA_DmaBuf:
|
||||
typename = "Spa:Enum:DataType:Fd:DmaBuf";
|
||||
break;
|
||||
default:
|
||||
case SPA_DATA_MemPtr:
|
||||
return;
|
||||
|
||||
}
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_ADD_MEM, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
"i", mem_id,
|
||||
"I", pw_protocol_native0_find_type(client, typename),
|
||||
"i", pw_protocol_native_add_resource_fd(resource, memfd),
|
||||
"i", flags);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void client_node_marshal_transport(void *data, uint32_t node_id, int readfd, int writefd,
|
||||
struct pw_client_node0_transport *transport)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct spa_pod_builder *b;
|
||||
struct pw_client_node0_transport_info info;
|
||||
|
||||
pw_client_node0_transport_get_info(transport, &info);
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_TRANSPORT, NULL);
|
||||
|
||||
spa_pod_builder_add_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);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_set_param(void *data, uint32_t seq, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_SET_PARAM, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
"i", seq,
|
||||
"I", id,
|
||||
"i", flags,
|
||||
"P", param);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void client_node_marshal_event_event(void *data, const struct spa_event *event)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_EVENT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b, "P", event);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_command(void *data, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct pw_impl_client *client = pw_resource_get_client(resource);
|
||||
struct spa_pod_builder *b;
|
||||
struct spa_pod_frame f;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_COMMAND, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b, "i", seq, NULL);
|
||||
if (SPA_COMMAND_TYPE(command) == 0)
|
||||
spa_pod_builder_add(b, "P", command, NULL);
|
||||
else
|
||||
pw_protocol_native0_pod_to_v2(client, (struct spa_pod *)command, b);
|
||||
spa_pod_builder_pop(b, &f);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_add_port(void *data,
|
||||
uint32_t seq, enum spa_direction direction, uint32_t port_id)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_ADD_PORT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_remove_port(void *data,
|
||||
uint32_t seq, enum spa_direction direction, uint32_t port_id)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_REMOVE_PORT, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_port_set_param(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id,
|
||||
uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct pw_impl_client *client = pw_resource_get_client(resource);
|
||||
struct spa_pod_builder *b;
|
||||
struct spa_pod_frame f;
|
||||
const char *typename;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_PORT_SET_PARAM, NULL);
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_Props:
|
||||
typename = "Spa:Enum:ParamId:Props";
|
||||
break;
|
||||
case SPA_PARAM_Format:
|
||||
typename = "Spa:Enum:ParamId:Format";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id,
|
||||
"I", pw_protocol_native0_find_type(client, typename),
|
||||
"i", flags, NULL);
|
||||
pw_protocol_native0_pod_to_v2(client, param, b);
|
||||
spa_pod_builder_pop(b, &f);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_port_use_buffers(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t n_buffers, struct pw_client_node0_buffer *buffers)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct pw_impl_client *client = pw_resource_get_client(resource);
|
||||
struct spa_pod_builder *b;
|
||||
struct spa_pod_frame f;
|
||||
uint32_t i, j;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_PORT_USE_BUFFERS, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id,
|
||||
"i", n_buffers, NULL);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
struct spa_buffer *buf = buffers[i].buffer;
|
||||
|
||||
spa_pod_builder_add(b,
|
||||
"i", buffers[i].mem_id,
|
||||
"i", buffers[i].offset,
|
||||
"i", buffers[i].size,
|
||||
"i", i,
|
||||
"i", buf->n_metas, NULL);
|
||||
|
||||
for (j = 0; j < buf->n_metas; j++) {
|
||||
struct spa_meta *m = &buf->metas[j];
|
||||
spa_pod_builder_add(b,
|
||||
"I", pw_protocol_native0_type_to_v2(client, spa_type_meta_type, m->type),
|
||||
"i", m->size, NULL);
|
||||
}
|
||||
spa_pod_builder_add(b, "i", buf->n_datas, NULL);
|
||||
for (j = 0; j < buf->n_datas; j++) {
|
||||
struct spa_data *d = &buf->datas[j];
|
||||
spa_pod_builder_add(b,
|
||||
"I", pw_protocol_native0_type_to_v2(client, spa_type_data_type, d->type),
|
||||
"i", SPA_PTR_TO_UINT32(d->data),
|
||||
"i", d->flags,
|
||||
"i", d->mapoffset,
|
||||
"i", d->maxsize, NULL);
|
||||
}
|
||||
}
|
||||
spa_pod_builder_pop(b, &f);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_port_command(void *data,
|
||||
uint32_t direction,
|
||||
uint32_t port_id,
|
||||
const struct spa_command *command)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct pw_impl_client *client = pw_resource_get_client(resource);
|
||||
struct spa_pod_builder *b;
|
||||
struct spa_pod_frame f;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_PORT_COMMAND, NULL);
|
||||
|
||||
spa_pod_builder_push_struct(b, &f);
|
||||
spa_pod_builder_add(b,
|
||||
"i", direction,
|
||||
"i", port_id, NULL);
|
||||
pw_protocol_native0_pod_to_v2(client, (struct spa_pod *)command, b);
|
||||
spa_pod_builder_pop(b, &f);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_port_set_io(void *data,
|
||||
uint32_t seq,
|
||||
uint32_t direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id,
|
||||
uint32_t memid,
|
||||
uint32_t offset,
|
||||
uint32_t size)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_PORT_SET_IO, NULL);
|
||||
|
||||
spa_pod_builder_add_struct(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id,
|
||||
"I", id,
|
||||
"i", memid,
|
||||
"i", offset,
|
||||
"i", size);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
|
||||
static int client_node_demarshal_done(void *object, const struct pw_protocol_native_message *msg)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t seq, res;
|
||||
|
||||
spa_pod_parser_init(&prs, msg->data, msg->size);
|
||||
if (spa_pod_parser_get_struct(&prs,
|
||||
"i", &seq,
|
||||
"i", &res) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return pw_resource_notify(resource, struct pw_client_node0_methods, done, 0, seq, res);
|
||||
}
|
||||
|
||||
static int client_node_demarshal_update(void *object, const struct pw_protocol_native_message *msg)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
struct spa_pod_frame f;
|
||||
uint32_t change_mask, max_input_ports, max_output_ports, n_params;
|
||||
const struct spa_pod **params;
|
||||
uint32_t i;
|
||||
|
||||
spa_pod_parser_init(&prs, msg->data, msg->size);
|
||||
if (spa_pod_parser_push_struct(&prs, &f) < 0 ||
|
||||
spa_pod_parser_get(&prs,
|
||||
"i", &change_mask,
|
||||
"i", &max_input_ports,
|
||||
"i", &max_output_ports,
|
||||
"i", &n_params, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
params = alloca(n_params * sizeof(struct spa_pod *));
|
||||
for (i = 0; i < n_params; i++)
|
||||
if (spa_pod_parser_get(&prs, "O", ¶ms[i], NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return pw_resource_notify(resource, struct pw_client_node0_methods, update, 0, change_mask,
|
||||
max_input_ports,
|
||||
max_output_ports,
|
||||
n_params,
|
||||
params);
|
||||
}
|
||||
|
||||
static int client_node_demarshal_port_update(void *object, const struct pw_protocol_native_message *msg)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
struct spa_pod_frame f[2];
|
||||
uint32_t i, direction, port_id, change_mask, n_params;
|
||||
const struct spa_pod **params = NULL;
|
||||
struct spa_port_info info = { 0 }, *infop = NULL;
|
||||
struct spa_dict props;
|
||||
|
||||
spa_pod_parser_init(&prs, msg->data, msg->size);
|
||||
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
|
||||
spa_pod_parser_get(&prs,
|
||||
"i", &direction,
|
||||
"i", &port_id,
|
||||
"i", &change_mask,
|
||||
"i", &n_params, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
params = alloca(n_params * sizeof(struct spa_pod *));
|
||||
for (i = 0; i < n_params; i++)
|
||||
if (spa_pod_parser_get(&prs, "O", ¶ms[i], NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
if (spa_pod_parser_push_struct(&prs, &f[1]) >= 0) {
|
||||
infop = &info;
|
||||
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"i", &info.flags,
|
||||
"i", &info.rate,
|
||||
"i", &props.n_items, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (props.n_items > 0) {
|
||||
info.props = &props;
|
||||
|
||||
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
|
||||
for (i = 0; i < props.n_items; i++) {
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"s", &props.items[i].key,
|
||||
"s", &props.items[i].value,
|
||||
NULL) < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pw_resource_notify(resource, struct pw_client_node0_methods, port_update, 0, direction,
|
||||
port_id,
|
||||
change_mask,
|
||||
n_params,
|
||||
params, infop);
|
||||
}
|
||||
|
||||
static int client_node_demarshal_set_active(void *object, const struct pw_protocol_native_message *msg)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
int active;
|
||||
|
||||
spa_pod_parser_init(&prs, msg->data, msg->size);
|
||||
if (spa_pod_parser_get_struct(&prs,
|
||||
"b", &active) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return pw_resource_notify(resource, struct pw_client_node0_methods, set_active, 0, active);
|
||||
}
|
||||
|
||||
static int client_node_demarshal_event_method(void *object, const struct pw_protocol_native_message *msg)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct pw_impl_client *client = pw_resource_get_client(resource);
|
||||
struct spa_pod_parser prs;
|
||||
struct spa_event *event;
|
||||
int res;
|
||||
|
||||
spa_pod_parser_init(&prs, msg->data, msg->size);
|
||||
if (spa_pod_parser_get_struct(&prs,
|
||||
"O", &event) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
event = (struct spa_event*)pw_protocol_native0_pod_from_v2(client, (struct spa_pod *)event);
|
||||
|
||||
res = pw_resource_notify(resource, struct pw_client_node0_methods, event, 0, event);
|
||||
free(event);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int client_node_demarshal_destroy(void *object, const struct pw_protocol_native_message *msg)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
int res;
|
||||
|
||||
spa_pod_parser_init(&prs, msg->data, msg->size);
|
||||
if (spa_pod_parser_get_struct(&prs, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
res = pw_resource_notify(resource, struct pw_client_node0_methods, destroy, 0);
|
||||
pw_resource_destroy(resource);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_method_demarshal[] = {
|
||||
{ &client_node_demarshal_done, 0, 0 },
|
||||
{ &client_node_demarshal_update, 0, PW_PROTOCOL_NATIVE_FLAG_REMAP },
|
||||
{ &client_node_demarshal_port_update, 0, PW_PROTOCOL_NATIVE_FLAG_REMAP },
|
||||
{ &client_node_demarshal_set_active, 0, 0 },
|
||||
{ &client_node_demarshal_event_method, 0, PW_PROTOCOL_NATIVE_FLAG_REMAP },
|
||||
{ &client_node_demarshal_destroy, 0, 0 },
|
||||
};
|
||||
|
||||
static const struct pw_client_node0_events pw_protocol_native_client_node_event_marshal = {
|
||||
PW_VERSION_CLIENT_NODE0_EVENTS,
|
||||
&client_node_marshal_add_mem,
|
||||
&client_node_marshal_transport,
|
||||
&client_node_marshal_set_param,
|
||||
&client_node_marshal_event_event,
|
||||
&client_node_marshal_command,
|
||||
&client_node_marshal_add_port,
|
||||
&client_node_marshal_remove_port,
|
||||
&client_node_marshal_port_set_param,
|
||||
&client_node_marshal_port_use_buffers,
|
||||
&client_node_marshal_port_command,
|
||||
&client_node_marshal_port_set_io,
|
||||
};
|
||||
|
||||
static const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = {
|
||||
PW_TYPE_INTERFACE_ClientNode,
|
||||
PW_VERSION_CLIENT_NODE0,
|
||||
PW_CLIENT_NODE0_METHOD_NUM,
|
||||
PW_CLIENT_NODE0_EVENT_NUM,
|
||||
0,
|
||||
NULL,
|
||||
.server_demarshal = &pw_protocol_native_client_node_method_demarshal,
|
||||
.server_marshal = &pw_protocol_native_client_node_event_marshal,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct pw_protocol *pw_protocol_native_ext_client_node0_init(struct pw_context *context)
|
||||
{
|
||||
struct pw_protocol *protocol;
|
||||
|
||||
protocol = pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native);
|
||||
|
||||
if (protocol == NULL)
|
||||
return NULL;
|
||||
|
||||
pw_protocol_add_marshal(protocol, &pw_protocol_native_client_node_marshal);
|
||||
|
||||
return protocol;
|
||||
}
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2016 Wim Taymans <wim.taymans@gmail.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
#include <spa/node/io.h>
|
||||
|
||||
#include <pipewire/impl.h>
|
||||
|
||||
#include "ext-client-node.h"
|
||||
|
||||
#include "transport.h"
|
||||
|
||||
/** \cond */
|
||||
|
||||
#define INPUT_BUFFER_SIZE (1<<12)
|
||||
#define OUTPUT_BUFFER_SIZE (1<<12)
|
||||
|
||||
struct transport {
|
||||
struct pw_client_node0_transport trans;
|
||||
|
||||
struct pw_memblock *mem;
|
||||
size_t offset;
|
||||
|
||||
struct pw_client_node0_message current;
|
||||
uint32_t current_index;
|
||||
};
|
||||
/** \endcond */
|
||||
|
||||
static size_t area_get_size(struct pw_client_node0_area *area)
|
||||
{
|
||||
size_t size;
|
||||
size = sizeof(struct pw_client_node0_area);
|
||||
size += area->max_input_ports * sizeof(struct spa_io_buffers);
|
||||
size += area->max_output_ports * sizeof(struct spa_io_buffers);
|
||||
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_node0_transport *trans)
|
||||
{
|
||||
struct pw_client_node0_area *a;
|
||||
|
||||
trans->area = a = p;
|
||||
p = SPA_PTROFF(p, sizeof(struct pw_client_node0_area), struct spa_io_buffers);
|
||||
|
||||
trans->inputs = p;
|
||||
p = SPA_PTROFF(p, a->max_input_ports * sizeof(struct spa_io_buffers), void);
|
||||
|
||||
trans->outputs = p;
|
||||
p = SPA_PTROFF(p, a->max_output_ports * sizeof(struct spa_io_buffers), void);
|
||||
|
||||
trans->input_buffer = p;
|
||||
p = SPA_PTROFF(p, sizeof(struct spa_ringbuffer), void);
|
||||
|
||||
trans->input_data = p;
|
||||
p = SPA_PTROFF(p, INPUT_BUFFER_SIZE, void);
|
||||
|
||||
trans->output_buffer = p;
|
||||
p = SPA_PTROFF(p, sizeof(struct spa_ringbuffer), void);
|
||||
|
||||
trans->output_data = p;
|
||||
p = SPA_PTROFF(p, OUTPUT_BUFFER_SIZE, void);
|
||||
}
|
||||
|
||||
static void transport_reset_area(struct pw_client_node0_transport *trans)
|
||||
{
|
||||
uint32_t i;
|
||||
struct pw_client_node0_area *a = trans->area;
|
||||
|
||||
for (i = 0; i < a->max_input_ports; i++) {
|
||||
trans->inputs[i] = SPA_IO_BUFFERS_INIT;
|
||||
}
|
||||
for (i = 0; i < a->max_output_ports; i++) {
|
||||
trans->outputs[i] = SPA_IO_BUFFERS_INIT;
|
||||
}
|
||||
spa_ringbuffer_init(trans->input_buffer);
|
||||
spa_ringbuffer_init(trans->output_buffer);
|
||||
}
|
||||
|
||||
static void destroy(struct pw_client_node0_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_node0_transport *trans, struct pw_client_node0_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 < (int)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_node0_transport *trans, struct pw_client_node0_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 < (int) sizeof(struct pw_client_node0_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_node0_message));
|
||||
|
||||
if (avail < (int) SPA_POD_SIZE(&impl->current))
|
||||
return 0;
|
||||
|
||||
*message = impl->current;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_message(struct pw_client_node0_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
|
||||
* \param max_input_ports maximum number of input_ports
|
||||
* \param max_output_ports maximum number of output_ports
|
||||
* \return a newly allocated \ref pw_client_node0_transport
|
||||
* \memberof pw_client_node0_transport
|
||||
*/
|
||||
struct pw_client_node0_transport *
|
||||
pw_client_node0_transport_new(struct pw_context *context,
|
||||
uint32_t max_input_ports, uint32_t max_output_ports)
|
||||
{
|
||||
struct transport *impl;
|
||||
struct pw_client_node0_transport *trans;
|
||||
struct pw_client_node0_area area = { 0 };
|
||||
|
||||
area.max_input_ports = max_input_ports;
|
||||
area.n_input_ports = 0;
|
||||
area.max_output_ports = max_output_ports;
|
||||
area.n_output_ports = 0;
|
||||
|
||||
impl = calloc(1, sizeof(struct transport));
|
||||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
pw_log_debug("transport %p: new %d %d", impl, max_input_ports, max_output_ports);
|
||||
|
||||
trans = &impl->trans;
|
||||
impl->offset = 0;
|
||||
|
||||
impl->mem = pw_mempool_alloc(pw_context_get_mempool(context),
|
||||
PW_MEMBLOCK_FLAG_READWRITE |
|
||||
PW_MEMBLOCK_FLAG_SEAL |
|
||||
PW_MEMBLOCK_FLAG_MAP,
|
||||
SPA_DATA_MemFd, area_get_size(&area));
|
||||
if (impl->mem == NULL) {
|
||||
free(impl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(impl->mem->map->ptr, &area, sizeof(struct pw_client_node0_area));
|
||||
transport_setup_area(impl->mem->map->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_node0_transport *
|
||||
pw_client_node0_transport_new_from_info(struct pw_client_node0_transport_info *info)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
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_node0_transport
|
||||
*/
|
||||
int pw_client_node0_transport_get_info(struct pw_client_node0_transport *trans,
|
||||
struct pw_client_node0_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,39 +0,0 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2016 Wim Taymans <wim.taymans@gmail.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef __PIPEWIRE_CLIENT_NODE0_TRANSPORT_H__
|
||||
#define __PIPEWIRE_CLIENT_NODE0_TRANSPORT_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <spa/utils/defs.h>
|
||||
|
||||
#include <pipewire/mem.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** information about the transport region \memberof pw_client_node */
|
||||
struct pw_client_node0_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_node0_transport *
|
||||
pw_client_node0_transport_new(struct pw_context *context, uint32_t max_input_ports, uint32_t max_output_ports);
|
||||
|
||||
struct pw_client_node0_transport *
|
||||
pw_client_node0_transport_new_from_info(struct pw_client_node0_transport_info *info);
|
||||
|
||||
int
|
||||
pw_client_node0_transport_get_info(struct pw_client_node0_transport *trans,
|
||||
struct pw_client_node0_transport_info *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __PIPEWIRE_CLIENT_NODE0_TRANSPORT_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue