1 /* PipeWire
2 *
3 * Copyright © 2018 Wim Taymans
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_PRIVATE_H
26 #define PIPEWIRE_PRIVATE_H
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #include <sys/socket.h>
33 #include <sys/types.h> /* for pthread_t */
34
35 #include "pipewire/impl.h"
36
37 #include <spa/support/plugin.h>
38 #include <spa/pod/builder.h>
39 #include <spa/param/latency-utils.h>
40 #include <spa/utils/result.h>
41 #include <spa/utils/type-info.h>
42
43 #ifdef __FreeBSD__
44 struct ucred {
45 };
46 #endif
47
48 #ifdef __DragonFly__
49 #include <sys/ucred.h>
50 #endif
51
52 #ifndef spa_debug
53 #define spa_debug(...) pw_log_trace(__VA_ARGS__)
54 #endif
55
56 #define MAX_RATES 16u
57 #define CLOCK_MIN_QUANTUM 4u
58 #define CLOCK_MAX_QUANTUM 8192u
59
60 struct settings {
61 uint32_t log_level;
62 uint32_t clock_rate; /* default clock rate */
63 uint32_t clock_rates[MAX_RATES]; /* allowed clock rates */
64 uint32_t n_clock_rates; /* number of alternative clock rates */
65 uint32_t clock_quantum; /* default quantum */
66 uint32_t clock_min_quantum; /* min quantum */
67 uint32_t clock_max_quantum; /* max quantum */
68 struct spa_rectangle video_size;
69 struct spa_fraction video_rate;
70 uint32_t link_max_buffers;
71 unsigned int mem_warn_mlock:1;
72 unsigned int mem_allow_mlock:1;
73 unsigned int clock_power_of_two_quantum:1;
74 #define CLOCK_RATE_UPDATE_MODE_HARD 0
75 #define CLOCK_RATE_UPDATE_MODE_SOFT 1
76 int clock_rate_update_mode;
77 uint32_t clock_force_rate; /* force a clock rate */
78 uint32_t clock_force_quantum; /* force a quantum */
79 };
80
81 struct ratelimit {
82 uint64_t interval;
83 uint64_t begin;
84 unsigned burst;
85 unsigned n_printed, n_missed;
86 };
87
ratelimit_test(struct ratelimit * r,uint64_t now,enum spa_log_level level)88 static inline bool ratelimit_test(struct ratelimit *r, uint64_t now, enum spa_log_level level)
89 {
90 if (r->begin + r->interval < now) {
91 if (r->n_missed)
92 pw_log(level, "%u events suppressed", r->n_missed);
93 r->begin = now;
94 r->n_printed = 0;
95 r->n_missed = 0;
96 } else if (r->n_printed >= r->burst) {
97 r->n_missed++;
98 return false;
99 }
100 r->n_printed++;
101 return true;
102 }
103
104 #define MAX_PARAMS 32
105
106 struct pw_param {
107 uint32_t id;
108 struct spa_list link;
109 struct spa_pod *param;
110 };
111
pw_param_clear(struct spa_list * param_list,uint32_t id)112 static inline uint32_t pw_param_clear(struct spa_list *param_list, uint32_t id)
113 {
114 struct pw_param *p, *t;
115 uint32_t count = 0;
116
117 spa_list_for_each_safe(p, t, param_list, link) {
118 if (id == SPA_ID_INVALID || p->id == id) {
119 spa_list_remove(&p->link);
120 free(p);
121 count++;
122 }
123 }
124 return count;
125 }
126
pw_param_add(struct spa_list * params,uint32_t id,const struct spa_pod * param)127 static inline struct pw_param *pw_param_add(struct spa_list *params,
128 uint32_t id, const struct spa_pod *param)
129 {
130 struct pw_param *p;
131
132 if (id == SPA_ID_INVALID) {
133 if (param == NULL || !spa_pod_is_object(param)) {
134 errno = EINVAL;
135 return NULL;
136 }
137 id = SPA_POD_OBJECT_ID(param);
138 }
139
140 if ((p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0))) == NULL)
141 return NULL;
142
143 p->id = id;
144 if (param != NULL) {
145 p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod);
146 memcpy(p->param, param, SPA_POD_SIZE(param));
147 } else {
148 pw_param_clear(params, id);
149 p->param = NULL;
150 }
151 spa_list_append(params, &p->link);
152 return p;
153 }
154
pw_param_update(struct spa_list * param_list,struct spa_list * pending_list)155 static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list)
156 {
157 struct pw_param *p;
158
159 spa_list_consume(p, pending_list, link) {
160 spa_list_remove(&p->link);
161 if (p->param == NULL) {
162 pw_param_clear(param_list, p->id);
163 free(p);
164 } else {
165 spa_list_append(param_list, &p->link);
166 }
167 }
168 }
169
pw_param_info_find(struct spa_param_info info[],uint32_t n_info,uint32_t id)170 static inline struct spa_param_info *pw_param_info_find(struct spa_param_info info[],
171 uint32_t n_info, uint32_t id)
172 {
173 uint32_t i;
174 for (i = 0; i < n_info; i++) {
175 if (info[i].id == id)
176 return &info[i];
177 }
178 return NULL;
179 }
180
181 #define pw_protocol_emit_destroy(p) spa_hook_list_call(&p->listener_list, struct pw_protocol_events, destroy, 0)
182
183 struct pw_protocol {
184 struct spa_list link; /**< link in context protocol_list */
185 struct pw_context *context; /**< context for this protocol */
186
187 char *name; /**< type name of the protocol */
188
189 struct spa_list marshal_list; /**< list of marshallers for supported interfaces */
190 struct spa_list client_list; /**< list of current clients */
191 struct spa_list server_list; /**< list of current servers */
192 struct spa_hook_list listener_list; /**< event listeners */
193
194 const struct pw_protocol_implementation *implementation; /**< implementation of the protocol */
195
196 const void *extension; /**< extension API */
197
198 void *user_data; /**< user data for the implementation */
199 };
200
201 /** the permission function. It returns the allowed access permissions for \a global
202 * for \a client */
203 typedef uint32_t (*pw_permission_func_t) (struct pw_global *global,
204 struct pw_impl_client *client, void *data);
205
206 #define pw_impl_client_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_client_events, m, v, ##__VA_ARGS__)
207
208 #define pw_impl_client_emit_destroy(o) pw_impl_client_emit(o, destroy, 0)
209 #define pw_impl_client_emit_free(o) pw_impl_client_emit(o, free, 0)
210 #define pw_impl_client_emit_initialized(o) pw_impl_client_emit(o, initialized, 0)
211 #define pw_impl_client_emit_info_changed(o,i) pw_impl_client_emit(o, info_changed, 0, i)
212 #define pw_impl_client_emit_resource_added(o,r) pw_impl_client_emit(o, resource_added, 0, r)
213 #define pw_impl_client_emit_resource_impl(o,r) pw_impl_client_emit(o, resource_impl, 0, r)
214 #define pw_impl_client_emit_resource_removed(o,r) pw_impl_client_emit(o, resource_removed, 0, r)
215 #define pw_impl_client_emit_busy_changed(o,b) pw_impl_client_emit(o, busy_changed, 0, b)
216
217 enum spa_node0_event {
218 SPA_NODE0_EVENT_START = SPA_TYPE_VENDOR_PipeWire,
219 SPA_NODE0_EVENT_RequestClockUpdate,
220 };
221
222 enum spa_node0_command {
223 SPA_NODE0_COMMAND_START = SPA_TYPE_VENDOR_PipeWire,
224 SPA_NODE0_COMMAND_ClockUpdate,
225 };
226
227 struct protocol_compat_v2 {
228 /* v2 typemap */
229 struct pw_map types;
230 unsigned int send_types:1;
231 };
232
233 #define pw_impl_core_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_core_events, m, v, ##__VA_ARGS__)
234
235 #define pw_impl_core_emit_destroy(s) pw_impl_core_emit(s, destroy, 0)
236 #define pw_impl_core_emit_free(s) pw_impl_core_emit(s, free, 0)
237 #define pw_impl_core_emit_initialized(s) pw_impl_core_emit(s, initialized, 0)
238
239 struct pw_impl_core {
240 struct pw_context *context;
241 struct spa_list link; /**< link in context object core_impl list */
242 struct pw_global *global; /**< global object created for this core */
243 struct spa_hook global_listener;
244
245 struct pw_properties *properties; /**< core properties */
246 struct pw_core_info info; /**< core info */
247
248 struct spa_hook_list listener_list;
249 void *user_data; /**< extra user data */
250
251 unsigned int registered:1;
252 };
253
254 #define pw_impl_metadata_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_metadata_events, m, v, ##__VA_ARGS__)
255
256 #define pw_impl_metadata_emit_destroy(s) pw_impl_metadata_emit(s, destroy, 0)
257 #define pw_impl_metadata_emit_free(s) pw_impl_metadata_emit(s, free, 0)
258 #define pw_impl_metadata_emit_property(s, ...) pw_impl_metadata_emit(s, property, 0, __VA_ARGS__)
259
260 struct pw_impl_metadata {
261 struct pw_context *context; /**< the context */
262 struct spa_list link; /**< link in context metadata_list */
263 struct pw_global *global; /**< global for this metadata */
264 struct spa_hook global_listener;
265
266 struct pw_properties *properties; /**< properties of the metadata */
267
268 struct pw_metadata *metadata;
269 struct spa_hook metadata_listener;
270
271 struct spa_hook_list listener_list; /**< event listeners */
272 void *user_data;
273
274 unsigned int registered:1;
275 };
276
277 struct pw_impl_client {
278 struct pw_impl_core *core; /**< core object */
279 struct pw_context *context; /**< context object */
280
281 struct spa_list link; /**< link in context object client list */
282 struct pw_global *global; /**< global object created for this client */
283 struct spa_hook global_listener;
284
285 pw_permission_func_t permission_func; /**< get permissions of an object */
286 void *permission_data; /**< data passed to permission function */
287
288 struct pw_properties *properties; /**< Client properties */
289
290 struct pw_client_info info; /**< client info */
291
292 struct pw_mempool *pool; /**< client mempool */
293 struct pw_resource *core_resource; /**< core resource object */
294 struct pw_resource *client_resource; /**< client resource object */
295
296 struct pw_map objects; /**< list of resource objects */
297
298 struct spa_hook_list listener_list;
299
300 struct pw_protocol *protocol; /**< protocol in use */
301 int recv_seq; /**< last received sequence number */
302 int send_seq; /**< last sender sequence number */
303
304 void *user_data; /**< extra user data */
305
306 struct ucred ucred; /**< ucred information */
307 unsigned int registered:1;
308 unsigned int ucred_valid:1; /**< if the ucred member is valid */
309 unsigned int busy:1;
310
311 /* v2 compatibility data */
312 void *compat_v2;
313 };
314
315 #define pw_global_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_global_events, m, v, ##__VA_ARGS__)
316
317 #define pw_global_emit_registering(g) pw_global_emit(g, registering, 0)
318 #define pw_global_emit_destroy(g) pw_global_emit(g, destroy, 0)
319 #define pw_global_emit_free(g) pw_global_emit(g, free, 0)
320 #define pw_global_emit_permissions_changed(g,...) pw_global_emit(g, permissions_changed, 0, __VA_ARGS__)
321
322 struct pw_global {
323 struct pw_context *context; /**< the context */
324
325 struct spa_list link; /**< link in context list of globals */
326 uint32_t id; /**< server id of the object */
327
328 struct pw_properties *properties; /**< properties of the global */
329
330 struct spa_hook_list listener_list;
331
332 const char *type; /**< type of interface */
333 uint32_t version; /**< version of interface */
334
335 pw_global_bind_func_t func; /**< bind function */
336 void *object; /**< object associated with the interface */
337 uint64_t serial; /**< increasing serial number */
338
339 struct spa_list resource_list; /**< The list of resources of this global */
340
341 unsigned int registered:1;
342 unsigned int destroyed:1;
343 };
344
345 #define pw_core_resource(r,m,v,...) pw_resource_call(r, struct pw_core_events, m, v, ##__VA_ARGS__)
346 #define pw_core_resource_info(r,...) pw_core_resource(r,info,0,__VA_ARGS__)
347 #define pw_core_resource_done(r,...) pw_core_resource(r,done,0,__VA_ARGS__)
348 #define pw_core_resource_ping(r,...) pw_core_resource(r,ping,0,__VA_ARGS__)
349 #define pw_core_resource_error(r,...) pw_core_resource(r,error,0,__VA_ARGS__)
350 #define pw_core_resource_remove_id(r,...) pw_core_resource(r,remove_id,0,__VA_ARGS__)
351 #define pw_core_resource_bound_id(r,...) pw_core_resource(r,bound_id,0,__VA_ARGS__)
352 #define pw_core_resource_add_mem(r,...) pw_core_resource(r,add_mem,0,__VA_ARGS__)
353 #define pw_core_resource_remove_mem(r,...) pw_core_resource(r,remove_mem,0,__VA_ARGS__)
354
355 static inline SPA_PRINTF_FUNC(5,0) void
pw_core_resource_errorv(struct pw_resource * resource,uint32_t id,int seq,int res,const char * message,va_list args)356 pw_core_resource_errorv(struct pw_resource *resource, uint32_t id, int seq,
357 int res, const char *message, va_list args)
358 {
359 char buffer[1024];
360 vsnprintf(buffer, sizeof(buffer), message, args);
361 buffer[1023] = '\0';
362 pw_log_debug("resource %p: id:%d seq:%d res:%d (%s) msg:\"%s\"",
363 resource, id, seq, res, spa_strerror(res), buffer);
364 pw_core_resource_error(resource, id, seq, res, buffer);
365 }
366
367 static inline SPA_PRINTF_FUNC(5,6) void
pw_core_resource_errorf(struct pw_resource * resource,uint32_t id,int seq,int res,const char * message,...)368 pw_core_resource_errorf(struct pw_resource *resource, uint32_t id, int seq,
369 int res, const char *message, ...)
370 {
371 va_list args;
372 va_start(args, message);
373 pw_core_resource_errorv(resource, id, seq, res, message, args);
374 va_end(args);
375 }
376
377 #define pw_context_driver_emit(c,m,v,...) spa_hook_list_call_simple(&c->driver_listener_list, struct pw_context_driver_events, m, v, ##__VA_ARGS__)
378 #define pw_context_driver_emit_start(c,n) pw_context_driver_emit(c, start, 0, n)
379 #define pw_context_driver_emit_xrun(c,n) pw_context_driver_emit(c, xrun, 0, n)
380 #define pw_context_driver_emit_incomplete(c,n) pw_context_driver_emit(c, incomplete, 0, n)
381 #define pw_context_driver_emit_timeout(c,n) pw_context_driver_emit(c, timeout, 0, n)
382 #define pw_context_driver_emit_drained(c,n) pw_context_driver_emit(c, drained, 0, n)
383 #define pw_context_driver_emit_complete(c,n) pw_context_driver_emit(c, complete, 0, n)
384
385 struct pw_context_driver_events {
386 #define PW_VERSION_CONTEXT_DRIVER_EVENTS 0
387 uint32_t version;
388
389 /** The driver graph is started */
390 void (*start) (void *data, struct pw_impl_node *node);
391 /** The driver under/overruns */
392 void (*xrun) (void *data, struct pw_impl_node *node);
393 /** The driver could not complete the graph */
394 void (*incomplete) (void *data, struct pw_impl_node *node);
395 /** The driver got a sync timeout */
396 void (*timeout) (void *data, struct pw_impl_node *node);
397 /** a node drained */
398 void (*drained) (void *data, struct pw_impl_node *node);
399 /** The driver completed the graph */
400 void (*complete) (void *data, struct pw_impl_node *node);
401 };
402
403 #define pw_registry_resource(r,m,v,...) pw_resource_call(r, struct pw_registry_events,m,v,##__VA_ARGS__)
404 #define pw_registry_resource_global(r,...) pw_registry_resource(r,global,0,__VA_ARGS__)
405 #define pw_registry_resource_global_remove(r,...) pw_registry_resource(r,global_remove,0,__VA_ARGS__)
406
407 #define pw_context_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_context_events, m, v, ##__VA_ARGS__)
408 #define pw_context_emit_destroy(c) pw_context_emit(c, destroy, 0)
409 #define pw_context_emit_free(c) pw_context_emit(c, free, 0)
410 #define pw_context_emit_info_changed(c,i) pw_context_emit(c, info_changed, 0, i)
411 #define pw_context_emit_check_access(c,cl) pw_context_emit(c, check_access, 0, cl)
412 #define pw_context_emit_global_added(c,g) pw_context_emit(c, global_added, 0, g)
413 #define pw_context_emit_global_removed(c,g) pw_context_emit(c, global_removed, 0, g)
414
415 struct pw_context {
416 struct pw_impl_core *core; /**< core object */
417
418 struct pw_properties *conf; /**< configuration of the context */
419 struct pw_properties *properties; /**< properties of the context */
420
421 struct settings defaults; /**< default parameters */
422 struct settings settings; /**< current parameters */
423
424 void *settings_impl; /**< settings metadata */
425
426 struct pw_mempool *pool; /**< global memory pool */
427
428 struct pw_map globals; /**< map of globals */
429
430 struct spa_list core_impl_list; /**< list of core_imp */
431 struct spa_list protocol_list; /**< list of protocols */
432 struct spa_list core_list; /**< list of core connections */
433 struct spa_list registry_resource_list; /**< list of registry resources */
434 struct spa_list module_list; /**< list of modules */
435 struct spa_list device_list; /**< list of devices */
436 struct spa_list global_list; /**< list of globals */
437 struct spa_list client_list; /**< list of clients */
438 struct spa_list node_list; /**< list of nodes */
439 struct spa_list factory_list; /**< list of factories */
440 struct spa_list metadata_list; /**< list of metadata */
441 struct spa_list link_list; /**< list of links */
442 struct spa_list control_list[2]; /**< list of controls, indexed by direction */
443 struct spa_list export_list; /**< list of export types */
444 struct spa_list driver_list; /**< list of driver nodes */
445
446 struct spa_hook_list driver_listener_list;
447 struct spa_hook_list listener_list;
448
449 struct pw_loop *main_loop; /**< main loop for control */
450 struct pw_loop *data_loop; /**< data loop for data passing */
451 struct pw_data_loop *data_loop_impl;
452 struct spa_system *data_system; /**< data system for data passing */
453 struct pw_work_queue *work_queue; /**< work queue */
454
455 struct spa_support support[16]; /**< support for spa plugins */
456 uint32_t n_support; /**< number of support items */
457 struct pw_array factory_lib; /**< mapping of factory_name regexp to library */
458
459 struct pw_array objects; /**< objects */
460
461 struct pw_impl_client *current_client; /**< client currently executing code in mainloop */
462
463 long sc_pagesize;
464 unsigned int freewheeling:1;
465
466 void *user_data; /**< extra user data */
467 };
468
469 #define pw_data_loop_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_data_loop_events, m, v, ##__VA_ARGS__)
470 #define pw_data_loop_emit_destroy(o) pw_data_loop_emit(o, destroy, 0)
471
472 struct pw_data_loop {
473 struct pw_loop *loop;
474
475 struct spa_hook_list listener_list;
476 struct spa_source *event;
477
478 pthread_t thread;
479 unsigned int created:1;
480 unsigned int running:1;
481 };
482
483 #define pw_main_loop_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_main_loop_events, m, v, ##__VA_ARGS__)
484 #define pw_main_loop_emit_destroy(o) pw_main_loop_emit(o, destroy, 0)
485
486 struct pw_main_loop {
487 struct pw_loop *loop;
488
489 struct spa_hook_list listener_list;
490 struct spa_source *event;
491
492 unsigned int created:1;
493 unsigned int running:1;
494 };
495
496 #define pw_impl_device_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_device_events, m, v, ##__VA_ARGS__)
497 #define pw_impl_device_emit_destroy(m) pw_impl_device_emit(m, destroy, 0)
498 #define pw_impl_device_emit_free(m) pw_impl_device_emit(m, free, 0)
499 #define pw_impl_device_emit_initialized(m) pw_impl_device_emit(m, initialized, 0)
500 #define pw_impl_device_emit_info_changed(n,i) pw_impl_device_emit(n, info_changed, 0, i)
501
502 struct pw_impl_device {
503 struct pw_context *context; /**< the context object */
504 struct spa_list link; /**< link in the context device_list */
505 struct pw_global *global; /**< global object for this device */
506 struct spa_hook global_listener;
507
508 struct pw_properties *properties; /**< properties of the device */
509 struct pw_device_info info; /**< introspectable device info */
510 struct spa_param_info params[MAX_PARAMS];
511
512 char *name; /**< device name for debug */
513
514 struct spa_device *device; /**< device implementation */
515 struct spa_hook listener;
516 struct spa_hook_list listener_list;
517
518 struct spa_list object_list;
519
520 void *user_data; /**< device user_data */
521
522 unsigned int registered:1;
523 };
524
525 #define pw_impl_module_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_module_events, m, v, ##__VA_ARGS__)
526 #define pw_impl_module_emit_destroy(m) pw_impl_module_emit(m, destroy, 0)
527 #define pw_impl_module_emit_free(m) pw_impl_module_emit(m, free, 0)
528 #define pw_impl_module_emit_initialized(m) pw_impl_module_emit(m, initialized, 0)
529 #define pw_impl_module_emit_registered(m) pw_impl_module_emit(m, registered, 0)
530
531 struct pw_impl_module {
532 struct pw_context *context; /**< the context object */
533 struct spa_list link; /**< link in the context module_list */
534 struct pw_global *global; /**< global object for this module */
535 struct spa_hook global_listener;
536
537 struct pw_properties *properties; /**< properties of the module */
538 struct pw_module_info info; /**< introspectable module info */
539
540 struct spa_hook_list listener_list;
541
542 void *user_data; /**< module user_data */
543 };
544
545 struct pw_node_activation_state {
546 int status; /**< current status, the result of spa_node_process() */
547 int32_t required; /**< required number of signals */
548 int32_t pending; /**< number of pending signals */
549 };
550
pw_node_activation_state_reset(struct pw_node_activation_state * state)551 static inline void pw_node_activation_state_reset(struct pw_node_activation_state *state)
552 {
553 state->pending = state->required;
554 }
555
556 #define pw_node_activation_state_dec(s,c) (__atomic_sub_fetch(&(s)->pending, c, __ATOMIC_SEQ_CST) == 0)
557
558 struct pw_node_target {
559 struct spa_list link;
560 struct pw_impl_node *node;
561 struct pw_node_activation *activation;
562 int (*signal) (void *data);
563 void *data;
564 unsigned int active:1;
565 };
566
567 struct pw_node_activation {
568 #define PW_NODE_ACTIVATION_NOT_TRIGGERED 0
569 #define PW_NODE_ACTIVATION_TRIGGERED 1
570 #define PW_NODE_ACTIVATION_AWAKE 2
571 #define PW_NODE_ACTIVATION_FINISHED 3
572 uint32_t status;
573
574 unsigned int version:1;
575 unsigned int pending_sync:1; /* a sync is pending */
576 unsigned int pending_new_pos:1; /* a new position is pending */
577
578 struct pw_node_activation_state state[2]; /* one current state and one next state,
579 * as version flag */
580 uint64_t signal_time;
581 uint64_t awake_time;
582 uint64_t finish_time;
583 uint64_t prev_signal_time;
584
585 /* updates */
586 struct spa_io_segment reposition; /* reposition info, used when driver reposition_owner
587 * has this node id */
588 struct spa_io_segment segment; /* update for the extra segment info fields.
589 * used when driver segment_owner has this node id */
590
591 /* for drivers, shared with all nodes */
592 uint32_t segment_owner[32]; /* id of owners for each segment info struct.
593 * nodes that want to update segment info need to
594 * CAS their node id in this array. */
595 struct spa_io_position position; /* contains current position and segment info.
596 * extra info is updated by nodes that have set
597 * themselves as owner in the segment structs */
598
599 uint64_t sync_timeout; /* sync timeout in nanoseconds
600 * position goes to RUNNING without waiting any
601 * longer for sync clients. */
602 uint64_t sync_left; /* number of cycles before timeout */
603
604
605 float cpu_load[3]; /* averaged over short, medium, long time */
606 uint32_t xrun_count; /* number of xruns */
607 uint64_t xrun_time; /* time of last xrun in microseconds */
608 uint64_t xrun_delay; /* delay of last xrun in microseconds */
609 uint64_t max_delay; /* max of all xruns in microseconds */
610
611 #define PW_NODE_ACTIVATION_COMMAND_NONE 0
612 #define PW_NODE_ACTIVATION_COMMAND_START 1
613 #define PW_NODE_ACTIVATION_COMMAND_STOP 2
614 uint32_t command; /* next command */
615 uint32_t reposition_owner; /* owner id with new reposition info, last one
616 * to update wins */
617 };
618
619 #define ATOMIC_CAS(v,ov,nv) \
620 ({ \
621 __typeof__(v) __ov = (ov); \
622 __atomic_compare_exchange_n(&(v), &__ov, (nv), \
623 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
624 })
625
626 #define ATOMIC_DEC(s) __atomic_sub_fetch(&(s), 1, __ATOMIC_SEQ_CST)
627 #define ATOMIC_INC(s) __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST)
628 #define ATOMIC_LOAD(s) __atomic_load_n(&(s), __ATOMIC_SEQ_CST)
629 #define ATOMIC_STORE(s,v) __atomic_store_n(&(s), (v), __ATOMIC_SEQ_CST)
630 #define ATOMIC_XCHG(s,v) __atomic_exchange_n(&(s), (v), __ATOMIC_SEQ_CST)
631
632 #define SEQ_WRITE(s) ATOMIC_INC(s)
633 #define SEQ_WRITE_SUCCESS(s1,s2) ((s1) + 1 == (s2) && ((s2) & 1) == 0)
634
635 #define SEQ_READ(s) ATOMIC_LOAD(s)
636 #define SEQ_READ_SUCCESS(s1,s2) ((s1) == (s2) && ((s2) & 1) == 0)
637
638 #define pw_impl_node_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_node_events, m, v, ##__VA_ARGS__)
639 #define pw_impl_node_emit_destroy(n) pw_impl_node_emit(n, destroy, 0)
640 #define pw_impl_node_emit_free(n) pw_impl_node_emit(n, free, 0)
641 #define pw_impl_node_emit_initialized(n) pw_impl_node_emit(n, initialized, 0)
642 #define pw_impl_node_emit_port_init(n,p) pw_impl_node_emit(n, port_init, 0, p)
643 #define pw_impl_node_emit_port_added(n,p) pw_impl_node_emit(n, port_added, 0, p)
644 #define pw_impl_node_emit_port_removed(n,p) pw_impl_node_emit(n, port_removed, 0, p)
645 #define pw_impl_node_emit_info_changed(n,i) pw_impl_node_emit(n, info_changed, 0, i)
646 #define pw_impl_node_emit_port_info_changed(n,p,i) pw_impl_node_emit(n, port_info_changed, 0, p, i)
647 #define pw_impl_node_emit_active_changed(n,a) pw_impl_node_emit(n, active_changed, 0, a)
648 #define pw_impl_node_emit_state_request(n,s) pw_impl_node_emit(n, state_request, 0, s)
649 #define pw_impl_node_emit_state_changed(n,o,s,e) pw_impl_node_emit(n, state_changed, 0, o, s, e)
650 #define pw_impl_node_emit_async_complete(n,s,r) pw_impl_node_emit(n, async_complete, 0, s, r)
651 #define pw_impl_node_emit_result(n,s,r,t,result) pw_impl_node_emit(n, result, 0, s, r, t, result)
652 #define pw_impl_node_emit_event(n,e) pw_impl_node_emit(n, event, 0, e)
653 #define pw_impl_node_emit_driver_changed(n,o,d) pw_impl_node_emit(n, driver_changed, 0, o, d)
654 #define pw_impl_node_emit_peer_added(n,p) pw_impl_node_emit(n, peer_added, 0, p)
655 #define pw_impl_node_emit_peer_removed(n,p) pw_impl_node_emit(n, peer_removed, 0, p)
656
657 struct pw_impl_node {
658 struct pw_context *context; /**< context object */
659 struct spa_list link; /**< link in context node_list */
660 struct pw_global *global; /**< global for this node */
661 struct spa_hook global_listener;
662
663 struct pw_properties *properties; /**< properties of the node */
664
665 struct pw_node_info info; /**< introspectable node info */
666 struct spa_param_info params[MAX_PARAMS];
667
668 char *name; /** for debug */
669
670 uint32_t priority_driver; /** priority for being driver */
671 char group[128]; /** group to schedule this node in */
672 uint64_t spa_flags;
673
674 unsigned int registered:1;
675 unsigned int active:1; /**< if the node is active */
676 unsigned int live:1; /**< if the node is live */
677 unsigned int driver:1; /**< if the node can drive the graph */
678 unsigned int exported:1; /**< if the node is exported */
679 unsigned int remote:1; /**< if the node is implemented remotely */
680 unsigned int driving:1; /**< a driving node is one of the driver nodes that
681 * is selected to drive the graph */
682 unsigned int visited:1; /**< for sorting */
683 unsigned int want_driver:1; /**< this node wants to be assigned to a driver */
684 unsigned int passive:1; /**< driver graph only has passive links */
685 unsigned int freewheel:1; /**< if this is the freewheel driver */
686 unsigned int loopchecked:1; /**< for feedback loop checking */
687 unsigned int always_process:1; /**< this node wants to always be processing, even when idle */
688 unsigned int lock_quantum:1; /**< don't change graph quantum */
689 unsigned int lock_rate:1; /**< don't change graph rate */
690 unsigned int transport_sync:1; /**< supports transport sync */
691 unsigned int current_pending:1; /**< a quantum/rate update is pending */
692
693 uint32_t port_user_data_size; /**< extra size for port user data */
694
695 struct spa_list driver_link;
696 struct pw_impl_node *driver_node;
697 struct spa_list follower_list;
698 struct spa_list follower_link;
699
700 struct spa_list sort_link; /**< link used to sort nodes */
701
702 struct spa_node *node; /**< SPA node implementation */
703 struct spa_hook listener;
704
705 struct spa_list input_ports; /**< list of input ports */
706 struct pw_map input_port_map; /**< map from port_id to port */
707 struct spa_list output_ports; /**< list of output ports */
708 struct pw_map output_port_map; /**< map from port_id to port */
709
710 struct spa_hook_list listener_list;
711
712 struct pw_loop *data_loop; /**< the data loop for this node */
713
714 struct spa_fraction latency; /**< requested latency */
715 struct spa_fraction max_latency; /**< maximum latency */
716 struct spa_fraction rate; /**< requested rate */
717 struct spa_source source; /**< source to remotely trigger this node */
718 struct pw_memblock *activation;
719 struct {
720 struct spa_io_clock *clock; /**< io area of the clock or NULL */
721 struct spa_io_position *position;
722 struct pw_node_activation *activation;
723
724 struct spa_list target_list; /* list of targets to signal after
725 * this node */
726 struct pw_node_target driver_target; /* driver target that we signal */
727 struct spa_list input_mix; /* our input ports (and mixers) */
728 struct spa_list output_mix; /* output ports (and mixers) */
729
730 struct pw_node_target target; /* our target that is signaled by the
731 driver */
732 struct spa_list driver_link; /* our link in driver */
733
734 struct ratelimit rate_limit;
735 } rt;
736 struct spa_fraction current_rate;
737 uint64_t current_quantum;
738
739 void *user_data; /**< extra user data */
740 };
741
742 struct pw_impl_port_mix {
743 struct spa_list link;
744 struct spa_list rt_link;
745 struct pw_impl_port *p;
746 struct {
747 enum spa_direction direction;
748 uint32_t port_id;
749 } port;
750 struct spa_io_buffers *io;
751 uint32_t id;
752 uint32_t peer_id;
753 unsigned int have_buffers:1;
754 };
755
756 struct pw_impl_port_implementation {
757 #define PW_VERSION_PORT_IMPLEMENTATION 0
758 uint32_t version;
759
760 int (*init_mix) (void *data, struct pw_impl_port_mix *mix);
761 int (*release_mix) (void *data, struct pw_impl_port_mix *mix);
762 };
763
764 #define pw_impl_port_call(p,m,v,...) \
765 ({ \
766 int _res = 0; \
767 spa_callbacks_call_res(&(p)->impl, \
768 struct pw_impl_port_implementation, \
769 _res, m, v, ## __VA_ARGS__); \
770 _res; \
771 })
772
773 #define pw_impl_port_call_init_mix(p,m) pw_impl_port_call(p,init_mix,0,m)
774 #define pw_impl_port_call_release_mix(p,m) pw_impl_port_call(p,release_mix,0,m)
775
776 #define pw_impl_port_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_port_events, m, v, ##__VA_ARGS__)
777 #define pw_impl_port_emit_destroy(p) pw_impl_port_emit(p, destroy, 0)
778 #define pw_impl_port_emit_free(p) pw_impl_port_emit(p, free, 0)
779 #define pw_impl_port_emit_initialized(p) pw_impl_port_emit(p, initialized, 0)
780 #define pw_impl_port_emit_info_changed(p,i) pw_impl_port_emit(p, info_changed, 0, i)
781 #define pw_impl_port_emit_link_added(p,l) pw_impl_port_emit(p, link_added, 0, l)
782 #define pw_impl_port_emit_link_removed(p,l) pw_impl_port_emit(p, link_removed, 0, l)
783 #define pw_impl_port_emit_state_changed(p,o,s,e) pw_impl_port_emit(p, state_changed, 0, o, s, e)
784 #define pw_impl_port_emit_control_added(p,c) pw_impl_port_emit(p, control_added, 0, c)
785 #define pw_impl_port_emit_control_removed(p,c) pw_impl_port_emit(p, control_removed, 0, c)
786 #define pw_impl_port_emit_param_changed(p,i) pw_impl_port_emit(p, param_changed, 1, i)
787 #define pw_impl_port_emit_latency_changed(p) pw_impl_port_emit(p, latency_changed, 2)
788
789 #define PW_IMPL_PORT_IS_CONTROL(port) SPA_FLAG_MASK(port->flags, \
790 PW_IMPL_PORT_FLAG_BUFFERS|PW_IMPL_PORT_FLAG_CONTROL,\
791 PW_IMPL_PORT_FLAG_CONTROL)
792 struct pw_impl_port {
793 struct spa_list link; /**< link in node port_list */
794
795 struct pw_impl_node *node; /**< owner node */
796 struct pw_global *global; /**< global for this port */
797 struct spa_hook global_listener;
798
799 #define PW_IMPL_PORT_FLAG_TO_REMOVE (1<<0) /**< if the port should be removed from the
800 * implementation when destroyed */
801 #define PW_IMPL_PORT_FLAG_BUFFERS (1<<1) /**< port has data */
802 #define PW_IMPL_PORT_FLAG_CONTROL (1<<2) /**< port has control */
803 #define PW_IMPL_PORT_FLAG_NO_MIXER (1<<3) /**< don't try to add mixer to port */
804 uint32_t flags;
805 uint64_t spa_flags;
806
807 enum pw_direction direction; /**< port direction */
808 uint32_t port_id; /**< port id */
809
810 enum pw_impl_port_state state; /**< state of the port */
811 const char *error; /**< error state */
812
813 struct pw_properties *properties; /**< properties of the port */
814 struct pw_port_info info;
815 struct spa_param_info params[MAX_PARAMS];
816
817 struct pw_buffers buffers; /**< buffers managed by this port, only on
818 * output ports, shared with all links */
819
820 struct spa_list links; /**< list of \ref pw_impl_link */
821
822 struct spa_list control_list[2];/**< list of \ref pw_control indexed by direction */
823
824 struct spa_hook_list listener_list;
825
826 struct spa_callbacks impl;
827
828 struct spa_node *mix; /**< port buffer mix/split */
829 #define PW_IMPL_PORT_MIX_FLAG_MULTI (1<<0) /**< multi input or output */
830 #define PW_IMPL_PORT_MIX_FLAG_MIX_ONLY (1<<1) /**< only negotiate mix ports */
831 #define PW_IMPL_PORT_MIX_FLAG_NEGOTIATE (1<<2) /**< negotiate buffers */
832 uint32_t mix_flags; /**< flags for the mixing */
833 struct spa_handle *mix_handle; /**< mix plugin handle */
834 struct pw_buffers mix_buffers; /**< buffers between mixer and node */
835
836 struct spa_list mix_list; /**< list of \ref pw_impl_port_mix */
837 struct pw_map mix_port_map; /**< map from port_id from mixer */
838 uint32_t n_mix;
839
840 struct {
841 struct spa_io_buffers io; /**< io area of the port */
842 struct spa_io_clock clock; /**< io area of the clock */
843 struct spa_list mix_list;
844 struct spa_list node_link;
845 } rt; /**< data only accessed from the data thread */
846 unsigned int added:1;
847 unsigned int destroying:1;
848 int busy_count;
849
850 struct spa_latency_info latency[2]; /**< latencies */
851 unsigned int have_latency_param:1;
852
853 void *owner_data; /**< extra owner data */
854 void *user_data; /**< extra user data */
855 };
856
857 struct pw_control_link {
858 struct spa_list out_link;
859 struct spa_list in_link;
860 struct pw_control *output;
861 struct pw_control *input;
862 uint32_t out_port;
863 uint32_t in_port;
864 unsigned int valid:1;
865 };
866
867 #define pw_impl_link_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_link_events, m, v, ##__VA_ARGS__)
868 #define pw_impl_link_emit_destroy(l) pw_impl_link_emit(l, destroy, 0)
869 #define pw_impl_link_emit_free(l) pw_impl_link_emit(l, free, 0)
870 #define pw_impl_link_emit_initialized(l) pw_impl_link_emit(l, initialized, 0)
871 #define pw_impl_link_emit_info_changed(l,i) pw_impl_link_emit(l, info_changed, 0, i)
872 #define pw_impl_link_emit_state_changed(l,...) pw_impl_link_emit(l, state_changed, 0, __VA_ARGS__)
873 #define pw_impl_link_emit_port_unlinked(l,p) pw_impl_link_emit(l, port_unlinked, 0, p)
874
875 struct pw_impl_link {
876 struct pw_context *context; /**< context object */
877 struct spa_list link; /**< link in context link_list */
878 struct pw_global *global; /**< global for this link */
879 struct spa_hook global_listener;
880
881 char *name;
882
883 struct pw_link_info info; /**< introspectable link info */
884 struct pw_properties *properties; /**< extra link properties */
885
886 struct spa_io_buffers *io; /**< link io area */
887
888 struct pw_impl_port *output; /**< output port */
889 struct spa_list output_link; /**< link in output port links */
890 struct pw_impl_port *input; /**< input port */
891 struct spa_list input_link; /**< link in input port links */
892
893 struct spa_hook_list listener_list;
894
895 struct pw_control_link control;
896 struct pw_control_link notify;
897
898 struct {
899 struct pw_impl_port_mix out_mix; /**< port added to the output mixer */
900 struct pw_impl_port_mix in_mix; /**< port added to the input mixer */
901 struct pw_node_target target; /**< target to trigger the input node */
902 } rt;
903
904 void *user_data;
905
906 unsigned int registered:1;
907 unsigned int feedback:1;
908 unsigned int preparing:1;
909 unsigned int prepared:1;
910 unsigned int passive:1;
911 };
912
913 #define pw_resource_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_resource_events, m, v, ##__VA_ARGS__)
914
915 #define pw_resource_emit_destroy(o) pw_resource_emit(o, destroy, 0)
916 #define pw_resource_emit_pong(o,s) pw_resource_emit(o, pong, 0, s)
917 #define pw_resource_emit_error(o,s,r,m) pw_resource_emit(o, error, 0, s, r, m)
918
919 struct pw_resource {
920 struct spa_interface impl; /**< object implementation */
921
922 struct pw_context *context; /**< the context object */
923 struct pw_global *global; /**< global of resource */
924 struct spa_list link; /**< link in global resource_list */
925
926 struct pw_impl_client *client; /**< owner client */
927
928 uint32_t id; /**< per client unique id, index in client objects */
929 uint32_t permissions; /**< resource permissions */
930 const char *type; /**< type of the client interface */
931 uint32_t version; /**< version of the client interface */
932 uint32_t bound_id; /**< global id we are bound to */
933
934 unsigned int removed:1; /**< resource was removed from server */
935
936 struct spa_hook_list listener_list;
937 struct spa_hook_list object_listener_list;
938
939 const struct pw_protocol_marshal *marshal;
940
941 void *user_data; /**< extra user data */
942 };
943
944 #define pw_proxy_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_proxy_events, m, v, ##__VA_ARGS__)
945 #define pw_proxy_emit_destroy(p) pw_proxy_emit(p, destroy, 0)
946 #define pw_proxy_emit_bound(p,g) pw_proxy_emit(p, bound, 0, g)
947 #define pw_proxy_emit_removed(p) pw_proxy_emit(p, removed, 0)
948 #define pw_proxy_emit_done(p,s) pw_proxy_emit(p, done, 0, s)
949 #define pw_proxy_emit_error(p,s,r,m) pw_proxy_emit(p, error, 0, s, r, m)
950
951 struct pw_proxy {
952 struct spa_interface impl; /**< object implementation */
953
954 struct pw_core *core; /**< the owner core of this proxy */
955
956 uint32_t id; /**< client side id */
957 const char *type; /**< type of the interface */
958 uint32_t version; /**< client side version */
959 uint32_t bound_id; /**< global id we are bound to */
960 int refcount;
961 unsigned int zombie:1; /**< proxy is removed locally and waiting to
962 * be removed from server */
963 unsigned int removed:1; /**< proxy was removed from server */
964 unsigned int destroyed:1; /**< proxy was destroyed by client */
965 unsigned int in_map:1; /**< proxy is in core object map */
966
967 struct spa_hook_list listener_list;
968 struct spa_hook_list object_listener_list;
969
970 const struct pw_protocol_marshal *marshal; /**< protocol specific marshal functions */
971
972 void *user_data; /**< extra user data */
973 };
974
975 struct pw_core {
976 struct pw_proxy proxy;
977
978 struct pw_context *context; /**< context */
979 struct spa_list link; /**< link in context core_list */
980 struct pw_properties *properties; /**< extra properties */
981
982 struct pw_mempool *pool; /**< memory pool */
983 struct pw_core *core; /**< proxy for the core object */
984 struct spa_hook core_listener;
985 struct spa_hook proxy_core_listener;
986
987 struct pw_map objects; /**< map of client side proxy objects
988 * indexed with the client id */
989 struct pw_client *client; /**< proxy for the client object */
990
991 struct spa_list stream_list; /**< list of \ref pw_stream objects */
992 struct spa_list filter_list; /**< list of \ref pw_stream objects */
993
994 struct pw_protocol_client *conn; /**< the protocol client connection */
995 int recv_seq; /**< last received sequence number */
996 int send_seq; /**< last protocol result code */
997
998 unsigned int removed:1;
999 unsigned int destroyed:1;
1000
1001 void *user_data; /**< extra user data */
1002 };
1003
1004 #define pw_stream_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_stream_events, m, v, ##__VA_ARGS__)
1005 #define pw_stream_emit_destroy(s) pw_stream_emit(s, destroy, 0)
1006 #define pw_stream_emit_state_changed(s,o,n,e) pw_stream_emit(s, state_changed,0,o,n,e)
1007 #define pw_stream_emit_io_changed(s,i,a,t) pw_stream_emit(s, io_changed,0,i,a,t)
1008 #define pw_stream_emit_param_changed(s,i,p) pw_stream_emit(s, param_changed,0,i,p)
1009 #define pw_stream_emit_add_buffer(s,b) pw_stream_emit(s, add_buffer, 0, b)
1010 #define pw_stream_emit_remove_buffer(s,b) pw_stream_emit(s, remove_buffer, 0, b)
1011 #define pw_stream_emit_process(s) pw_stream_emit(s, process, 0)
1012 #define pw_stream_emit_drained(s) pw_stream_emit(s, drained,0)
1013 #define pw_stream_emit_control_info(s,i,c) pw_stream_emit(s, control_info, 0, i, c)
1014 #define pw_stream_emit_command(s,c) pw_stream_emit(s, command,1,c)
1015 #define pw_stream_emit_trigger_done(s) pw_stream_emit(s, trigger_done,2)
1016
1017
1018 struct pw_stream {
1019 struct pw_core *core; /**< the owner core */
1020 struct spa_hook core_listener;
1021
1022 struct spa_list link; /**< link in the core */
1023
1024 char *name; /**< the name of the stream */
1025 struct pw_properties *properties; /**< properties of the stream */
1026
1027 uint32_t node_id; /**< node id for remote node, available from
1028 * CONFIGURE state and higher */
1029 enum pw_stream_state state; /**< stream state */
1030 char *error; /**< error reason when state is in error */
1031
1032 struct spa_hook_list listener_list;
1033
1034 struct pw_proxy *proxy;
1035 struct spa_hook proxy_listener;
1036
1037 struct spa_hook node_listener;
1038
1039 struct spa_list controls;
1040 };
1041
1042 #define pw_filter_emit(s,m,v,...) spa_hook_list_call(&(s)->listener_list, struct pw_filter_events, m, v, ##__VA_ARGS__)
1043 #define pw_filter_emit_destroy(s) pw_filter_emit(s, destroy, 0)
1044 #define pw_filter_emit_state_changed(s,o,n,e) pw_filter_emit(s, state_changed,0,o,n,e)
1045 #define pw_filter_emit_io_changed(s,p,i,d,t) pw_filter_emit(s, io_changed,0,p,i,d,t)
1046 #define pw_filter_emit_param_changed(s,p,i,f) pw_filter_emit(s, param_changed,0,p,i,f)
1047 #define pw_filter_emit_add_buffer(s,p,b) pw_filter_emit(s, add_buffer, 0, p, b)
1048 #define pw_filter_emit_remove_buffer(s,p,b) pw_filter_emit(s, remove_buffer, 0, p, b)
1049 #define pw_filter_emit_process(s,p) pw_filter_emit(s, process, 0, p)
1050 #define pw_filter_emit_drained(s) pw_filter_emit(s, drained, 0)
1051 #define pw_filter_emit_command(s,c) pw_filter_emit(s, command, 1, c)
1052
1053
1054 struct pw_filter {
1055 struct pw_core *core; /**< the owner core proxy */
1056 struct spa_hook core_listener;
1057
1058 struct spa_list link; /**< link in the core proxy */
1059
1060 char *name; /**< the name of the filter */
1061 struct pw_properties *properties; /**< properties of the filter */
1062
1063 uint32_t node_id; /**< node id for remote node, available from
1064 * CONFIGURE state and higher */
1065 enum pw_filter_state state; /**< filter state */
1066 char *error; /**< error reason when state is in error */
1067
1068 struct spa_hook_list listener_list;
1069
1070 struct pw_proxy *proxy;
1071 struct spa_hook proxy_listener;
1072
1073 struct spa_list controls;
1074 };
1075
1076 #define pw_impl_factory_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_factory_events, m, v, ##__VA_ARGS__)
1077
1078 #define pw_impl_factory_emit_destroy(s) pw_impl_factory_emit(s, destroy, 0)
1079 #define pw_impl_factory_emit_free(s) pw_impl_factory_emit(s, free, 0)
1080 #define pw_impl_factory_emit_initialized(s) pw_impl_factory_emit(s, initialized, 0)
1081
1082 struct pw_impl_factory {
1083 struct pw_context *context; /**< the context */
1084 struct spa_list link; /**< link in context factory_list */
1085 struct pw_global *global; /**< global for this factory */
1086 struct spa_hook global_listener;
1087
1088 struct pw_factory_info info; /**< introspectable factory info */
1089 struct pw_properties *properties; /**< properties of the factory */
1090
1091 struct spa_hook_list listener_list; /**< event listeners */
1092
1093 struct spa_callbacks impl;
1094
1095 void *user_data;
1096
1097 unsigned int registered:1;
1098 };
1099
1100 #define pw_control_emit(c,m,v,...) spa_hook_list_call(&c->listener_list, struct pw_control_events, m, v, ##__VA_ARGS__)
1101 #define pw_control_emit_destroy(c) pw_control_emit(c, destroy, 0)
1102 #define pw_control_emit_free(c) pw_control_emit(c, free, 0)
1103 #define pw_control_emit_linked(c,o) pw_control_emit(c, linked, 0, o)
1104 #define pw_control_emit_unlinked(c,o) pw_control_emit(c, unlinked, 0, o)
1105
1106 struct pw_control {
1107 struct spa_list link; /**< link in context control_list */
1108 struct pw_context *context; /**< the context */
1109
1110 struct pw_impl_port *port; /**< owner port or NULL */
1111 struct spa_list port_link; /**< link in port control_list */
1112
1113 enum spa_direction direction; /**< the direction */
1114 struct spa_list links; /**< list of pw_control_link */
1115
1116 uint32_t id;
1117 int32_t size;
1118
1119 struct spa_hook_list listener_list;
1120
1121 void *user_data;
1122 };
1123
1124 /** Find a good format between 2 ports */
1125 int pw_context_find_format(struct pw_context *context,
1126 struct pw_impl_port *output,
1127 struct pw_impl_port *input,
1128 struct pw_properties *props,
1129 uint32_t n_format_filters,
1130 struct spa_pod **format_filters,
1131 struct spa_pod **format,
1132 struct spa_pod_builder *builder,
1133 char **error);
1134
1135 /** Find a ports compatible with \a other_port and the format filters */
1136 struct pw_impl_port *
1137 pw_context_find_port(struct pw_context *context,
1138 struct pw_impl_port *other_port,
1139 uint32_t id,
1140 struct pw_properties *props,
1141 uint32_t n_format_filters,
1142 struct spa_pod **format_filters,
1143 char **error);
1144
1145 int pw_context_debug_port_params(struct pw_context *context,
1146 struct spa_node *node, enum spa_direction direction,
1147 uint32_t port_id, uint32_t id, int err, const char *debug, ...);
1148
1149 const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, const char *type);
1150
1151 int pw_proxy_init(struct pw_proxy *proxy, const char *type, uint32_t version);
1152
1153 void pw_proxy_remove(struct pw_proxy *proxy);
1154
1155 int pw_context_recalc_graph(struct pw_context *context, const char *reason);
1156
1157 void pw_impl_port_update_info(struct pw_impl_port *port, const struct spa_port_info *info);
1158
1159 int pw_impl_port_register(struct pw_impl_port *port,
1160 struct pw_properties *properties);
1161
1162 /** Get the user data of a port, the size of the memory was given \ref in pw_context_create_port */
1163 void * pw_impl_port_get_user_data(struct pw_impl_port *port);
1164
1165 int pw_impl_port_set_mix(struct pw_impl_port *port, struct spa_node *node, uint32_t flags);
1166
1167 int pw_impl_port_init_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix);
1168 int pw_impl_port_release_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix);
1169
1170 void pw_impl_port_update_state(struct pw_impl_port *port, enum pw_impl_port_state state, int res, char *error);
1171
1172 /** Unlink a port */
1173 void pw_impl_port_unlink(struct pw_impl_port *port);
1174
1175 /** Destroy a port */
1176 void pw_impl_port_destroy(struct pw_impl_port *port);
1177
1178 /** Iterate the params of the given port. The callback should return
1179 * 1 to fetch the next item, 0 to stop iteration or <0 on error.
1180 * The function returns 0 on success or the error returned by the callback. */
1181 int pw_impl_port_for_each_param(struct pw_impl_port *port,
1182 int seq, uint32_t param_id,
1183 uint32_t index, uint32_t max,
1184 const struct spa_pod *filter,
1185 int (*callback) (void *data, int seq,
1186 uint32_t id, uint32_t index, uint32_t next,
1187 struct spa_pod *param),
1188 void *data);
1189
1190 int pw_impl_port_for_each_filtered_param(struct pw_impl_port *in_port,
1191 struct pw_impl_port *out_port,
1192 int seq,
1193 uint32_t in_param_id,
1194 uint32_t out_param_id,
1195 const struct spa_pod *filter,
1196 int (*callback) (void *data, int seq,
1197 uint32_t id, uint32_t index, uint32_t next,
1198 struct spa_pod *param),
1199 void *data);
1200
1201 /** Iterate the links of the port. The callback should return
1202 * 0 to fetch the next item, any other value stops the iteration and returns
1203 * the value. When all callbacks return 0, this function returns 0 when all
1204 * items are iterated. */
1205 int pw_impl_port_for_each_link(struct pw_impl_port *port,
1206 int (*callback) (void *data, struct pw_impl_link *link),
1207 void *data);
1208
1209 /** Set a param on a port, use SPA_ID_INVALID for mix_id to set
1210 * the param on all mix ports */
1211 int pw_impl_port_set_param(struct pw_impl_port *port,
1212 uint32_t id, uint32_t flags, const struct spa_pod *param);
1213
1214 /** Use buffers on a port */
1215 int pw_impl_port_use_buffers(struct pw_impl_port *port, struct pw_impl_port_mix *mix, uint32_t flags,
1216 struct spa_buffer **buffers, uint32_t n_buffers);
1217
1218 int pw_impl_port_recalc_latency(struct pw_impl_port *port);
1219
1220 /** Change the state of the node */
1221 int pw_impl_node_set_state(struct pw_impl_node *node, enum pw_node_state state);
1222
1223 int pw_impl_node_set_param(struct pw_impl_node *node,
1224 uint32_t id, uint32_t flags, const struct spa_pod *param);
1225
1226 int pw_impl_node_update_ports(struct pw_impl_node *node);
1227
1228 int pw_impl_node_set_driver(struct pw_impl_node *node, struct pw_impl_node *driver);
1229
1230 /** Prepare a link
1231 * Starts the negotiation of formats and buffers on \a link */
1232 int pw_impl_link_prepare(struct pw_impl_link *link);
1233 /** starts streaming on a link */
1234 int pw_impl_link_activate(struct pw_impl_link *link);
1235
1236 /** Deactivate a link */
1237 int pw_impl_link_deactivate(struct pw_impl_link *link);
1238
1239 struct pw_control *
1240 pw_control_new(struct pw_context *context,
1241 struct pw_impl_port *owner, /**< can be NULL */
1242 uint32_t id, uint32_t size,
1243 size_t user_data_size /**< extra user data */);
1244
1245 int pw_control_add_link(struct pw_control *control, uint32_t cmix,
1246 struct pw_control *other, uint32_t omix,
1247 struct pw_control_link *link);
1248
1249 int pw_control_remove_link(struct pw_control_link *link);
1250
1251 void pw_control_destroy(struct pw_control *control);
1252
1253 #define PW_LOG_OBJECT_POD (1<<0)
1254 void pw_log_log_object(enum spa_log_level level, const char *file, int line,
1255 const char *func, uint32_t flags, const void *object);
1256
1257 #define pw_log_object(lev,fl,obj) \
1258 ({ \
1259 if (SPA_UNLIKELY(pw_log_level_enabled (lev))) \
1260 pw_log_log_object(lev,__FILE__,__LINE__,__func__,(fl),(obj)); \
1261 })
1262
1263 #define pw_log_pod(lev,pod) pw_log_object(lev,PW_LOG_OBJECT_POD,pod)
1264 #define pw_log_format(lev,pod) pw_log_object(lev,PW_LOG_OBJECT_POD,pod)
1265
1266 bool pw_log_is_default(void);
1267
1268 void pw_log_init(void);
1269 void pw_log_deinit(void);
1270
1271 void pw_settings_init(struct pw_context *context);
1272 int pw_settings_expose(struct pw_context *context);
1273 void pw_settings_clean(struct pw_context *context);
1274
1275 /** \endcond */
1276
1277 #ifdef __cplusplus
1278 }
1279 #endif
1280
1281 #endif /* PIPEWIRE_PRIVATE_H */
1282