diff options
Diffstat (limited to 'third_party/pipewire/spa/support')
-rw-r--r-- | third_party/pipewire/spa/support/cpu.h | 126 | ||||
-rw-r--r-- | third_party/pipewire/spa/support/dbus.h | 100 | ||||
-rw-r--r-- | third_party/pipewire/spa/support/log-impl.h | 86 | ||||
-rw-r--r-- | third_party/pipewire/spa/support/log.h | 179 | ||||
-rw-r--r-- | third_party/pipewire/spa/support/loop.h | 312 | ||||
-rw-r--r-- | third_party/pipewire/spa/support/plugin.h | 215 | ||||
-rw-r--r-- | third_party/pipewire/spa/support/system.h | 152 |
7 files changed, 1170 insertions, 0 deletions
diff --git a/third_party/pipewire/spa/support/cpu.h b/third_party/pipewire/spa/support/cpu.h new file mode 100644 index 0000000000..80f7aefd41 --- /dev/null +++ b/third_party/pipewire/spa/support/cpu.h @@ -0,0 +1,126 @@ +/* Simple Plugin API + * + * 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 SPA_CPU_H +#define SPA_CPU_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdarg.h> + +#include <spa/utils/defs.h> +#include <spa/utils/hook.h> + +/** + * The CPU features interface + */ +#define SPA_TYPE_INTERFACE_CPU SPA_TYPE_INFO_INTERFACE_BASE "CPU" + +#define SPA_VERSION_CPU 0 +struct spa_cpu { struct spa_interface iface; }; + +/* x86 specific */ +#define SPA_CPU_FLAG_MMX (1<<0) /**< standard MMX */ +#define SPA_CPU_FLAG_MMXEXT (1<<1) /**< SSE integer or AMD MMX ext */ +#define SPA_CPU_FLAG_3DNOW (1<<2) /**< AMD 3DNOW */ +#define SPA_CPU_FLAG_SSE (1<<3) /**< SSE */ +#define SPA_CPU_FLAG_SSE2 (1<<4) /**< SSE2 */ +#define SPA_CPU_FLAG_3DNOWEXT (1<<5) /**< AMD 3DNowExt */ +#define SPA_CPU_FLAG_SSE3 (1<<6) /**< Prescott SSE3 */ +#define SPA_CPU_FLAG_SSSE3 (1<<7) /**< Conroe SSSE3 */ +#define SPA_CPU_FLAG_SSE41 (1<<8) /**< Penryn SSE4.1 */ +#define SPA_CPU_FLAG_SSE42 (1<<9) /**< Nehalem SSE4.2 */ +#define SPA_CPU_FLAG_AESNI (1<<10) /**< Advanced Encryption Standard */ +#define SPA_CPU_FLAG_AVX (1<<11) /**< AVX */ +#define SPA_CPU_FLAG_XOP (1<<12) /**< Bulldozer XOP */ +#define SPA_CPU_FLAG_FMA4 (1<<13) /**< Bulldozer FMA4 */ +#define SPA_CPU_FLAG_CMOV (1<<14) /**< supports cmov */ +#define SPA_CPU_FLAG_AVX2 (1<<15) /**< AVX2 */ +#define SPA_CPU_FLAG_FMA3 (1<<16) /**< Haswell FMA3 */ +#define SPA_CPU_FLAG_BMI1 (1<<17) /**< Bit Manipulation Instruction Set 1 */ +#define SPA_CPU_FLAG_BMI2 (1<<18) /**< Bit Manipulation Instruction Set 2 */ +#define SPA_CPU_FLAG_AVX512 (1<<19) /**< AVX-512 */ +#define SPA_CPU_FLAG_SLOW_UNALIGNED (1<<20) /**< unaligned loads/stores are slow */ + +/* PPC specific */ +#define SPA_CPU_FLAG_ALTIVEC (1<<0) /**< standard */ +#define SPA_CPU_FLAG_VSX (1<<1) /**< ISA 2.06 */ +#define SPA_CPU_FLAG_POWER8 (1<<2) /**< ISA 2.07 */ + +/* ARM specific */ +#define SPA_CPU_FLAG_ARMV5TE (1 << 0) +#define SPA_CPU_FLAG_ARMV6 (1 << 1) +#define SPA_CPU_FLAG_ARMV6T2 (1 << 2) +#define SPA_CPU_FLAG_VFP (1 << 3) +#define SPA_CPU_FLAG_VFPV3 (1 << 4) +#define SPA_CPU_FLAG_NEON (1 << 5) +#define SPA_CPU_FLAG_ARMV8 (1 << 6) + +#define SPA_CPU_FORCE_AUTODETECT ((uint32_t)-1) +/** + * methods + */ +struct spa_cpu_methods { + /** the version of the methods. This can be used to expand this + structure in the future */ +#define SPA_VERSION_CPU_METHODS 0 + uint32_t version; + + /** get CPU flags */ + uint32_t (*get_flags) (void *object); + + /** force CPU flags, use SPA_CPU_FORCE_AUTODETECT to autodetect CPU flags */ + int (*force_flags) (void *object, uint32_t flags); + + /** get number of CPU cores */ + uint32_t (*get_count) (void *object); + + /** get maximum required alignment of data */ + uint32_t (*get_max_align) (void *object); +}; + +#define spa_cpu_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + struct spa_cpu *_c = o; \ + spa_interface_call_res(&_c->iface, \ + struct spa_cpu_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) +#define spa_cpu_get_flags(c) spa_cpu_method(c, get_flags, 0) +#define spa_cpu_force_flags(c,f) spa_cpu_method(c, force_flags, 0, f) +#define spa_cpu_get_count(c) spa_cpu_method(c, get_count, 0) +#define spa_cpu_get_max_align(c) spa_cpu_method(c, get_max_align, 0) + +/** keys can be given when initializing the cpu handle */ +#define SPA_KEY_CPU_FORCE "cpu.force" /**< force cpu flags */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_CPU_H */ diff --git a/third_party/pipewire/spa/support/dbus.h b/third_party/pipewire/spa/support/dbus.h new file mode 100644 index 0000000000..ecef81485f --- /dev/null +++ b/third_party/pipewire/spa/support/dbus.h @@ -0,0 +1,100 @@ +/* Simple Plugin API + * + * 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 SPA_DBUS_H +#define SPA_DBUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <spa/support/loop.h> + +#define SPA_TYPE_INTERFACE_DBus SPA_TYPE_INFO_INTERFACE_BASE "DBus" + +#define SPA_VERSION_DBUS 0 +struct spa_dbus { struct spa_interface iface; }; + +enum spa_dbus_type { + SPA_DBUS_TYPE_SESSION, /**< The login session bus */ + SPA_DBUS_TYPE_SYSTEM, /**< The systemwide bus */ + SPA_DBUS_TYPE_STARTER /**< The bus that started us, if any */ +}; + +struct spa_dbus_connection { +#define SPA_VERSION_DBUS_CONNECTION 0 + uint32_t version; + /** + * Get the DBusConnection from a wrapper + * + * \param conn the spa_dbus_connection wrapper + * \return a pointer of type DBusConnection + */ + void *(*get) (struct spa_dbus_connection *conn); + /** + * Destroy a dbus connection wrapper + * + * \param conn the wrapper to destroy + */ + void (*destroy) (struct spa_dbus_connection *conn); +}; + +#define spa_dbus_connection_get(c) (c)->get((c)) +#define spa_dbus_connection_destroy(c) (c)->destroy((c)) + +struct spa_dbus_methods { +#define SPA_VERSION_DBUS_METHODS 0 + uint32_t version; + + /** + * Get a new connection wrapper for the given bus type. + * + * The connection wrapper is completely configured to operate + * in the main context of the handle that manages the spa_dbus + * interface. + * + * \param dbus the dbus manager + * \param type the bus type to wrap + * \param error location for the DBusError + * \return a new dbus connection wrapper or NULL on error + */ + struct spa_dbus_connection * (*get_connection) (void *object, + enum spa_dbus_type type); +}; + +static inline struct spa_dbus_connection * +spa_dbus_get_connection(struct spa_dbus *dbus, enum spa_dbus_type type) +{ + struct spa_dbus_connection *res = NULL; + spa_interface_call_res(&dbus->iface, + struct spa_dbus_methods, res, + get_connection, 0, type); + return res; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_DBUS_H */ diff --git a/third_party/pipewire/spa/support/log-impl.h b/third_party/pipewire/spa/support/log-impl.h new file mode 100644 index 0000000000..f0f4247412 --- /dev/null +++ b/third_party/pipewire/spa/support/log-impl.h @@ -0,0 +1,86 @@ +/* Simple Plugin API + * + * 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 SPA_LOG_IMPL_H +#define SPA_LOG_IMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> + +#include <spa/utils/type.h> +#include <spa/support/log.h> + +static inline SPA_PRINTF_FUNC(6, 0) void spa_log_impl_logv(void *object, + enum spa_log_level level, + const char *file, + int line, + const char *func, + const char *fmt, + va_list args) +{ + char text[512], location[1024]; + static const char *levels[] = { "-", "E", "W", "I", "D", "T" }; + + vsnprintf(text, sizeof(text), fmt, args); + snprintf(location, sizeof(location), "[%s][%s:%i %s()] %s\n", + levels[level], strrchr(file, '/') + 1, line, func, text); + fputs(location, stderr); +} +static inline SPA_PRINTF_FUNC(6,7) void spa_log_impl_log(void *object, + enum spa_log_level level, + const char *file, + int line, + const char *func, + const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + spa_log_impl_logv(object, level, file, line, func, fmt, args); + va_end(args); +} + +#define SPA_LOG_IMPL_DEFINE(name) \ +struct { \ + struct spa_log log; \ + struct spa_log_methods methods; \ +} name + +#define SPA_LOG_IMPL_INIT(name) \ + { { { SPA_TYPE_INTERFACE_Log, SPA_VERSION_LOG, \ + SPA_CALLBACKS_INIT(&name.methods, &name) }, \ + SPA_LOG_LEVEL_INFO, }, \ + { SPA_VERSION_LOG_METHODS, \ + spa_log_impl_log, \ + spa_log_impl_logv,} } + +#define SPA_LOG_IMPL(name) \ + SPA_LOG_IMPL_DEFINE(name) = SPA_LOG_IMPL_INIT(name) + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* SPA_LOG_IMPL_H */ diff --git a/third_party/pipewire/spa/support/log.h b/third_party/pipewire/spa/support/log.h new file mode 100644 index 0000000000..51b3e741c7 --- /dev/null +++ b/third_party/pipewire/spa/support/log.h @@ -0,0 +1,179 @@ +/* Simple Plugin API + * + * 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 SPA_LOG_H +#define SPA_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdarg.h> + +#include <spa/utils/defs.h> +#include <spa/utils/hook.h> + +enum spa_log_level { + SPA_LOG_LEVEL_NONE = 0, + SPA_LOG_LEVEL_ERROR, + SPA_LOG_LEVEL_WARN, + SPA_LOG_LEVEL_INFO, + SPA_LOG_LEVEL_DEBUG, + SPA_LOG_LEVEL_TRACE, +}; + +/** + * The Log interface + */ +#define SPA_TYPE_INTERFACE_Log SPA_TYPE_INFO_INTERFACE_BASE "Log" + +#define SPA_VERSION_LOG 0 + +struct spa_log { + /** the version of this log. This can be used to expand this + * structure in the future */ + struct spa_interface iface; + /** + * Logging level, everything above this level is not logged + */ + enum spa_log_level level; +}; + +struct spa_log_methods { +#define SPA_VERSION_LOG_METHODS 0 + uint32_t version; + /** + * Log a message with the given log level. + * + * \param log a spa_log + * \param level a spa_log_level + * \param file the file name + * \param line the line number + * \param func the function name + * \param fmt printf style format + * \param ... format arguments + */ + void (*log) (void *object, + enum spa_log_level level, + const char *file, + int line, + const char *func, + const char *fmt, ...) SPA_PRINTF_FUNC(6, 7); + + /** + * Log a message with the given log level. + * + * \param log a spa_log + * \param level a spa_log_level + * \param file the file name + * \param line the line number + * \param func the function name + * \param fmt printf style format + * \param args format arguments + */ + void (*logv) (void *object, + enum spa_log_level level, + const char *file, + int line, + const char *func, + const char *fmt, + va_list args) SPA_PRINTF_FUNC(6, 0); +}; + +#define spa_log_level_enabled(l,lev) ((l) && (l)->level >= (lev)) + +#if defined(__USE_ISOC11) || defined(__USE_ISOC99) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) + +#define spa_log_log(l,lev,...) \ +({ \ + struct spa_log *_l = l; \ + if (SPA_UNLIKELY(spa_log_level_enabled(_l, lev))) \ + spa_interface_call(&_l->iface, \ + struct spa_log_methods, log, 0, lev, \ + __VA_ARGS__); \ +}) + +#define spa_log_logv(l,lev,...) \ +({ \ + struct spa_log *_l = l; \ + if (SPA_UNLIKELY(spa_log_level_enabled(_l, lev))) \ + spa_interface_call(&_l->iface, \ + struct spa_log_methods, logv, 0, lev, \ + __VA_ARGS__); \ +}) + +#define spa_log_error(l,...) spa_log_log(l,SPA_LOG_LEVEL_ERROR,__FILE__,__LINE__,__func__,__VA_ARGS__) +#define spa_log_warn(l,...) spa_log_log(l,SPA_LOG_LEVEL_WARN,__FILE__,__LINE__,__func__,__VA_ARGS__) +#define spa_log_info(l,...) spa_log_log(l,SPA_LOG_LEVEL_INFO,__FILE__,__LINE__,__func__,__VA_ARGS__) +#define spa_log_debug(l,...) spa_log_log(l,SPA_LOG_LEVEL_DEBUG,__FILE__,__LINE__,__func__,__VA_ARGS__) +#define spa_log_trace(l,...) spa_log_log(l,SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__) + +#ifndef FASTPATH +#define spa_log_trace_fp(l,...) spa_log_log(l,SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__) +#else +#define spa_log_trace_fp(l,...) +#endif + +#else + +#define SPA_LOG_FUNC(name,lev) \ +static inline SPA_PRINTF_FUNC(2,3) void spa_log_##name (struct spa_log *l, const char *format, ...) \ +{ \ + if (SPA_UNLIKELY(spa_log_level_enabled(l, lev))) { \ + va_list varargs; \ + va_start (varargs, format); \ + spa_interface_call(&l->iface, \ + struct spa_log_methods, logv, 0, lev, \ + __FILE__,__LINE__,__func__,format,varargs); \ + va_end (varargs); \ + } \ +} + +SPA_LOG_FUNC(error, SPA_LOG_LEVEL_ERROR) +SPA_LOG_FUNC(warn, SPA_LOG_LEVEL_WARN) +SPA_LOG_FUNC(info, SPA_LOG_LEVEL_INFO) +SPA_LOG_FUNC(debug, SPA_LOG_LEVEL_DEBUG) +SPA_LOG_FUNC(trace, SPA_LOG_LEVEL_TRACE) + +#ifndef FASTPATH +SPA_LOG_FUNC(trace_fp, SPA_LOG_LEVEL_TRACE) +#else +static inline void spa_log_trace_fp (struct spa_log *l, const char *format, ...) { } +#endif + +#endif + +/** keys can be given when initializing the logger handle */ +#define SPA_KEY_LOG_LEVEL "log.level" /**< the default log level */ +#define SPA_KEY_LOG_COLORS "log.colors" /**< enable colors in the logger */ +#define SPA_KEY_LOG_FILE "log.file" /**< log to the specified file instead of + * stderr. */ +#define SPA_KEY_LOG_TIMESTAMP "log.timestamp" /**< log timestamps */ +#define SPA_KEY_LOG_LINE "log.line" /**< log file and line numbers */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* SPA_LOG_H */ diff --git a/third_party/pipewire/spa/support/loop.h b/third_party/pipewire/spa/support/loop.h new file mode 100644 index 0000000000..34ddaa89e5 --- /dev/null +++ b/third_party/pipewire/spa/support/loop.h @@ -0,0 +1,312 @@ +/* Simple Plugin API + * + * 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 SPA_LOOP_H +#define SPA_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <spa/utils/defs.h> +#include <spa/utils/hook.h> +#include <spa/support/system.h> + +#define SPA_TYPE_INTERFACE_Loop SPA_TYPE_INFO_INTERFACE_BASE "Loop" +#define SPA_TYPE_INTERFACE_DataLoop SPA_TYPE_INFO_INTERFACE_BASE "DataLoop" +#define SPA_VERSION_LOOP 0 +struct spa_loop { struct spa_interface iface; }; + +#define SPA_TYPE_INTERFACE_LoopControl SPA_TYPE_INFO_INTERFACE_BASE "LoopControl" +#define SPA_VERSION_LOOP_CONTROL 0 +struct spa_loop_control { struct spa_interface iface; }; + +#define SPA_TYPE_INTERFACE_LoopUtils SPA_TYPE_INFO_INTERFACE_BASE "LoopUtils" +#define SPA_VERSION_LOOP_UTILS 0 +struct spa_loop_utils { struct spa_interface iface; }; + +struct spa_source; + +typedef void (*spa_source_func_t) (struct spa_source *source); + +struct spa_source { + struct spa_loop *loop; + spa_source_func_t func; + void *data; + int fd; + uint32_t mask; + uint32_t rmask; +}; + +typedef int (*spa_invoke_func_t) (struct spa_loop *loop, + bool async, + uint32_t seq, + const void *data, + size_t size, + void *user_data); + +/** + * Register sources and work items to an event loop + */ +struct spa_loop_methods { + /* the version of this structure. This can be used to expand this + * structure in the future */ +#define SPA_VERSION_LOOP_METHODS 0 + uint32_t version; + + /** add a source to the loop */ + int (*add_source) (void *object, + struct spa_source *source); + + /** update the source io mask */ + int (*update_source) (void *object, + struct spa_source *source); + + /** remove a source from the loop */ + int (*remove_source) (void *object, + struct spa_source *source); + + /** invoke a function in the context of this loop */ + int (*invoke) (void *object, + spa_invoke_func_t func, + uint32_t seq, + const void *data, + size_t size, + bool block, + void *user_data); +}; + +#define spa_loop_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + struct spa_loop *_o = o; \ + spa_interface_call_res(&_o->iface, \ + struct spa_loop_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define spa_loop_add_source(l,...) spa_loop_method(l,add_source,0,##__VA_ARGS__) +#define spa_loop_update_source(l,...) spa_loop_method(l,update_source,0,##__VA_ARGS__) +#define spa_loop_remove_source(l,...) spa_loop_method(l,remove_source,0,##__VA_ARGS__) +#define spa_loop_invoke(l,...) spa_loop_method(l,invoke,0,##__VA_ARGS__) + + +/** Control hooks. These hooks can't be removed from their + * callbacks and must be removed from a safe place (when the loop + * is not running or when it is locked). */ +struct spa_loop_control_hooks { +#define SPA_VERSION_LOOP_CONTROL_HOOKS 0 + uint32_t version; + /** Executed right before waiting for events. It is typically used to + * release locks. */ + void (*before) (void *data); + /** Executed right after waiting for events. It is typically used to + * reacquire locks. */ + void (*after) (void *data); +}; + +#define spa_loop_control_hook_before(l) \ +({ \ + struct spa_hook_list *_l = l; \ + struct spa_hook *_h; \ + spa_list_for_each_reverse(_h, &_l->list, link) \ + spa_callbacks_call(&_h->cb, struct spa_loop_control_hooks, before, 0); \ +}) + +#define spa_loop_control_hook_after(l) \ +({ \ + struct spa_hook_list *_l = l; \ + struct spa_hook *_h; \ + spa_list_for_each(_h, &_l->list, link) \ + spa_callbacks_call(&_h->cb, struct spa_loop_control_hooks, after, 0); \ +}) + +/** + * Control an event loop + */ +struct spa_loop_control_methods { + /* the version of this structure. This can be used to expand this + * structure in the future */ +#define SPA_VERSION_LOOP_CONTROL_METHODS 0 + uint32_t version; + + int (*get_fd) (void *object); + + /** Add a hook + * \param ctrl the control to change + * \param hooks the hooks to add + * + * Adds hooks to the loop controlled by \a ctrl. + */ + void (*add_hook) (void *object, + struct spa_hook *hook, + const struct spa_loop_control_hooks *hooks, + void *data); + + /** Enter a loop + * \param ctrl the control + * + * Start an iteration of the loop. This function should be called + * before calling iterate and is typically used to capture the thread + * that this loop will run in. + */ + void (*enter) (void *object); + /** Leave a loop + * \param ctrl the control + * + * Ends the iteration of a loop. This should be called after calling + * iterate. + */ + void (*leave) (void *object); + + /** Perform one iteration of the loop. + * \param ctrl the control + * \param timeout an optional timeout in milliseconds. + * 0 for no timeout, -1 for infinite timeout. + * + * This function will block + * up to \a timeout milliseconds and then dispatch the fds with activity. + * The number of dispatched fds is returned. + */ + int (*iterate) (void *object, int timeout); +}; + +#define spa_loop_control_method_v(o,method,version,...) \ +({ \ + struct spa_loop_control *_o = o; \ + spa_interface_call(&_o->iface, \ + struct spa_loop_control_methods, \ + method, version, ##__VA_ARGS__); \ +}) + +#define spa_loop_control_method_r(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + struct spa_loop_control *_o = o; \ + spa_interface_call_res(&_o->iface, \ + struct spa_loop_control_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define spa_loop_control_get_fd(l) spa_loop_control_method_r(l,get_fd,0) +#define spa_loop_control_add_hook(l,...) spa_loop_control_method_v(l,add_hook,0,__VA_ARGS__) +#define spa_loop_control_enter(l) spa_loop_control_method_v(l,enter,0) +#define spa_loop_control_leave(l) spa_loop_control_method_v(l,leave,0) +#define spa_loop_control_iterate(l,...) spa_loop_control_method_r(l,iterate,0,__VA_ARGS__) + +typedef void (*spa_source_io_func_t) (void *data, int fd, uint32_t mask); +typedef void (*spa_source_idle_func_t) (void *data); +typedef void (*spa_source_event_func_t) (void *data, uint64_t count); +typedef void (*spa_source_timer_func_t) (void *data, uint64_t expirations); +typedef void (*spa_source_signal_func_t) (void *data, int signal_number); + +/** + * Create sources for an event loop + */ +struct spa_loop_utils_methods { + /* the version of this structure. This can be used to expand this + * structure in the future */ +#define SPA_VERSION_LOOP_UTILS_METHODS 0 + uint32_t version; + + struct spa_source *(*add_io) (void *object, + int fd, + uint32_t mask, + bool close, + spa_source_io_func_t func, void *data); + + int (*update_io) (void *object, struct spa_source *source, uint32_t mask); + + struct spa_source *(*add_idle) (void *object, + bool enabled, + spa_source_idle_func_t func, void *data); + int (*enable_idle) (void *object, struct spa_source *source, bool enabled); + + struct spa_source *(*add_event) (void *object, + spa_source_event_func_t func, void *data); + int (*signal_event) (void *object, struct spa_source *source); + + struct spa_source *(*add_timer) (void *object, + spa_source_timer_func_t func, void *data); + int (*update_timer) (void *object, + struct spa_source *source, + struct timespec *value, + struct timespec *interval, + bool absolute); + struct spa_source *(*add_signal) (void *object, + int signal_number, + spa_source_signal_func_t func, void *data); + + /** destroy a source allocated with this interface. This function + * should only be called when the loop is not running or from the + * context of the running loop */ + void (*destroy_source) (void *object, struct spa_source *source); +}; + +#define spa_loop_utils_method_v(o,method,version,...) \ +({ \ + struct spa_loop_utils *_o = o; \ + spa_interface_call(&_o->iface, \ + struct spa_loop_utils_methods, \ + method, version, ##__VA_ARGS__); \ +}) + +#define spa_loop_utils_method_r(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + struct spa_loop_utils *_o = o; \ + spa_interface_call_res(&_o->iface, \ + struct spa_loop_utils_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) +#define spa_loop_utils_method_s(o,method,version,...) \ +({ \ + struct spa_source *_res = NULL; \ + struct spa_loop_utils *_o = o; \ + spa_interface_call_res(&_o->iface, \ + struct spa_loop_utils_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + + +#define spa_loop_utils_add_io(l,...) spa_loop_utils_method_s(l,add_io,0,__VA_ARGS__) +#define spa_loop_utils_update_io(l,...) spa_loop_utils_method_r(l,update_io,0,__VA_ARGS__) +#define spa_loop_utils_add_idle(l,...) spa_loop_utils_method_s(l,add_idle,0,__VA_ARGS__) +#define spa_loop_utils_enable_idle(l,...) spa_loop_utils_method_r(l,enable_idle,0,__VA_ARGS__) +#define spa_loop_utils_add_event(l,...) spa_loop_utils_method_s(l,add_event,0,__VA_ARGS__) +#define spa_loop_utils_signal_event(l,...) spa_loop_utils_method_r(l,signal_event,0,__VA_ARGS__) +#define spa_loop_utils_add_timer(l,...) spa_loop_utils_method_s(l,add_timer,0,__VA_ARGS__) +#define spa_loop_utils_update_timer(l,...) spa_loop_utils_method_r(l,update_timer,0,__VA_ARGS__) +#define spa_loop_utils_add_signal(l,...) spa_loop_utils_method_s(l,add_signal,0,__VA_ARGS__) +#define spa_loop_utils_destroy_source(l,...) spa_loop_utils_method_v(l,destroy_source,0,__VA_ARGS__) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_LOOP_H */ diff --git a/third_party/pipewire/spa/support/plugin.h b/third_party/pipewire/spa/support/plugin.h new file mode 100644 index 0000000000..ea4fc2255d --- /dev/null +++ b/third_party/pipewire/spa/support/plugin.h @@ -0,0 +1,215 @@ +/* Simple Plugin API + * + * 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 SPA_PLUGIN_H +#define SPA_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <spa/utils/defs.h> +#include <spa/utils/dict.h> + +struct spa_handle { + /** Version of this struct */ +#define SPA_VERSION_HANDLE 0 + uint32_t version; + + /** + * Get the interface provided by \a handle with \a type. + * + * \a interface is always a struct spa_interface but depending on + * \a type, the struct might contain other information. + * + * \param handle a spa_handle + * \param type the interface type + * \param interface result to hold the interface. + * \return 0 on success + * -ENOTSUP when there are no interfaces + * -EINVAL when handle or info is NULL + */ + int (*get_interface) (struct spa_handle *handle, const char *type, void **interface); + /** + * Clean up the memory of \a handle. After this, \a handle should not be used + * anymore. + * + * \param handle a pointer to memory + * \return 0 on success + */ + int (*clear) (struct spa_handle *handle); +}; + +#define spa_handle_get_interface(h,...) (h)->get_interface((h),__VA_ARGS__) +#define spa_handle_clear(h) (h)->clear((h)) + +/** + * This structure lists the information about available interfaces on + * handles. + */ +struct spa_interface_info { + const char *type; /*< the type of the interface, can be + * used to get the interface */ +}; + +/** + * Extra supporting infrastructure passed to the init() function of + * a factory. It can be extra information or interfaces such as logging. + */ +struct spa_support { + const char *type; /*< the type of the support item */ + void *data; /*< specific data for the item */ +}; + +/** Find a support item of the given type */ +static inline void *spa_support_find(const struct spa_support *support, + uint32_t n_support, + const char *type) +{ + uint32_t i; + for (i = 0; i < n_support; i++) { + if (strcmp(support[i].type, type) == 0) + return support[i].data; + } + return NULL; +} + +#define SPA_SUPPORT_INIT(type,data) (struct spa_support) { (type), (data) } + +struct spa_handle_factory { + /** The version of this structure */ +#define SPA_VERSION_HANDLE_FACTORY 1 + uint32_t version; + /** + * The name of the factory contains a logical name that describes + * the function of the handle. Other plugins might contain an alternative + * implementation with the same name. + * + * See utils/names.h for the list of standard names. + * + * Examples include: + * + * api.alsa.pcm.sink: an object to write PCM samples to an alsa PLAYBACK + * device + * api.v4l2.source: an object to read from a v4l2 source. + */ + const char *name; + /** + * Extra information about the handles of this factory. + */ + const struct spa_dict *info; + /** + * Get the size of handles from this factory. + * + * \param factory a spa_handle_factory + * \param params extra parameters that determine the size of the + * handle. + */ + size_t (*get_size) (const struct spa_handle_factory *factory, + const struct spa_dict *params); + + /** + * Initialize an instance of this factory. The caller should allocate + * memory at least size bytes and pass this as \a handle. + * + * \a support can optionally contain extra interfaces or data items that the + * plugin can use such as a logger. + * + * \param factory a spa_handle_factory + * \param handle a pointer to memory + * \param info extra handle specific information, usually obtained + * from a spa_device. This can be used to configure the handle. + * \param support support items + * \param n_support number of elements in \a support + * \return 0 on success + * < 0 errno type error + */ + int (*init) (const struct spa_handle_factory *factory, + struct spa_handle *handle, + const struct spa_dict *info, + const struct spa_support *support, + uint32_t n_support); + + /** + * spa_handle_factory::enum_interface_info: + * \param factory: a #spa_handle_factory + * \param info: result to hold spa_interface_info. + * \param index: index to keep track of the enumeration, 0 for first item + * + * Enumerate the interface information for \a factory. + * + * \return 1 when an item is available + * 0 when no more items are available + * < 0 errno type error + */ + int (*enum_interface_info) (const struct spa_handle_factory *factory, + const struct spa_interface_info **info, + uint32_t *index); +}; + +#define spa_handle_factory_get_size(h,...) (h)->get_size((h),__VA_ARGS__) +#define spa_handle_factory_init(h,...) (h)->init((h),__VA_ARGS__) +#define spa_handle_factory_enum_interface_info(h,...) (h)->enum_interface_info((h),__VA_ARGS__) + +/** + * The function signature of the entry point in a plugin. + * + * \param factory a location to hold the factory result + * \param index index to keep track of the enumeration + * \return 1 on success + * 0 when there are no more factories + * -EINVAL when factory is NULL + */ +typedef int (*spa_handle_factory_enum_func_t) (const struct spa_handle_factory **factory, + uint32_t *index); + +#define SPA_HANDLE_FACTORY_ENUM_FUNC_NAME "spa_handle_factory_enum" + +/** + * The entry point in a plugin. + * + * \param factory a location to hold the factory result + * \param index index to keep track of the enumeration + * \return 1 on success + * 0 when no more items are available + * < 0 errno type error + */ +int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index); + + + +#define SPA_KEY_FACTORY_NAME "factory.name" /**< the name of a factory */ +#define SPA_KEY_FACTORY_AUTHOR "factory.author" /**< a comma separated list of factory authors */ +#define SPA_KEY_FACTORY_DESCRIPTION "factory.description" /**< description of a factory */ +#define SPA_KEY_FACTORY_USAGE "factory.usage" /**< usage of a factory */ + +#define SPA_KEY_LIBRARY_NAME "library.name" /**< the name of a library. This is usually + * the filename of the plugin without the + * path or the plugin extension. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PLUGIN_H */ diff --git a/third_party/pipewire/spa/support/system.h b/third_party/pipewire/spa/support/system.h new file mode 100644 index 0000000000..fb867dc5f3 --- /dev/null +++ b/third_party/pipewire/spa/support/system.h @@ -0,0 +1,152 @@ +/* Simple Plugin API + * + * Copyright © 2019 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 SPA_SYSTEM_H +#define SPA_SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct itimerspec; + +#include <time.h> +#include <sys/types.h> + +#include <spa/utils/defs.h> +#include <spa/utils/hook.h> + +/** + * a collection of core system functions + */ +#define SPA_TYPE_INTERFACE_System SPA_TYPE_INFO_INTERFACE_BASE "System" +#define SPA_TYPE_INTERFACE_DataSystem SPA_TYPE_INFO_INTERFACE_BASE "DataSystem" + +#define SPA_VERSION_SYSTEM 0 +struct spa_system { struct spa_interface iface; }; + +/* IO events */ +#define SPA_IO_IN (1 << 0) +#define SPA_IO_OUT (1 << 2) +#define SPA_IO_ERR (1 << 3) +#define SPA_IO_HUP (1 << 4) + +/* flags */ +#define SPA_FD_CLOEXEC (1<<0) +#define SPA_FD_NONBLOCK (1<<1) +#define SPA_FD_EVENT_SEMAPHORE (1<<2) +#define SPA_FD_TIMER_ABSTIME (1<<3) +#define SPA_FD_TIMER_CANCEL_ON_SET (1<<4) + +struct spa_poll_event { + uint32_t events; + void *data; +}; + +struct spa_system_methods { +#define SPA_VERSION_SYSTEM_METHODS 0 + uint32_t version; + + /* read/write/ioctl */ + ssize_t (*read) (void *object, int fd, void *buf, size_t count); + ssize_t (*write) (void *object, int fd, const void *buf, size_t count); + int (*ioctl) (void *object, int fd, unsigned long request, ...); + int (*close) (void *object, int fd); + + /* clock */ + int (*clock_gettime) (void *object, + int clockid, struct timespec *value); + int (*clock_getres) (void *object, + int clockid, struct timespec *res); + + /* poll */ + int (*pollfd_create) (void *object, int flags); + int (*pollfd_add) (void *object, int pfd, int fd, uint32_t events, void *data); + int (*pollfd_mod) (void *object, int pfd, int fd, uint32_t events, void *data); + int (*pollfd_del) (void *object, int pfd, int fd); + int (*pollfd_wait) (void *object, int pfd, + struct spa_poll_event *ev, int n_ev, int timeout); + + /* timers */ + int (*timerfd_create) (void *object, int clockid, int flags); + int (*timerfd_settime) (void *object, + int fd, int flags, + const struct itimerspec *new_value, + struct itimerspec *old_value); + int (*timerfd_gettime) (void *object, + int fd, struct itimerspec *curr_value); + int (*timerfd_read) (void *object, int fd, uint64_t *expirations); + + /* events */ + int (*eventfd_create) (void *object, int flags); + int (*eventfd_write) (void *object, int fd, uint64_t count); + int (*eventfd_read) (void *object, int fd, uint64_t *count); + + /* signals */ + int (*signalfd_create) (void *object, int signal, int flags); + int (*signalfd_read) (void *object, int fd, int *signal); +}; + +#define spa_system_method_r(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + struct spa_system *_o = o; \ + spa_interface_call_res(&_o->iface, \ + struct spa_system_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + + +#define spa_system_read(s,...) spa_system_method_r(s,read,0,__VA_ARGS__) +#define spa_system_write(s,...) spa_system_method_r(s,write,0,__VA_ARGS__) +#define spa_system_ioctl(s,...) spa_system_method_r(s,ioctl,0,__VA_ARGS__) +#define spa_system_close(s,...) spa_system_method_r(s,close,0,__VA_ARGS__) + +#define spa_system_clock_gettime(s,...) spa_system_method_r(s,clock_gettime,0,__VA_ARGS__) +#define spa_system_clock_getres(s,...) spa_system_method_r(s,clock_getres,0,__VA_ARGS__) + +#define spa_system_pollfd_create(s,...) spa_system_method_r(s,pollfd_create,0,__VA_ARGS__) +#define spa_system_pollfd_add(s,...) spa_system_method_r(s,pollfd_add,0,__VA_ARGS__) +#define spa_system_pollfd_mod(s,...) spa_system_method_r(s,pollfd_mod,0,__VA_ARGS__) +#define spa_system_pollfd_del(s,...) spa_system_method_r(s,pollfd_del,0,__VA_ARGS__) +#define spa_system_pollfd_wait(s,...) spa_system_method_r(s,pollfd_wait,0,__VA_ARGS__) + +#define spa_system_timerfd_create(s,...) spa_system_method_r(s,timerfd_create,0,__VA_ARGS__) +#define spa_system_timerfd_settime(s,...) spa_system_method_r(s,timerfd_settime,0,__VA_ARGS__) +#define spa_system_timerfd_gettime(s,...) spa_system_method_r(s,timerfd_gettime,0,__VA_ARGS__) +#define spa_system_timerfd_read(s,...) spa_system_method_r(s,timerfd_read,0,__VA_ARGS__) + +#define spa_system_eventfd_create(s,...) spa_system_method_r(s,eventfd_create,0,__VA_ARGS__) +#define spa_system_eventfd_write(s,...) spa_system_method_r(s,eventfd_write,0,__VA_ARGS__) +#define spa_system_eventfd_read(s,...) spa_system_method_r(s,eventfd_read,0,__VA_ARGS__) + +#define spa_system_signalfd_create(s,...) spa_system_method_r(s,signalfd_create,0,__VA_ARGS__) +#define spa_system_signalfd_read(s,...) spa_system_method_r(s,signalfd_read,0,__VA_ARGS__) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_SYSTEM_H */ |