1 /* PipeWire 2 * 3 * Copyright © 2016 Wim Taymans <wim.taymans@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25 #ifndef __PIPEWIRE_EXT_CLIENT_NODE0_H__ 26 #define __PIPEWIRE_EXT_CLIENT_NODE0_H__ 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #include <spa/utils/defs.h> 33 #include <spa/param/param.h> 34 #include <spa/node/node.h> 35 36 #include <pipewire/proxy.h> 37 38 #define PW_TYPE_INTERFACE_ClientNode PW_TYPE_INFO_INTERFACE_BASE "ClientNode" 39 40 #define PW_VERSION_CLIENT_NODE0 0 41 42 struct pw_client_node0_message; 43 44 /** Shared structure between client and server \memberof pw_client_node */ 45 struct pw_client_node0_area { 46 uint32_t max_input_ports; /**< max input ports of the node */ 47 uint32_t n_input_ports; /**< number of input ports of the node */ 48 uint32_t max_output_ports; /**< max output ports of the node */ 49 uint32_t n_output_ports; /**< number of output ports of the node */ 50 }; 51 52 /** \class pw_client_node0_transport 53 * 54 * \brief Transport object 55 * 56 * The transport object contains shared data and ringbuffers to exchange 57 * events and data between the server and the client in a low-latency and 58 * lockfree way. 59 */ 60 struct pw_client_node0_transport { 61 struct pw_client_node0_area *area; /**< the transport area */ 62 struct spa_io_buffers *inputs; /**< array of buffer input io */ 63 struct spa_io_buffers *outputs; /**< array of buffer output io */ 64 void *input_data; /**< input memory for ringbuffer */ 65 struct spa_ringbuffer *input_buffer; /**< ringbuffer for input memory */ 66 void *output_data; /**< output memory for ringbuffer */ 67 struct spa_ringbuffer *output_buffer; /**< ringbuffer for output memory */ 68 69 /** Destroy a transport 70 * \param trans a transport to destroy 71 * \memberof pw_client_node0_transport 72 */ 73 void (*destroy) (struct pw_client_node0_transport *trans); 74 75 /** Add a message to the transport 76 * \param trans the transport to send the message on 77 * \param message the message to add 78 * \return 0 on success, < 0 on error 79 * 80 * Write \a message to the shared ringbuffer. 81 */ 82 int (*add_message) (struct pw_client_node0_transport *trans, struct pw_client_node0_message *message); 83 84 /** Get next message from a transport 85 * \param trans the transport to get the message of 86 * \param[out] message the message to read 87 * \return < 0 on error, 1 when a message is available, 88 * 0 when no more messages are available. 89 * 90 * Get the skeleton next message from \a trans into \a message. This function will 91 * only read the head and object body of the message. 92 * 93 * After the complete size of the message has been calculated, you should call 94 * \ref parse_message() to read the complete message contents. 95 */ 96 int (*next_message) (struct pw_client_node0_transport *trans, struct pw_client_node0_message *message); 97 98 /** Parse the complete message on transport 99 * \param trans the transport to read from 100 * \param[out] message memory that can hold the complete message 101 * \return 0 on success, < 0 on error 102 * 103 * Use this function after \ref next_message(). 104 */ 105 int (*parse_message) (struct pw_client_node0_transport *trans, void *message); 106 }; 107 108 #define pw_client_node0_transport_destroy(t) ((t)->destroy((t))) 109 #define pw_client_node0_transport_add_message(t,m) ((t)->add_message((t), (m))) 110 #define pw_client_node0_transport_next_message(t,m) ((t)->next_message((t), (m))) 111 #define pw_client_node0_transport_parse_message(t,m) ((t)->parse_message((t), (m))) 112 113 enum pw_client_node0_message_type { 114 PW_CLIENT_NODE0_MESSAGE_HAVE_OUTPUT, /*< signal that the node has output */ 115 PW_CLIENT_NODE0_MESSAGE_NEED_INPUT, /*< signal that the node needs input */ 116 PW_CLIENT_NODE0_MESSAGE_PROCESS_INPUT, /*< instruct the node to process input */ 117 PW_CLIENT_NODE0_MESSAGE_PROCESS_OUTPUT, /*< instruct the node output is processed */ 118 PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER, /*< reuse a buffer */ 119 }; 120 121 struct pw_client_node0_message_body { 122 struct spa_pod_int type SPA_ALIGNED(8); /*< one of enum pw_client_node0_message_type */ 123 }; 124 125 struct pw_client_node0_message { 126 struct spa_pod_struct pod; 127 struct pw_client_node0_message_body body; 128 }; 129 130 struct pw_client_node0_message_port_reuse_buffer_body { 131 struct spa_pod_int type SPA_ALIGNED(8); /*< PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER */ 132 struct spa_pod_int port_id SPA_ALIGNED(8); /*< port id */ 133 struct spa_pod_int buffer_id SPA_ALIGNED(8); /*< buffer id to reuse */ 134 }; 135 136 struct pw_client_node0_message_port_reuse_buffer { 137 struct spa_pod_struct pod; 138 struct pw_client_node0_message_port_reuse_buffer_body body; 139 }; 140 141 #define PW_CLIENT_NODE0_MESSAGE_TYPE(message) (((struct pw_client_node0_message*)(message))->body.type.value) 142 143 #define PW_CLIENT_NODE0_MESSAGE_INIT(message) (struct pw_client_node0_message) \ 144 { { { sizeof(struct pw_client_node0_message_body), SPA_TYPE_Struct } }, \ 145 { SPA_POD_INIT_Int(message) } } 146 147 #define PW_CLIENT_NODE0_MESSAGE_INIT_FULL(type,size,message,...) (type) \ 148 { { { size, SPA_TYPE_Struct } }, \ 149 { SPA_POD_INIT_Int(message), ##__VA_ARGS__ } } \ 150 151 #define PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER_INIT(port_id,buffer_id) \ 152 PW_CLIENT_NODE0_MESSAGE_INIT_FULL(struct pw_client_node0_message_port_reuse_buffer, \ 153 sizeof(struct pw_client_node0_message_port_reuse_buffer_body), \ 154 PW_CLIENT_NODE0_MESSAGE_PORT_REUSE_BUFFER, \ 155 SPA_POD_INIT_Int(port_id), \ 156 SPA_POD_INIT_Int(buffer_id)) 157 158 /** information about a buffer */ 159 struct pw_client_node0_buffer { 160 uint32_t mem_id; /**< the memory id for the metadata */ 161 uint32_t offset; /**< offset in memory */ 162 uint32_t size; /**< size in memory */ 163 struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */ 164 }; 165 166 #define PW_CLIENT_NODE0_METHOD_DONE 0 167 #define PW_CLIENT_NODE0_METHOD_UPDATE 1 168 #define PW_CLIENT_NODE0_METHOD_PORT_UPDATE 2 169 #define PW_CLIENT_NODE0_METHOD_SET_ACTIVE 3 170 #define PW_CLIENT_NODE0_METHOD_EVENT 4 171 #define PW_CLIENT_NODE0_METHOD_DESTROY 5 172 #define PW_CLIENT_NODE0_METHOD_NUM 6 173 174 /** \ref pw_client_node methods */ 175 struct pw_client_node0_methods { 176 #define PW_VERSION_CLIENT_NODE0_METHODS 0 177 uint32_t version; 178 179 /** Complete an async operation */ 180 void (*done) (void *object, int seq, int res); 181 182 /** 183 * Update the node ports and properties 184 * 185 * Update the maximum number of ports and the params of the 186 * client node. 187 * \param change_mask bitfield with changed parameters 188 * \param max_input_ports new max input ports 189 * \param max_output_ports new max output ports 190 * \param params new params 191 */ 192 void (*update) (void *object, 193 #define PW_CLIENT_NODE0_UPDATE_MAX_INPUTS (1 << 0) 194 #define PW_CLIENT_NODE0_UPDATE_MAX_OUTPUTS (1 << 1) 195 #define PW_CLIENT_NODE0_UPDATE_PARAMS (1 << 2) 196 uint32_t change_mask, 197 uint32_t max_input_ports, 198 uint32_t max_output_ports, 199 uint32_t n_params, 200 const struct spa_pod **params); 201 202 /** 203 * Update a node port 204 * 205 * Update the information of one port of a node. 206 * \param direction the direction of the port 207 * \param port_id the port id to update 208 * \param change_mask a bitfield of changed items 209 * \param n_params number of port parameters 210 * \param params array of port parameters 211 * \param info port information 212 */ 213 void (*port_update) (void *object, 214 enum spa_direction direction, 215 uint32_t port_id, 216 #define PW_CLIENT_NODE0_PORT_UPDATE_PARAMS (1 << 0) 217 #define PW_CLIENT_NODE0_PORT_UPDATE_INFO (1 << 1) 218 uint32_t change_mask, 219 uint32_t n_params, 220 const struct spa_pod **params, 221 const struct spa_port_info *info); 222 /** 223 * Activate or deactivate the node 224 */ 225 void (*set_active) (void *object, bool active); 226 /** 227 * Send an event to the node 228 * \param event the event to send 229 */ 230 void (*event) (void *object, struct spa_event *event); 231 /** 232 * Destroy the client_node 233 */ 234 void (*destroy) (void *object); 235 }; 236 237 #define PW_CLIENT_NODE0_EVENT_ADD_MEM 0 238 #define PW_CLIENT_NODE0_EVENT_TRANSPORT 1 239 #define PW_CLIENT_NODE0_EVENT_SET_PARAM 2 240 #define PW_CLIENT_NODE0_EVENT_EVENT 3 241 #define PW_CLIENT_NODE0_EVENT_COMMAND 4 242 #define PW_CLIENT_NODE0_EVENT_ADD_PORT 5 243 #define PW_CLIENT_NODE0_EVENT_REMOVE_PORT 6 244 #define PW_CLIENT_NODE0_EVENT_PORT_SET_PARAM 7 245 #define PW_CLIENT_NODE0_EVENT_PORT_USE_BUFFERS 8 246 #define PW_CLIENT_NODE0_EVENT_PORT_COMMAND 9 247 #define PW_CLIENT_NODE0_EVENT_PORT_SET_IO 10 248 #define PW_CLIENT_NODE0_EVENT_NUM 11 249 250 /** \ref pw_client_node events */ 251 struct pw_client_node0_events { 252 #define PW_VERSION_CLIENT_NODE0_EVENTS 0 253 uint32_t version; 254 /** 255 * Memory was added to a node 256 * 257 * \param mem_id the id of the memory 258 * \param type the memory type 259 * \param memfd the fd of the memory 260 * \param flags flags for the \a memfd 261 */ 262 void (*add_mem) (void *object, 263 uint32_t mem_id, 264 uint32_t type, 265 int memfd, 266 uint32_t flags); 267 /** 268 * Notify of a new transport area 269 * 270 * The transport area is used to exchange real-time commands between 271 * the client and the server. 272 * 273 * \param node_id the node id created for this client node 274 * \param readfd fd for signal data can be read 275 * \param writefd fd for signal data can be written 276 * \param transport the shared transport area 277 */ 278 void (*transport) (void *object, 279 uint32_t node_id, 280 int readfd, 281 int writefd, 282 struct pw_client_node0_transport *transport); 283 /** 284 * Notify of a property change 285 * 286 * When the server configures the properties on the node 287 * this event is sent 288 * 289 * \param seq a sequence number 290 * \param id the id of the parameter 291 * \param flags parameter flags 292 * \param param the param to set 293 */ 294 void (*set_param) (void *object, uint32_t seq, 295 uint32_t id, uint32_t flags, 296 const struct spa_pod *param); 297 /** 298 * Receive an event from the client node 299 * \param event the received event */ 300 void (*event) (void *object, const struct spa_event *event); 301 /** 302 * Notify of a new node command 303 * 304 * \param seq a sequence number 305 * \param command the command 306 */ 307 void (*command) (void *object, uint32_t seq, const struct spa_command *command); 308 /** 309 * A new port was added to the node 310 * 311 * The server can at any time add a port to the node when there 312 * are free ports available. 313 * 314 * \param seq a sequence number 315 * \param direction the direction of the port 316 * \param port_id the new port id 317 */ 318 void (*add_port) (void *object, 319 uint32_t seq, 320 enum spa_direction direction, 321 uint32_t port_id); 322 /** 323 * A port was removed from the node 324 * 325 * \param seq a sequence number 326 * \param direction a port direction 327 * \param port_id the remove port id 328 */ 329 void (*remove_port) (void *object, 330 uint32_t seq, 331 enum spa_direction direction, 332 uint32_t port_id); 333 /** 334 * A parameter was configured on the port 335 * 336 * \param seq a sequence number 337 * \param direction a port direction 338 * \param port_id the port id 339 * \param id the id of the parameter 340 * \param flags flags used when setting the param 341 * \param param the new param 342 */ 343 void (*port_set_param) (void *object, 344 uint32_t seq, 345 enum spa_direction direction, 346 uint32_t port_id, 347 uint32_t id, uint32_t flags, 348 const struct spa_pod *param); 349 /** 350 * Notify the port of buffers 351 * 352 * \param seq a sequence number 353 * \param direction a port direction 354 * \param port_id the port id 355 * \param n_buffer the number of buffers 356 * \param buffers and array of buffer descriptions 357 */ 358 void (*port_use_buffers) (void *object, 359 uint32_t seq, 360 enum spa_direction direction, 361 uint32_t port_id, 362 uint32_t n_buffers, 363 struct pw_client_node0_buffer *buffers); 364 /** 365 * Notify of a new port command 366 * 367 * \param direction a port direction 368 * \param port_id the port id 369 * \param command the command 370 */ 371 void (*port_command) (void *object, 372 enum spa_direction direction, 373 uint32_t port_id, 374 const struct spa_command *command); 375 376 /** 377 * Configure the io area with \a id of \a port_id. 378 * 379 * \param seq a sequence number 380 * \param direction the direction of the port 381 * \param port_id the port id 382 * \param id the id of the io area to set 383 * \param mem_id the id of the memory to use 384 * \param offset offset of io area in memory 385 * \param size size of the io area 386 */ 387 void (*port_set_io) (void *object, 388 uint32_t seq, 389 enum spa_direction direction, 390 uint32_t port_id, 391 uint32_t id, 392 uint32_t mem_id, 393 uint32_t offset, 394 uint32_t size); 395 }; 396 #define pw_client_node0_resource(r,m,v,...) pw_resource_call(r, struct pw_client_node0_events, m, v, ##__VA_ARGS__) 397 398 #define pw_client_node0_resource_add_mem(r,...) pw_client_node0_resource(r,add_mem,0,__VA_ARGS__) 399 #define pw_client_node0_resource_transport(r,...) pw_client_node0_resource(r,transport,0,__VA_ARGS__) 400 #define pw_client_node0_resource_set_param(r,...) pw_client_node0_resource(r,set_param,0,__VA_ARGS__) 401 #define pw_client_node0_resource_event(r,...) pw_client_node0_resource(r,event,0,__VA_ARGS__) 402 #define pw_client_node0_resource_command(r,...) pw_client_node0_resource(r,command,0,__VA_ARGS__) 403 #define pw_client_node0_resource_add_port(r,...) pw_client_node0_resource(r,add_port,0,__VA_ARGS__) 404 #define pw_client_node0_resource_remove_port(r,...) pw_client_node0_resource(r,remove_port,0,__VA_ARGS__) 405 #define pw_client_node0_resource_port_set_param(r,...) pw_client_node0_resource(r,port_set_param,0,__VA_ARGS__) 406 #define pw_client_node0_resource_port_use_buffers(r,...) pw_client_node0_resource(r,port_use_buffers,0,__VA_ARGS__) 407 #define pw_client_node0_resource_port_command(r,...) pw_client_node0_resource(r,port_command,0,__VA_ARGS__) 408 #define pw_client_node0_resource_port_set_io(r,...) pw_client_node0_resource(r,port_set_io,0,__VA_ARGS__) 409 410 #ifdef __cplusplus 411 } /* extern "C" */ 412 #endif 413 414 #endif /* __PIPEWIRE_EXT_CLIENT_NODE0_H__ */ 415