Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/pipewire/pipewire/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 48 kB image not shown  

Quelle  private.h   Sprache: C

 
/* PipeWire
 *
 * Copyright © 2018 Wim Taymans
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */


#ifndef PIPEWIRE_PRIVATE_H
#define PIPEWIRE_PRIVATE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/socket.h>
#include <sys/types.h> /* for pthread_t */

#include "pipewire/impl.h"

#include <spa/support/plugin.h>
#include <spa/pod/builder.h>
#include <spa/param/latency-utils.h>
#include <spa/utils/result.h>
#include <spa/utils/type-info.h>

#if defined(__FreeBSD__) || defined(__MidnightBSD__)
struct ucred {
};
#endif

#ifndef spa_debug
#define spa_debug(...) pw_log_trace(__VA_ARGS__)
#endif

#define MAX_RATES    16u
#define CLOCK_MIN_QUANTUM   4u
#define CLOCK_MAX_QUANTUM   65536u

struct settings {
 uint32_t log_level;
 uint32_t clock_rate;   /* default clock rate */
 uint32_t clock_rates[MAX_RATES]; /* allowed clock rates */
 uint32_t n_clock_rates;   /* number of alternative clock rates */
 uint32_t clock_quantum;   /* default quantum */
 uint32_t clock_min_quantum;  /* min quantum */
 uint32_t clock_max_quantum;  /* max quantum */
 uint32_t clock_quantum_limit;  /* quantum limit */
 struct spa_rectangle video_size;
 struct spa_fraction video_rate;
 uint32_t link_max_buffers;
 unsigned int mem_warn_mlock:1;
 unsigned int mem_allow_mlock:1;
 unsigned int clock_power_of_two_quantum:1;
 unsigned int check_quantum:1;
 unsigned int check_rate:1;
#define CLOCK_RATE_UPDATE_MODE_HARD 0
#define CLOCK_RATE_UPDATE_MODE_SOFT 1
 int clock_rate_update_mode;
 uint32_t clock_force_rate;  /* force a clock rate */
 uint32_t clock_force_quantum;  /* force a quantum */
};

struct ratelimit {
 uint64_t interval;
 uint64_t begin;
 unsigned burst;
 unsigned n_printed, n_missed;
};

static inline bool ratelimit_test(struct ratelimit *r, uint64_t now, enum spa_log_level level)
{
 if (r->begin + r->interval < now) {
  if (r->n_missed)
   pw_log(level, "%u events suppressed", r->n_missed);
  r->begin = now;
  r->n_printed = 0;
  r->n_missed = 0;
 } else if (r->n_printed >= r->burst) {
  r->n_missed++;
  return false;
 }
 r->n_printed++;
 return true;
}

#define MAX_PARAMS 32

struct pw_param {
 uint32_t id;
 struct spa_list link;
 struct spa_pod *param;
};

static inline uint32_t pw_param_clear(struct spa_list *param_list, uint32_t id)
{
 struct pw_param *p, *t;
 uint32_t count = 0;

 spa_list_for_each_safe(p, t, param_list, link) {
  if (id == SPA_ID_INVALID || p->id == id) {
   spa_list_remove(&p->link);
   free(p);
   count++;
  }
 }
 return count;
}

static inline struct pw_param *pw_param_add(struct spa_list *params,
  uint32_t id, const struct spa_pod *param)
{
 struct pw_param *p;

 if (id == SPA_ID_INVALID) {
  if (param == NULL || !spa_pod_is_object(param)) {
   errno = EINVAL;
   return NULL;
  }
  id = SPA_POD_OBJECT_ID(param);
 }

 if ((p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0))) == NULL)
  return NULL;

 p->id = id;
 if (param != NULL) {
  p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod);
  memcpy(p->param, param, SPA_POD_SIZE(param));
 } else {
  pw_param_clear(params, id);
  p->param = NULL;
 }
 spa_list_append(params, &p->link);
 return p;
}

static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list)
{
 struct pw_param *p;

 spa_list_consume(p, pending_list, link) {
  spa_list_remove(&p->link);
  if (p->param == NULL) {
   pw_param_clear(param_list, p->id);
   free(p);
  } else {
   spa_list_append(param_list, &p->link);
  }
 }
}

static inline struct spa_param_info *pw_param_info_find(struct spa_param_info info[],
  uint32_t n_info, uint32_t id)
{
 uint32_t i;
 for (i = 0; i < n_info; i++) {
  if (info[i].id == id)
   return &info[i];
 }
 return NULL;
}

#define pw_protocol_emit_destroy(p) spa_hook_list_call(&p->listener_list, struct pw_protocol_events, destroy, 0)

struct pw_protocol {
 struct spa_list link;                   /**< link in context protocol_list */
 struct pw_context *context;                   /**< context for this protocol */

 char *name;                             /**< type name of the protocol */

 struct spa_list marshal_list;           /**< list of marshallers for supported interfaces */
 struct spa_list client_list;            /**< list of current clients */
 struct spa_list server_list;            /**< list of current servers */
 struct spa_hook_list listener_list; /**< event listeners */

 const struct pw_protocol_implementation *implementation; /**< implementation of the protocol */

 const void *extension;  /**< extension API */

 void *user_data;        /**< user data for the implementation */
};

/** the permission function. It returns the allowed access permissions for \a global
  * for \a client */

typedef uint32_t (*pw_permission_func_t) (struct pw_global *global,
       struct pw_impl_client *client, void *data);

#define pw_impl_client_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_client_events, m, v, ##__VA_ARGS__)

#define pw_impl_client_emit_destroy(o)   pw_impl_client_emit(o, destroy, 0)
#define pw_impl_client_emit_free(o)   pw_impl_client_emit(o, free, 0)
#define pw_impl_client_emit_initialized(o)  pw_impl_client_emit(o, initialized, 0)
#define pw_impl_client_emit_info_changed(o,i)  pw_impl_client_emit(o, info_changed, 0, i)
#define pw_impl_client_emit_resource_added(o,r)  pw_impl_client_emit(o, resource_added, 0, r)
#define pw_impl_client_emit_resource_impl(o,r)  pw_impl_client_emit(o, resource_impl, 0, r)
#define pw_impl_client_emit_resource_removed(o,r) pw_impl_client_emit(o, resource_removed, 0, r)
#define pw_impl_client_emit_busy_changed(o,b)  pw_impl_client_emit(o, busy_changed, 0, b)

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,
};

struct protocol_compat_v2 {
 /* v2 typemap */
 struct pw_map types;
 unsigned int send_types:1;
};

#define pw_impl_core_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_core_events, m, v, ##__VA_ARGS__)

#define pw_impl_core_emit_destroy(s)  pw_impl_core_emit(s, destroy, 0)
#define pw_impl_core_emit_free(s)  pw_impl_core_emit(s, free, 0)
#define pw_impl_core_emit_initialized(s) pw_impl_core_emit(s, initialized, 0)

struct pw_impl_core {
 struct pw_context *context;
 struct spa_list link;   /**< link in context object core_impl list */
 struct pw_global *global;  /**< global object created for this core */
 struct spa_hook global_listener;

 struct pw_properties *properties; /**< core properties */
 struct pw_core_info info;  /**< core info */

 struct spa_hook_list listener_list;
 void *user_data;   /**< extra user data */

 unsigned int registered:1;
};

#define pw_impl_metadata_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_metadata_events, m, v, ##__VA_ARGS__)

#define pw_impl_metadata_emit_destroy(s) pw_impl_metadata_emit(s, destroy, 0)
#define pw_impl_metadata_emit_free(s)  pw_impl_metadata_emit(s, free, 0)
#define pw_impl_metadata_emit_property(s, ...) pw_impl_metadata_emit(s, property, 0, __VA_ARGS__)

struct pw_impl_metadata {
 struct pw_context *context;  /**< the context */
 struct spa_list link;   /**< link in context metadata_list */
 struct pw_global *global;  /**< global for this metadata */
 struct spa_hook global_listener;

 struct pw_properties *properties; /**< properties of the metadata */

 struct pw_metadata *metadata;
 struct spa_hook metadata_listener;

 struct spa_hook_list listener_list; /**< event listeners */
 void *user_data;

 unsigned int registered:1;
};

struct pw_impl_client {
 struct pw_impl_core *core;  /**< core object */
 struct pw_context *context;  /**< context object */

 struct spa_list link;   /**< link in context object client list */
 struct pw_global *global;  /**< global object created for this client */
 struct spa_hook global_listener;

 pw_permission_func_t permission_func; /**< get permissions of an object */
 void *permission_data;   /**< data passed to permission function */

 struct pw_properties *properties; /**< Client properties */

 struct pw_client_info info; /**< client info */

 struct pw_mempool *pool;  /**< client mempool */
 struct pw_resource *core_resource; /**< core resource object */
 struct pw_resource *client_resource; /**< client resource object */

 struct pw_map objects;  /**< list of resource objects */

 struct spa_hook_list listener_list;

 struct pw_protocol *protocol; /**< protocol in use */
 int recv_seq;   /**< last received sequence number */
 int send_seq;   /**< last sender sequence number */
 uint64_t recv_generation; /**< last received registry generation */
 uint64_t sent_generation; /**< last sent registry generation */

 void *user_data;  /**< extra user data */

 struct ucred ucred;  /**< ucred information */
 unsigned int registered:1;
 unsigned int ucred_valid:1; /**< if the ucred member is valid */
 unsigned int busy:1;
 unsigned int destroyed:1;

 int refcount;

 /* v2 compatibility data */
 void *compat_v2;
};

#define pw_global_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_global_events, m, v, ##__VA_ARGS__)

#define pw_global_emit_registering(g) pw_global_emit(g, registering, 0)
#define pw_global_emit_destroy(g) pw_global_emit(g, destroy, 0)
#define pw_global_emit_free(g)  pw_global_emit(g, free, 0)
#define pw_global_emit_permissions_changed(g,...) pw_global_emit(g, permissions_changed, 0, __VA_ARGS__)

struct pw_global {
 struct pw_context *context;  /**< the context */

 struct spa_list link;  /**< link in context list of globals */
 uint32_t id;   /**< server id of the object */

 struct pw_properties *properties; /**< properties of the global */

 struct spa_hook_list listener_list;

 const char *type;  /**< type of interface */
 uint32_t version;  /**< version of interface */

 pw_global_bind_func_t func; /**< bind function */
 void *object;   /**< object associated with the interface */
 uint64_t serial;  /**< increasing serial number */
 uint64_t generation;  /**< registry generation number */

 struct spa_list resource_list; /**< The list of resources of this global */

 unsigned int registered:1;
 unsigned int destroyed:1;
};

#define pw_core_resource(r,m,v,...) pw_resource_call(r, struct pw_core_events, m, v, ##__VA_ARGS__)
#define pw_core_resource_info(r,...)  pw_core_resource(r,info,0,__VA_ARGS__)
#define pw_core_resource_done(r,...)  pw_core_resource(r,done,0,__VA_ARGS__)
#define pw_core_resource_ping(r,...)  pw_core_resource(r,ping,0,__VA_ARGS__)
#define pw_core_resource_error(r,...)  pw_core_resource(r,error,0,__VA_ARGS__)
#define pw_core_resource_remove_id(r,...) pw_core_resource(r,remove_id,0,__VA_ARGS__)
#define pw_core_resource_bound_id(r,...) pw_core_resource(r,bound_id,0,__VA_ARGS__)
#define pw_core_resource_add_mem(r,...)  pw_core_resource(r,add_mem,0,__VA_ARGS__)
#define pw_core_resource_remove_mem(r,...) pw_core_resource(r,remove_mem,0,__VA_ARGS__)

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)
{
 char buffer[1024];
 vsnprintf(buffer, sizeof(buffer), message, args);
 buffer[1023] = '\0';
 pw_log_debug("resource %p: id:%d seq:%d res:%d (%s) msg:\"%s\"",
   resource, id, seq, res, spa_strerror(res), buffer);
 if (resource)
  pw_core_resource_error(resource, id, seq, res, buffer);
 else
  pw_log_error("id:%d seq:%d res:%d (%s) msg:\"%s\"",
    id, seq, res, spa_strerror(res), buffer);
}

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, ...)
{
        va_list args;
 va_start(args, message);
 pw_core_resource_errorv(resource, id, seq, res, message, args);
 va_end(args);
}

#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__)
#define pw_context_driver_emit_start(c,n) pw_context_driver_emit(c, start, 0, n)
#define pw_context_driver_emit_xrun(c,n) pw_context_driver_emit(c, xrun, 0, n)
#define pw_context_driver_emit_incomplete(c,n) pw_context_driver_emit(c, incomplete, 0, n)
#define pw_context_driver_emit_timeout(c,n) pw_context_driver_emit(c, timeout, 0, n)
#define pw_context_driver_emit_drained(c,n) pw_context_driver_emit(c, drained, 0, n)
#define pw_context_driver_emit_complete(c,n) pw_context_driver_emit(c, complete, 0, n)

struct pw_context_driver_events {
#define PW_VERSION_CONTEXT_DRIVER_EVENTS 0
 uint32_t version;

 /** The driver graph is started */
 void (*start) (void *data, struct pw_impl_node *node);
 /** The driver under/overruns */
 void (*xrun) (void *data, struct pw_impl_node *node);
 /** The driver could not complete the graph */
 void (*incomplete) (void *data, struct pw_impl_node *node);
 /** The driver got a sync timeout */
 void (*timeout) (void *data, struct pw_impl_node *node);
 /** a node drained */
 void (*drained) (void *data, struct pw_impl_node *node);
 /** The driver completed the graph */
 void (*complete) (void *data, struct pw_impl_node *node);
};

#define pw_registry_resource(r,m,v,...) pw_resource_call(r, struct pw_registry_events,m,v,##__VA_ARGS__)
#define pw_registry_resource_global(r,...)        pw_registry_resource(r,global,0,__VA_ARGS__)
#define pw_registry_resource_global_remove(r,...) pw_registry_resource(r,global_remove,0,__VA_ARGS__)

#define pw_context_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_context_events, m, v, ##__VA_ARGS__)
#define pw_context_emit_destroy(c)  pw_context_emit(c, destroy, 0)
#define pw_context_emit_free(c)   pw_context_emit(c, free, 0)
#define pw_context_emit_info_changed(c,i) pw_context_emit(c, info_changed, 0, i)
#define pw_context_emit_check_access(c,cl) pw_context_emit(c, check_access, 0, cl)
#define pw_context_emit_global_added(c,g) pw_context_emit(c, global_added, 0, g)
#define pw_context_emit_global_removed(c,g) pw_context_emit(c, global_removed, 0, g)

struct pw_context {
 struct pw_impl_core *core;  /**< core object */

 struct pw_properties *conf;  /**< configuration of the context */
 struct pw_properties *properties; /**< properties of the context */

 struct settings defaults;  /**< default parameters */
 struct settings settings;  /**< current parameters */

 void *settings_impl;  /**< settings metadata */

 struct pw_mempool *pool;  /**< global memory pool */

 uint64_t stamp;
 uint64_t serial;
 uint64_t generation;   /**< registry generation number */
 struct pw_map globals;   /**< map of globals */

 struct spa_list core_impl_list;  /**< list of core_imp */
 struct spa_list protocol_list;  /**< list of protocols */
 struct spa_list core_list;  /**< list of core connections */
 struct spa_list registry_resource_list; /**< list of registry resources */
 struct spa_list module_list;  /**< list of modules */
 struct spa_list device_list;  /**< list of devices */
 struct spa_list global_list;  /**< list of globals */
 struct spa_list client_list;  /**< list of clients */
 struct spa_list node_list;  /**< list of nodes */
 struct spa_list factory_list;  /**< list of factories */
 struct spa_list metadata_list;  /**< list of metadata */
 struct spa_list link_list;  /**< list of links */
 struct spa_list control_list[2]; /**< list of controls, indexed by direction */
 struct spa_list export_list;  /**< list of export types */
 struct spa_list driver_list;  /**< list of driver nodes */

 struct spa_hook_list driver_listener_list;
 struct spa_hook_list listener_list;

 struct spa_thread_utils *thread_utils;
 struct pw_loop *main_loop;  /**< main loop for control */
 struct pw_loop *data_loop;  /**< data loop for data passing */
 struct pw_data_loop *data_loop_impl;
 struct spa_system *data_system;  /**< data system for data passing */
 struct pw_work_queue *work_queue; /**< work queue */

 struct spa_support support[16]; /**< support for spa plugins */
 uint32_t n_support;  /**< number of support items */
 struct pw_array factory_lib; /**< mapping of factory_name regexp to library */

 struct pw_array objects; /**< objects */

 struct pw_impl_client *current_client; /**< client currently executing code in mainloop */

 long sc_pagesize;
 unsigned int freewheeling:1;

 void *user_data;  /**< extra user data */
};

#define pw_data_loop_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_data_loop_events, m, v, ##__VA_ARGS__)
#define pw_data_loop_emit_destroy(o) pw_data_loop_emit(o, destroy, 0)

struct pw_data_loop {
 struct pw_loop *loop;

 struct spa_hook_list listener_list;

 struct spa_thread_utils *thread_utils;

 pthread_t thread;
 unsigned int cancel:1;
 unsigned int created:1;
 unsigned int running:1;
};

#define pw_main_loop_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_main_loop_events, m, v, ##__VA_ARGS__)
#define pw_main_loop_emit_destroy(o) pw_main_loop_emit(o, destroy, 0)

struct pw_main_loop {
        struct pw_loop *loop;

 struct spa_hook_list listener_list;

 unsigned int created:1;
 unsigned int running:1;
};

#define pw_impl_device_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_device_events, m, v, ##__VA_ARGS__)
#define pw_impl_device_emit_destroy(m)  pw_impl_device_emit(m, destroy, 0)
#define pw_impl_device_emit_free(m)  pw_impl_device_emit(m, free, 0)
#define pw_impl_device_emit_initialized(m) pw_impl_device_emit(m, initialized, 0)
#define pw_impl_device_emit_info_changed(n,i) pw_impl_device_emit(n, info_changed, 0, i)

struct pw_impl_device {
 struct pw_context *context;           /**< the context object */
 struct spa_list link;           /**< link in the context device_list */
 struct pw_global *global;       /**< global object for this device */
 struct spa_hook global_listener;

 struct pw_properties *properties; /**< properties of the device */
 struct pw_device_info info;  /**< introspectable device info */
 struct spa_param_info params[MAX_PARAMS];

 char *name;    /**< device name for debug */

 struct spa_device *device;  /**< device implementation */
 struct spa_hook listener;
 struct spa_hook_list listener_list;

 struct spa_list object_list;

 void *user_data;                /**< device user_data */

 unsigned int registered:1;
};

#define pw_impl_module_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_module_events, m, v, ##__VA_ARGS__)
#define pw_impl_module_emit_destroy(m)  pw_impl_module_emit(m, destroy, 0)
#define pw_impl_module_emit_free(m)  pw_impl_module_emit(m, free, 0)
#define pw_impl_module_emit_initialized(m) pw_impl_module_emit(m, initialized, 0)
#define pw_impl_module_emit_registered(m) pw_impl_module_emit(m, registered, 0)

struct pw_impl_module {
 struct pw_context *context; /**< the context object */
 struct spa_list link;  /**< link in the context module_list */
 struct pw_global *global; /**< global object for this module */
 struct spa_hook global_listener;

 struct pw_properties *properties; /**< properties of the module */
 struct pw_module_info info; /**< introspectable module info */

 struct spa_hook_list listener_list;

 void *user_data;  /**< module user_data */
};

struct pw_node_activation_state {
 int status;                     /**< current status, the result of spa_node_process() */
 int32_t required;  /**< required number of signals */
 int32_t pending;  /**< number of pending signals */
};

static inline void pw_node_activation_state_reset(struct pw_node_activation_state *state)
{
        state->pending = state->required;
}

#define pw_node_activation_state_dec(s,c) (__atomic_sub_fetch(&(s)->pending, c, __ATOMIC_SEQ_CST) == 0)

struct pw_node_target {
 struct spa_list link;
 struct pw_impl_node *node;
 struct pw_node_activation *activation;
 int (*signal) (void *data);
 void *data;
 unsigned int active:1;
};

struct pw_node_activation {
#define PW_NODE_ACTIVATION_NOT_TRIGGERED 0
#define PW_NODE_ACTIVATION_TRIGGERED  1
#define PW_NODE_ACTIVATION_AWAKE  2
#define PW_NODE_ACTIVATION_FINISHED  3
 uint32_t status;

 unsigned int version:1;
 unsigned int pending_sync:1;   /* a sync is pending */
 unsigned int pending_new_pos:1;   /* a new position is pending */

 struct pw_node_activation_state state[2]; /* one current state and one next state,
 * as version flag */

 uint64_t signal_time;
 uint64_t awake_time;
 uint64_t finish_time;
 uint64_t prev_signal_time;

 /* updates */
 struct spa_io_segment reposition;  /* reposition info, used when driver reposition_owner
 * has this node id */

 struct spa_io_segment segment;   /* update for the extra segment info fields.
 * used when driver segment_owner has this node id */


 /* for drivers, shared with all nodes */
 uint32_t segment_owner[32];   /* id of owners for each segment info struct.
 * nodes that want to update segment info need to
 * CAS their node id in this array. */

 struct spa_io_position position;  /* contains current position and segment info.
 * extra info is updated by nodes that have set
 * themselves as owner in the segment structs */


 uint64_t sync_timeout;    /* sync timeout in nanoseconds
 * position goes to RUNNING without waiting any
 * longer for sync clients. */

 uint64_t sync_left;    /* number of cycles before timeout */


 float cpu_load[3];    /* averaged over short, medium, long time */
 uint32_t xrun_count;    /* number of xruns */
 uint64_t xrun_time;    /* time of last xrun in microseconds */
 uint64_t xrun_delay;    /* delay of last xrun in microseconds */
 uint64_t max_delay;    /* max of all xruns in microseconds */

#define PW_NODE_ACTIVATION_COMMAND_NONE  0
#define PW_NODE_ACTIVATION_COMMAND_START 1
#define PW_NODE_ACTIVATION_COMMAND_STOP  2
 uint32_t command;    /* next command */
 uint32_t reposition_owner;   /* owner id with new reposition info, last one
 * to update wins */

};

#define ATOMIC_CAS(v,ov,nv)      \
({         \
 __typeof__(v) __ov = (ov);     \
 __atomic_compare_exchange_n(&(v), &__ov, (nv),   \
   0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);  \
})

#define ATOMIC_DEC(s)   __atomic_sub_fetch(&(s), 1, __ATOMIC_SEQ_CST)
#define ATOMIC_INC(s)   __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST)
#define ATOMIC_LOAD(s)   __atomic_load_n(&(s), __ATOMIC_SEQ_CST)
#define ATOMIC_STORE(s,v)  __atomic_store_n(&(s), (v), __ATOMIC_SEQ_CST)
#define ATOMIC_XCHG(s,v)  __atomic_exchange_n(&(s), (v), __ATOMIC_SEQ_CST)

#define SEQ_WRITE(s)   ATOMIC_INC(s)
#define SEQ_WRITE_SUCCESS(s1,s2) ((s1) + 1 == (s2) && ((s2) & 1) == 0)

#define SEQ_READ(s)   ATOMIC_LOAD(s)
#define SEQ_READ_SUCCESS(s1,s2)  ((s1) == (s2) && ((s2) & 1) == 0)

#define pw_impl_node_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_node_events, m, v, ##__VA_ARGS__)
#define pw_impl_node_emit_destroy(n)   pw_impl_node_emit(n, destroy, 0)
#define pw_impl_node_emit_free(n)   pw_impl_node_emit(n, free, 0)
#define pw_impl_node_emit_initialized(n)  pw_impl_node_emit(n, initialized, 0)
#define pw_impl_node_emit_port_init(n,p)  pw_impl_node_emit(n, port_init, 0, p)
#define pw_impl_node_emit_port_added(n,p)  pw_impl_node_emit(n, port_added, 0, p)
#define pw_impl_node_emit_port_removed(n,p)  pw_impl_node_emit(n, port_removed, 0, p)
#define pw_impl_node_emit_info_changed(n,i)  pw_impl_node_emit(n, info_changed, 0, i)
#define pw_impl_node_emit_port_info_changed(n,p,i) pw_impl_node_emit(n, port_info_changed, 0, p, i)
#define pw_impl_node_emit_active_changed(n,a)  pw_impl_node_emit(n, active_changed, 0, a)
#define pw_impl_node_emit_state_request(n,s)  pw_impl_node_emit(n, state_request, 0, s)
#define pw_impl_node_emit_state_changed(n,o,s,e) pw_impl_node_emit(n, state_changed, 0, o, s, e)
#define pw_impl_node_emit_async_complete(n,s,r)  pw_impl_node_emit(n, async_complete, 0, s, r)
#define pw_impl_node_emit_result(n,s,r,t,result) pw_impl_node_emit(n, result, 0, s, r, t, result)
#define pw_impl_node_emit_event(n,e)   pw_impl_node_emit(n, event, 0, e)
#define pw_impl_node_emit_driver_changed(n,o,d)  pw_impl_node_emit(n, driver_changed, 0, o, d)
#define pw_impl_node_emit_peer_added(n,p)  pw_impl_node_emit(n, peer_added, 0, p)
#define pw_impl_node_emit_peer_removed(n,p)  pw_impl_node_emit(n, peer_removed, 0, p)

struct pw_impl_node {
 struct pw_context *context;  /**< context object */
 struct spa_list link;  /**< link in context node_list */
 struct pw_global *global; /**< global for this node */
 struct spa_hook global_listener;

 struct pw_properties *properties; /**< properties of the node */

 struct pw_node_info info;  /**< introspectable node info */
 struct spa_param_info params[MAX_PARAMS];

 char *name;    /** for debug */

 uint32_t priority_driver; /** priority for being driver */
 char group[128];  /** group to schedule this node in */
 uint64_t spa_flags;

 unsigned int registered:1;
 unsigned int active:1;  /**< if the node is active */
 unsigned int live:1;  /**< if the node is live */
 unsigned int driver:1;  /**< if the node can drive the graph */
 unsigned int exported:1; /**< if the node is exported */
 unsigned int remote:1;  /**< if the node is implemented remotely */
 unsigned int driving:1;  /**< a driving node is one of the driver nodes that
  *  is selected to drive the graph */

 unsigned int visited:1;  /**< for sorting */
 unsigned int want_driver:1; /**< this node wants to be assigned to a driver */
 unsigned int passive:1;  /**< driver graph only has passive links */
 unsigned int freewheel:1; /**< if this is the freewheel driver */
 unsigned int loopchecked:1; /**< for feedback loop checking */
 unsigned int always_process:1; /**< this node wants to always be processing, even when idle */
 unsigned int lock_quantum:1; /**< don't change graph quantum */
 unsigned int lock_rate:1; /**< don't change graph rate */
 unsigned int transport_sync:1; /**< supports transport sync */
 unsigned int current_pending:1; /**< a quantum/rate update is pending */
 unsigned int moved:1;  /**< the node was moved drivers */

 uint32_t port_user_data_size; /**< extra size for port user data */

 struct spa_list driver_link;
 struct pw_impl_node *driver_node;
 struct spa_list follower_list;
 struct spa_list follower_link;

 struct spa_list sort_link; /**< link used to sort nodes */

 struct spa_node *node;  /**< SPA node implementation */
 struct spa_hook listener;

 struct spa_list input_ports;  /**< list of input ports */
 struct pw_map input_port_map;  /**< map from port_id to port */
 struct spa_list output_ports;  /**< list of output ports */
 struct pw_map output_port_map;  /**< map from port_id to port */

 struct spa_hook_list listener_list;

 struct pw_loop *data_loop;  /**< the data loop for this node */

 struct spa_fraction latency;  /**< requested latency */
 struct spa_fraction max_latency; /**< maximum latency */
 struct spa_fraction rate;  /**< requested rate */
 uint32_t force_quantum;   /**< forced quantum */
 uint32_t force_rate;   /**< forced rate */
 uint32_t stamp;    /**< stamp of last update */
 struct spa_source source;  /**< source to remotely trigger this node */
 struct pw_memblock *activation;
 struct {
  struct spa_io_clock *clock; /**< io area of the clock or NULL */
  struct spa_io_position *position;
  struct pw_node_activation *activation;

  struct spa_list target_list;  /* list of targets to signal after
 * this node */

  struct pw_node_target driver_target; /* driver target that we signal */
  struct spa_list input_mix;  /* our input ports (and mixers) */
  struct spa_list output_mix;  /* output ports (and mixers) */

  struct pw_node_target target;  /* our target that is signaled by the
   driver */

  struct spa_list driver_link;  /* our link in driver */

  struct ratelimit rate_limit;
 } rt;
 struct spa_fraction current_rate;
 uint64_t current_quantum;

        void *user_data;                /**< extra user data */
};

struct pw_impl_port_mix {
 struct spa_list link;
 struct spa_list rt_link;
 struct pw_impl_port *p;
 struct {
  enum spa_direction direction;
  uint32_t port_id;
 } port;
 struct spa_io_buffers *io;
 uint32_t id;
 uint32_t peer_id;
 unsigned int have_buffers:1;
};

struct pw_impl_port_implementation {
#define PW_VERSION_PORT_IMPLEMENTATION       0
 uint32_t version;

 int (*init_mix) (void *data, struct pw_impl_port_mix *mix);
 int (*release_mix) (void *data, struct pw_impl_port_mix *mix);
};

#define pw_impl_port_call(p,m,v,...)    \
({        \
 int _res = 0;      \
 spa_callbacks_call_res(&(p)->impl,   \
   struct pw_impl_port_implementation, \
   _res, m, v, ## __VA_ARGS__);  \
 _res;       \
})

#define pw_impl_port_call_init_mix(p,m)  pw_impl_port_call(p,init_mix,0,m)
#define pw_impl_port_call_release_mix(p,m) pw_impl_port_call(p,release_mix,0,m)

#define pw_impl_port_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_port_events, m, v, ##__VA_ARGS__)
#define pw_impl_port_emit_destroy(p)   pw_impl_port_emit(p, destroy, 0)
#define pw_impl_port_emit_free(p)   pw_impl_port_emit(p, free, 0)
#define pw_impl_port_emit_initialized(p)  pw_impl_port_emit(p, initialized, 0)
#define pw_impl_port_emit_info_changed(p,i)  pw_impl_port_emit(p, info_changed, 0, i)
#define pw_impl_port_emit_link_added(p,l)  pw_impl_port_emit(p, link_added, 0, l)
#define pw_impl_port_emit_link_removed(p,l)  pw_impl_port_emit(p, link_removed, 0, l)
#define pw_impl_port_emit_state_changed(p,o,s,e) pw_impl_port_emit(p, state_changed, 0, o, s, e)
#define pw_impl_port_emit_control_added(p,c)  pw_impl_port_emit(p, control_added, 0, c)
#define pw_impl_port_emit_control_removed(p,c)  pw_impl_port_emit(p, control_removed, 0, c)
#define pw_impl_port_emit_param_changed(p,i)  pw_impl_port_emit(p, param_changed, 1, i)
#define pw_impl_port_emit_latency_changed(p)  pw_impl_port_emit(p, latency_changed, 2)

#define PW_IMPL_PORT_IS_CONTROL(port) SPA_FLAG_MASK(port->flags, \
      PW_IMPL_PORT_FLAG_BUFFERS|PW_IMPL_PORT_FLAG_CONTROL,\
      PW_IMPL_PORT_FLAG_CONTROL)
struct pw_impl_port {
 struct spa_list link;  /**< link in node port_list */

 struct pw_impl_node *node;  /**< owner node */
 struct pw_global *global; /**< global for this port */
 struct spa_hook global_listener;

#define PW_IMPL_PORT_FLAG_TO_REMOVE  (1<<0)  /**< if the port should be removed from the
  *  implementation when destroyed */

#define PW_IMPL_PORT_FLAG_BUFFERS  (1<<1)  /**< port has data */
#define PW_IMPL_PORT_FLAG_CONTROL  (1<<2)  /**< port has control */
#define PW_IMPL_PORT_FLAG_NO_MIXER  (1<<3)  /**< don't try to add mixer to port */
 uint32_t flags;
 uint64_t spa_flags;

 enum pw_direction direction; /**< port direction */
 uint32_t port_id;  /**< port id */

 enum pw_impl_port_state state; /**< state of the port */
 const char *error;  /**< error state */

 struct pw_properties *properties; /**< properties of the port */
 struct pw_port_info info;
 struct spa_param_info params[MAX_PARAMS];

 struct pw_buffers buffers; /**< buffers managed by this port, only on
  *  output ports, shared with all links */


 struct spa_list links;  /**< list of \ref pw_impl_link */

 struct spa_list control_list[2];/**< list of \ref pw_control indexed by direction */

 struct spa_hook_list listener_list;

 struct spa_callbacks impl;

 struct spa_node *mix;  /**< port buffer mix/split */
#define PW_IMPL_PORT_MIX_FLAG_MULTI (1<<0) /**< multi input or output */
#define PW_IMPL_PORT_MIX_FLAG_MIX_ONLY (1<<1) /**< only negotiate mix ports */
#define PW_IMPL_PORT_MIX_FLAG_NEGOTIATE (1<<2) /**< negotiate buffers  */
 uint32_t mix_flags;  /**< flags for the mixing */
 struct spa_handle *mix_handle; /**< mix plugin handle */
 struct pw_buffers mix_buffers; /**< buffers between mixer and node */

 struct spa_list mix_list; /**< list of \ref pw_impl_port_mix */
 struct pw_map mix_port_map; /**< map from port_id from mixer */
 uint32_t n_mix;

 struct {
  struct spa_io_buffers io; /**< io area of the port */
  struct spa_io_clock clock; /**< io area of the clock */
  struct spa_list mix_list;
  struct spa_list node_link;
 } rt;     /**< data only accessed from the data thread */
 unsigned int added:1;
 unsigned int destroying:1;
 int busy_count;

 struct spa_latency_info latency[2]; /**< latencies */
 unsigned int have_latency_param:1;

 void *owner_data;  /**< extra owner data */
 void *user_data;                /**< extra user data */
};

struct pw_control_link {
 struct spa_list out_link;
 struct spa_list in_link;
 struct pw_control *output;
 struct pw_control *input;
 uint32_t out_port;
 uint32_t in_port;
 unsigned int valid:1;
};

#define pw_impl_link_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_link_events, m, v, ##__VA_ARGS__)
#define pw_impl_link_emit_destroy(l)  pw_impl_link_emit(l, destroy, 0)
#define pw_impl_link_emit_free(l)  pw_impl_link_emit(l, free, 0)
#define pw_impl_link_emit_initialized(l) pw_impl_link_emit(l, initialized, 0)
#define pw_impl_link_emit_info_changed(l,i) pw_impl_link_emit(l, info_changed, 0, i)
#define pw_impl_link_emit_state_changed(l,...) pw_impl_link_emit(l, state_changed, 0, __VA_ARGS__)
#define pw_impl_link_emit_port_unlinked(l,p) pw_impl_link_emit(l, port_unlinked, 0, p)

struct pw_impl_link {
 struct pw_context *context;  /**< context object */
 struct spa_list link;   /**< link in context link_list */
 struct pw_global *global;  /**< global for this link */
 struct spa_hook global_listener;

 char *name;

 struct pw_link_info info;  /**< introspectable link info */
 struct pw_properties *properties; /**< extra link properties */

 struct spa_io_buffers *io;  /**< link io area */

 struct pw_impl_port *output;  /**< output port */
 struct spa_list output_link;  /**< link in output port links */
 struct pw_impl_port *input;  /**< input port */
 struct spa_list input_link;  /**< link in input port links */

 struct spa_hook_list listener_list;

 struct pw_control_link control;
 struct pw_control_link notify;

 struct {
  struct pw_impl_port_mix out_mix; /**< port added to the output mixer */
  struct pw_impl_port_mix in_mix;  /**< port added to the input mixer */
  struct pw_node_target target;  /**< target to trigger the input node */
 } rt;

 void *user_data;

 unsigned int registered:1;
 unsigned int feedback:1;
 unsigned int preparing:1;
 unsigned int prepared:1;
 unsigned int passive:1;
};

#define pw_resource_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_resource_events, m, v, ##__VA_ARGS__)

#define pw_resource_emit_destroy(o) pw_resource_emit(o, destroy, 0)
#define pw_resource_emit_pong(o,s) pw_resource_emit(o, pong, 0, s)
#define pw_resource_emit_error(o,s,r,m) pw_resource_emit(o, error, 0, s, r, m)

struct pw_resource {
 struct spa_interface impl; /**< object implementation */

 struct pw_context *context; /**< the context object */
 struct pw_global *global; /**< global of resource */
 struct spa_list link;  /**< link in global resource_list */

 struct pw_impl_client *client; /**< owner client */

 uint32_t id;   /**< per client unique id, index in client objects */
 uint32_t permissions;  /**< resource permissions */
 const char *type;  /**< type of the client interface */
 uint32_t version;  /**< version of the client interface */
 uint32_t bound_id;  /**< global id we are bound to */
 int refcount;

 unsigned int removed:1;  /**< resource was removed from server */
 unsigned int destroyed:1; /**< resource was destroyed */

 struct spa_hook_list listener_list;
 struct spa_hook_list object_listener_list;

        const struct pw_protocol_marshal *marshal;

 void *user_data;  /**< extra user data */
};

#define pw_proxy_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_proxy_events, m, v, ##__VA_ARGS__)
#define pw_proxy_emit_destroy(p) pw_proxy_emit(p, destroy, 0)
#define pw_proxy_emit_bound(p,g) pw_proxy_emit(p, bound, 0, g)
#define pw_proxy_emit_removed(p) pw_proxy_emit(p, removed, 0)
#define pw_proxy_emit_done(p,s)  pw_proxy_emit(p, done, 0, s)
#define pw_proxy_emit_error(p,s,r,m) pw_proxy_emit(p, error, 0, s, r, m)

struct pw_proxy {
 struct spa_interface impl; /**< object implementation */

 struct pw_core *core;  /**< the owner core of this proxy */

 uint32_t id;   /**< client side id */
 const char *type;  /**< type of the interface */
 uint32_t version;  /**< client side version */
 uint32_t bound_id;  /**< global id we are bound to */
 int refcount;
 unsigned int zombie:1;  /**< proxy is removed locally and waiting to
  *  be removed from server */

 unsigned int removed:1;  /**< proxy was removed from server */
 unsigned int destroyed:1; /**< proxy was destroyed by client */
 unsigned int in_map:1;  /**< proxy is in core object map */

 struct spa_hook_list listener_list;
 struct spa_hook_list object_listener_list;

 const struct pw_protocol_marshal *marshal; /**< protocol specific marshal functions */

 void *user_data;  /**< extra user data */
};

struct pw_core {
 struct pw_proxy proxy;

 struct pw_context *context;  /**< context */
 struct spa_list link;   /**< link in context core_list */
 struct pw_properties *properties; /**< extra properties */

 struct pw_mempool *pool;  /**< memory pool */
 struct pw_core *core;   /**< proxy for the core object */
 struct spa_hook core_listener;
 struct spa_hook proxy_core_listener;

 struct pw_map objects;   /**< map of client side proxy objects
 *   indexed with the client id */

 struct pw_client *client;  /**< proxy for the client object */

 struct spa_list stream_list;  /**< list of \ref pw_stream objects */
 struct spa_list filter_list;  /**< list of \ref pw_stream objects */

 struct pw_protocol_client *conn; /**< the protocol client connection */
 int recv_seq;    /**< last received sequence number */
 int send_seq;    /**< last protocol result code */
 uint64_t recv_generation;  /**< last received registry generation */

 unsigned int removed:1;
 unsigned int destroyed:1;

 void *user_data;   /**< extra user data */
};

#define pw_stream_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_stream_events, m, v, ##__VA_ARGS__)
#define pw_stream_emit_destroy(s)  pw_stream_emit(s, destroy, 0)
#define pw_stream_emit_state_changed(s,o,n,e) pw_stream_emit(s, state_changed,0,o,n,e)
#define pw_stream_emit_io_changed(s,i,a,t) pw_stream_emit(s, io_changed,0,i,a,t)
#define pw_stream_emit_param_changed(s,i,p) pw_stream_emit(s, param_changed,0,i,p)
#define pw_stream_emit_add_buffer(s,b)  pw_stream_emit(s, add_buffer, 0, b)
#define pw_stream_emit_remove_buffer(s,b) pw_stream_emit(s, remove_buffer, 0, b)
#define pw_stream_emit_process(s)  pw_stream_emit(s, process, 0)
#define pw_stream_emit_drained(s)  pw_stream_emit(s, drained,0)
#define pw_stream_emit_control_info(s,i,c) pw_stream_emit(s, control_info, 0, i, c)
#define pw_stream_emit_command(s,c)  pw_stream_emit(s, command,1,c)
#define pw_stream_emit_trigger_done(s)  pw_stream_emit(s, trigger_done,2)


struct pw_stream {
 struct pw_core *core;   /**< the owner core */
 struct spa_hook core_listener;

 struct spa_list link;   /**< link in the core */

 char *name;    /**< the name of the stream */
 struct pw_properties *properties; /**< properties of the stream */

 uint32_t node_id;   /**< node id for remote node, available from
  *  CONFIGURE state and higher */

 enum pw_stream_state state;  /**< stream state */
 char *error;    /**< error reason when state is in error */

 struct spa_hook_list listener_list;

 struct pw_proxy *proxy;
 struct spa_hook proxy_listener;

 struct spa_hook node_listener;

 struct spa_list controls;
};

#define pw_filter_emit(s,m,v,...) spa_hook_list_call(&(s)->listener_list, struct pw_filter_events, m, v, ##__VA_ARGS__)
#define pw_filter_emit_destroy(s)  pw_filter_emit(s, destroy, 0)
#define pw_filter_emit_state_changed(s,o,n,e) pw_filter_emit(s, state_changed,0,o,n,e)
#define pw_filter_emit_io_changed(s,p,i,d,t) pw_filter_emit(s, io_changed,0,p,i,d,t)
#define pw_filter_emit_param_changed(s,p,i,f) pw_filter_emit(s, param_changed,0,p,i,f)
#define pw_filter_emit_add_buffer(s,p,b) pw_filter_emit(s, add_buffer, 0, p, b)
#define pw_filter_emit_remove_buffer(s,p,b) pw_filter_emit(s, remove_buffer, 0, p, b)
#define pw_filter_emit_process(s,p)  pw_filter_emit(s, process, 0, p)
#define pw_filter_emit_drained(s)  pw_filter_emit(s, drained, 0)
#define pw_filter_emit_command(s,c)  pw_filter_emit(s, command, 1, c)


struct pw_filter {
 struct pw_core *core; /**< the owner core proxy */
 struct spa_hook core_listener;

 struct spa_list link;   /**< link in the core proxy */

 char *name;    /**< the name of the filter */
 struct pw_properties *properties; /**< properties of the filter */

 uint32_t node_id;   /**< node id for remote node, available from
  *  CONFIGURE state and higher */

 enum pw_filter_state state;  /**< filter state */
 char *error;    /**< error reason when state is in error */

 struct spa_hook_list listener_list;

 struct pw_proxy *proxy;
 struct spa_hook proxy_listener;

 struct spa_list controls;
};

#define pw_impl_factory_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_factory_events, m, v, ##__VA_ARGS__)

#define pw_impl_factory_emit_destroy(s)  pw_impl_factory_emit(s, destroy, 0)
#define pw_impl_factory_emit_free(s)  pw_impl_factory_emit(s, free, 0)
#define pw_impl_factory_emit_initialized(s) pw_impl_factory_emit(s, initialized, 0)

struct pw_impl_factory {
 struct pw_context *context;  /**< the context */
 struct spa_list link;  /**< link in context factory_list */
 struct pw_global *global; /**< global for this factory */
 struct spa_hook global_listener;

 struct pw_factory_info info; /**< introspectable factory info */
 struct pw_properties *properties; /**< properties of the factory */

 struct spa_hook_list listener_list; /**< event listeners */

 struct spa_callbacks impl;

 void *user_data;

 unsigned int registered:1;
};

#define pw_control_emit(c,m,v,...) spa_hook_list_call(&c->listener_list, struct pw_control_events, m, v, ##__VA_ARGS__)
#define pw_control_emit_destroy(c) pw_control_emit(c, destroy, 0)
#define pw_control_emit_free(c)  pw_control_emit(c, free, 0)
#define pw_control_emit_linked(c,o) pw_control_emit(c, linked, 0, o)
#define pw_control_emit_unlinked(c,o) pw_control_emit(c, unlinked, 0, o)

struct pw_control {
 struct spa_list link;  /**< link in context control_list */
 struct pw_context *context;  /**< the context */

 struct pw_impl_port *port;  /**< owner port or NULL */
 struct spa_list port_link; /**< link in port control_list */

 enum spa_direction direction; /**< the direction */
 struct spa_list links;  /**< list of pw_control_link */

 uint32_t id;
 int32_t size;

 struct spa_hook_list listener_list;

 void *user_data;
};

/** Find a good format between 2 ports */
int pw_context_find_format(struct pw_context *context,
   struct pw_impl_port *output,
   struct pw_impl_port *input,
   struct pw_properties *props,
   uint32_t n_format_filters,
   struct spa_pod **format_filters,
   struct spa_pod **format,
   struct spa_pod_builder *builder,
   char **error);

/** Find a ports compatible with \a other_port and the format filters */
struct pw_impl_port *
pw_context_find_port(struct pw_context *context,
    struct pw_impl_port *other_port,
    uint32_t id,
    struct pw_properties *props,
    uint32_t n_format_filters,
    struct spa_pod **format_filters,
    char **error);

int pw_context_debug_port_params(struct pw_context *context,
  struct spa_node *node, enum spa_direction direction,
  uint32_t port_id, uint32_t id, int err, const char *debug, ...);

const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, const char *type);

int pw_proxy_init(struct pw_proxy *proxy, const char *type, uint32_t version);

void pw_proxy_remove(struct pw_proxy *proxy);

int pw_context_recalc_graph(struct pw_context *context, const char *reason);

void pw_impl_port_update_info(struct pw_impl_port *port, const struct spa_port_info *info);

int pw_impl_port_register(struct pw_impl_port *port,
       struct pw_properties *properties);

/** Get the user data of a port, the size of the memory was given \ref in pw_context_create_port */
void * pw_impl_port_get_user_data(struct pw_impl_port *port);

int pw_impl_port_set_mix(struct pw_impl_port *port, struct spa_node *node, uint32_t flags);

int pw_impl_port_init_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix);
int pw_impl_port_release_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix);

void pw_impl_port_update_state(struct pw_impl_port *port, enum pw_impl_port_state state, int res, char *error);

/** Unlink a port */
void pw_impl_port_unlink(struct pw_impl_port *port);

/** Destroy a port */
void pw_impl_port_destroy(struct pw_impl_port *port);

/** Iterate the params of the given port. The callback should return
 * 1 to fetch the next item, 0 to stop iteration or <0 on error.
 * The function returns 0 on success or the error returned by the callback. */

int pw_impl_port_for_each_param(struct pw_impl_port *port,
      int seq, uint32_t param_id,
      uint32_t index, uint32_t max,
      const struct spa_pod *filter,
      int (*callback) (void *data, int seq,
         uint32_t id, uint32_t index, uint32_t next,
         struct spa_pod *param),
      void *data);

int pw_impl_port_for_each_filtered_param(struct pw_impl_port *in_port,
        struct pw_impl_port *out_port,
        int seq,
        uint32_t in_param_id,
        uint32_t out_param_id,
        const struct spa_pod *filter,
        int (*callback) (void *data, int seq,
           uint32_t id, uint32_t index, uint32_t next,
           struct spa_pod *param),
        void *data);

/** Iterate the links of the port. The callback should return
 * 0 to fetch the next item, any other value stops the iteration and returns
 * the value. When all callbacks return 0, this function returns 0 when all
 * items are iterated. */

int pw_impl_port_for_each_link(struct pw_impl_port *port,
      int (*callback) (void *data, struct pw_impl_link *link),
      void *data);

/** Set a param on a port, use SPA_ID_INVALID for mix_id to set
 * the param on all mix ports */

int pw_impl_port_set_param(struct pw_impl_port *port,
  uint32_t id, uint32_t flags, const struct spa_pod *param);

/** Use buffers on a port */
int pw_impl_port_use_buffers(struct pw_impl_port *port, struct pw_impl_port_mix *mix, uint32_t flags,
  struct spa_buffer **buffers, uint32_t n_buffers);

int pw_impl_port_recalc_latency(struct pw_impl_port *port);

/** Change the state of the node */
int pw_impl_node_set_state(struct pw_impl_node *node, enum pw_node_state state);

int pw_impl_node_set_param(struct pw_impl_node *node,
  uint32_t id, uint32_t flags, const struct spa_pod *param);

int pw_impl_node_update_ports(struct pw_impl_node *node);

int pw_impl_node_set_driver(struct pw_impl_node *node, struct pw_impl_node *driver);

/** Prepare a link
  * Starts the negotiation of formats and buffers on \a link */

int pw_impl_link_prepare(struct pw_impl_link *link);
/** starts streaming on a link */
int pw_impl_link_activate(struct pw_impl_link *link);

/** Deactivate a link */
int pw_impl_link_deactivate(struct pw_impl_link *link);

struct pw_control *
pw_control_new(struct pw_context *context,
        struct pw_impl_port *owner,  /**< can be NULL */
        uint32_t id, uint32_t size,
        size_t user_data_size  /**< extra user data */);

int pw_control_add_link(struct pw_control *control, uint32_t cmix,
  struct pw_control *other, uint32_t omix,
  struct pw_control_link *link);

int pw_control_remove_link(struct pw_control_link *link);

void pw_control_destroy(struct pw_control *control);

void pw_impl_client_unref(struct pw_impl_client *client);

#define PW_LOG_OBJECT_POD (1<<0)
void pw_log_log_object(enum spa_log_level level, const char *file, int line,
    const char *func, uint32_t flags, const void *object);

#define pw_log_object(lev,fl,obj)      \
({          \
 if (SPA_UNLIKELY(pw_log_level_enabled (lev)))    \
  pw_log_log_object(lev,__FILE__,__LINE__,__func__,(fl),(obj)); \
})

#define pw_log_pod(lev,pod) pw_log_object(lev,PW_LOG_OBJECT_POD,pod)
#define pw_log_format(lev,pod) pw_log_object(lev,PW_LOG_OBJECT_POD,pod)

bool pw_log_is_default(void);

void pw_log_init(void);
void pw_log_deinit(void);

void pw_settings_init(struct pw_context *context);
int pw_settings_expose(struct pw_context *context);
void pw_settings_clean(struct pw_context *context);

void pw_impl_module_schedule_destroy(struct pw_impl_module *module);

pthread_attr_t *pw_thread_fill_attr(const struct spa_dict *props, pthread_attr_t *attr);

/** \endcond */

#ifdef __cplusplus
}
#endif

#endif /* PIPEWIRE_PRIVATE_H */

Messung V0.5
C=77 H=100 G=89

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.