diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 45c96beb2808..964e24c7a0f0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -22,6 +22,7 @@ /drivers/alsamidi/ @godotengine/audio /drivers/coreaudio/ @godotengine/audio /drivers/coremidi/ @godotengine/audio +/drivers/pipewire/ @godotengine/audio /drivers/pulseaudio/ @godotengine/audio /drivers/wasapi/ @godotengine/audio /drivers/winmidi/ @godotengine/audio diff --git a/drivers/SCsub b/drivers/SCsub index a1eb8510500c..321f64abea90 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -14,6 +14,7 @@ SConscript("windows/SCsub") # Sounds drivers SConscript("alsa/SCsub") +SConscript("pipewire/SCsub") SConscript("pulseaudio/SCsub") if env["platform"] == "windows": SConscript("wasapi/SCsub") diff --git a/drivers/pipewire/SCsub b/drivers/pipewire/SCsub new file mode 100644 index 000000000000..7af82085759c --- /dev/null +++ b/drivers/pipewire/SCsub @@ -0,0 +1,11 @@ +#!/usr/bin/env python +from misc.utility.scons_hints import * + +Import("env") + +if "pipewire" in env and env["pipewire"]: + if env["use_sowrap"]: + env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers/pipewire"]) + env.add_source_files(env.drivers_sources, "pipewire-so_wrap.c") + +env.add_source_files(env.drivers_sources, "*.cpp") diff --git a/drivers/pipewire/audio_driver_pipewire.cpp b/drivers/pipewire/audio_driver_pipewire.cpp new file mode 100644 index 000000000000..47ba69122a89 --- /dev/null +++ b/drivers/pipewire/audio_driver_pipewire.cpp @@ -0,0 +1,635 @@ +/**************************************************************************/ +/* audio_driver_pipewire.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 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. */ +/**************************************************************************/ + +#include "audio_driver_pipewire.h" + +#ifdef PIPEWIRE_ENABLED + +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/io/json.h" +#include "core/version.h" + +GODOT_GCC_WARNING_PUSH +GODOT_GCC_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_CLANG_WARNING_PUSH +GODOT_CLANG_WARNING_IGNORE("-Wmissing-field-initializers") + +#include +#include +#include +#include + +const struct pw_core_events AudioDriverPipeWire::core_events = { + .version = PW_VERSION_CORE_EVENTS, + .info = nullptr, + .done = on_core_done, + .ping = nullptr, + .error = nullptr, + .remove_id = nullptr, + .bound_id = nullptr, + .add_mem = nullptr, + .remove_mem = nullptr, + .bound_props = nullptr, +}; + +const struct pw_registry_events AudioDriverPipeWire::registry_events = { + .version = PW_VERSION_REGISTRY_EVENTS, + .global = on_registry_event_global, + .global_remove = on_registry_event_global_remove, +}; + +const struct pw_node_events AudioDriverPipeWire::node_events = { + .version = PW_VERSION_NODE_EVENTS, + .info = on_node_info, + .param = nullptr, +}; + +const struct pw_metadata_events AudioDriverPipeWire::metadata_events = { + .version = PW_VERSION_METADATA_EVENTS, + .property = on_metadata_property, +}; + +const struct pw_stream_events AudioDriverPipeWire::output_stream_events = { + .version = PW_VERSION_STREAM_EVENTS, + .destroy = on_output_stream_destroy, + .state_changed = nullptr, + .control_info = nullptr, + .io_changed = nullptr, + .param_changed = nullptr, + .add_buffer = nullptr, + .remove_buffer = nullptr, + .process = on_output_stream_process, + .drained = nullptr, + .command = nullptr, + .trigger_done = nullptr, +}; + +const struct pw_stream_events AudioDriverPipeWire::input_stream_events = { + .version = PW_VERSION_STREAM_EVENTS, + .destroy = on_input_stream_destroy, + .state_changed = nullptr, + .control_info = nullptr, + .io_changed = nullptr, + .param_changed = nullptr, + .add_buffer = nullptr, + .remove_buffer = nullptr, + .process = on_input_stream_process, + .drained = nullptr, + .command = nullptr, + .trigger_done = nullptr, +}; + +void AudioDriverPipeWire::on_core_done(void *data, uint32_t id, int seq) { + AudioDriverPipeWire *ad = static_cast(data); + + if (id == ad->pending_id && seq == ad->pending_seq) { + pw_thread_loop_signal(ad->loop, false); + } +} + +void AudioDriverPipeWire::on_registry_event_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props) { + AudioDriverPipeWire *ad = static_cast(data); + + if (spa_streq(type, PW_TYPE_INTERFACE_Metadata)) { + const char *metadata_name = spa_dict_lookup(props, PW_KEY_METADATA_NAME); + if (spa_streq(metadata_name, "default")) { + ad->metadata = (struct pw_metadata *)pw_registry_bind(ad->registry, id, type, version, 0); + pw_metadata_add_listener(ad->metadata, &ad->metadata_listener, &metadata_events, ad); + ad->sync_wait(); + return; + } + } + + if (strcmp(type, PW_TYPE_INTERFACE_Node) != 0) { + return; + } + + const char *media_class = spa_dict_lookup(props, SPA_KEY_MEDIA_CLASS); + if (media_class == nullptr) { + return; + } + if (strcmp(media_class, "Audio/Sink") && strcmp(media_class, "Audio/Source")) { + return; + } + + const char *node_name = spa_dict_lookup(props, PW_KEY_NODE_NAME); + + struct pw_proxy *proxy = (struct pw_proxy *)pw_registry_bind(ad->registry, id, type, version, 0); + struct spa_hook *listener = (spa_hook *)malloc(sizeof(spa_hook)); + pw_node_add_listener((pw_node *)proxy, listener, &node_events, ad); + + struct PipeWireNode node = { + .id = id, + .proxy = proxy, + .listener = listener, + .media_class = media_class, + .node_name = node_name, + }; + ad->pw_nodes.push_back(node); + + ad->sync_wait(); +} + +void AudioDriverPipeWire::on_registry_event_global_remove(void *data, uint32_t id) { + AudioDriverPipeWire *ad = static_cast(data); + + for (int i = 0; i < ad->pw_nodes.size(); i++) { + const struct PipeWireNode &node = ad->pw_nodes[i]; + if (node.id == id) { + if (node.media_class == "Audio/Sink" && ad->get_output_device() == node.node_name) { + ad->set_output_device("Default"); + } else if (node.media_class == "Audio/Source" && ad->get_input_device() == node.node_name) { + ad->set_input_device("Default"); + } + if (node.proxy) { + pw_proxy_destroy(node.proxy); + } + if (node.listener) { + spa_hook_remove(node.listener); + } + ad->pw_nodes.remove_at(i); + return; + } + } +} + +int AudioDriverPipeWire::on_metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { + AudioDriverPipeWire *ad = static_cast(data); + + if (spa_streq(key, "default.audio.sink") || spa_streq(key, "default.audio.source")) { + JSON json; + ERR_FAIL_COND_V(json.parse(value) != OK, 0); + Dictionary dict = json.get_data(); + ERR_FAIL_COND_V(!dict.has("name"), 0); + if (spa_streq(key, "default.audio.sink")) { + ad->default_output_device = dict["name"]; + if (ad->output_stream && ad->get_output_device() == "Default") { + ad->set_output_device("Default"); + } + } else if (spa_streq(key, "default.audio.source")) { + ad->default_input_device = dict["name"]; + if (ad->input_stream && ad->get_input_device() == "Default") { + ad->set_input_device("Default"); + } + } + } + return 0; +} + +void AudioDriverPipeWire::on_node_info(void *data, const struct pw_node_info *info) { + AudioDriverPipeWire *ad = static_cast(data); + + if (info == nullptr || !(info->change_mask & PW_NODE_CHANGE_MASK_PARAMS)) { + return; + } + + for (int i = 0; i < ad->pw_nodes.size(); i++) { + PipeWireNode &node = ad->pw_nodes.ptrw()[i]; + if (node.id != info->id) { + continue; + } + if (node.media_class == "Audio/Sink") { + node.channels = info->n_input_ports; + } else if (node.media_class == "Audio/Source") { + node.channels = info->n_output_ports; + } + } +} + +void AudioDriverPipeWire::on_output_stream_destroy(void *data) { + AudioDriverPipeWire *ad = static_cast(data); + ad->output_stream = nullptr; +} + +void AudioDriverPipeWire::on_output_stream_process(void *data) { + struct pw_buffer *b; + struct spa_data *dst_data; + AudioDriverPipeWire *ad = static_cast(data); + + ad->start_counting_ticks(); + + ERR_FAIL_NULL_MSG((b = pw_stream_dequeue_buffer(ad->output_stream)), "Out of buffer."); + dst_data = &b->buffer->datas[0]; // codespell:ignore datas + + uint32_t stride = sizeof(int16_t) * ad->output_channels; + uint32_t n_frames = dst_data->maxsize / stride; + + if (b->requested) { + n_frames = SPA_MIN(b->requested, n_frames); + } + + if (ad->output_buffer.size() != dst_data->maxsize) { + ad->output_buffer.resize(dst_data->maxsize); + } + ad->audio_server_process(n_frames, ad->output_buffer.ptrw()); + + int16_t *dst = (int16_t *)dst_data->data; + for (uint32_t i = 0; i < n_frames * ad->output_channels; i++) { + *dst++ = ad->output_buffer[i] >> 16; + } + + dst_data->chunk->offset = 0; + dst_data->chunk->stride = stride; + dst_data->chunk->size = n_frames * stride; + + pw_stream_queue_buffer(ad->output_stream, b); + + ad->stop_counting_ticks(); +} + +void AudioDriverPipeWire::on_input_stream_destroy(void *data) { + AudioDriverPipeWire *ad = static_cast(data); + ad->input_stream = nullptr; +} + +void AudioDriverPipeWire::on_input_stream_process(void *data) { + struct pw_buffer *b; + struct spa_data *src_data; + AudioDriverPipeWire *ad = static_cast(data); + + ERR_FAIL_NULL_MSG((b = pw_stream_dequeue_buffer(ad->input_stream)), "Out of buffer."); + src_data = &b->buffer->datas[0]; // codespell:ignore datas + + uint32_t n_samples = src_data->chunk->size / sizeof(int16_t); + int16_t *src = (int16_t *)src_data->data; + + if (ad->input_buffer.size() != src_data->maxsize) { + ad->input_buffer.resize(src_data->maxsize); + ad->input_position = 0; + ad->input_size = 0; + } + + for (uint32_t i = 0; i < n_samples; i++) { + int32_t sample = int32_t(*src++) << 16; + ad->input_buffer_write(sample); + if (ad->input_channels == 1) { + ad->input_buffer_write(sample); + } + } + + pw_stream_queue_buffer(ad->input_stream, b); +} + +void AudioDriverPipeWire::sync_wait() { + ERR_FAIL_NULL(loop); + pending_id = PW_ID_CORE; + pending_seq = pw_core_sync(core, pending_id, pending_seq); + if (!pw_thread_loop_in_thread(loop)) { + pw_thread_loop_wait(loop); + } +} + +const AudioDriverPipeWire::PipeWireNode *AudioDriverPipeWire::get_pw_node(const String &p_name) const { + for (int i = 0; i < pw_nodes.size(); i++) { + const PipeWireNode *node = &pw_nodes.ptr()[i]; + if (node->node_name == p_name) { + return node; + } + } + return nullptr; +} + +void AudioDriverPipeWire::init_output_stream() { + struct pw_properties *props = pw_properties_new( + PW_KEY_MEDIA_TYPE, "Audio", + PW_KEY_MEDIA_CATEGORY, "Playback", + PW_KEY_MEDIA_ROLE, "Music", + NULL); + output_stream = pw_stream_new(core, "Sound", props); + pw_stream_add_listener(output_stream, &output_stream_listener, &output_stream_events, this); + set_output_device("Default"); +} + +void AudioDriverPipeWire::init_input_stream() { + struct pw_properties *props = pw_properties_new( + PW_KEY_MEDIA_TYPE, "Audio", + PW_KEY_MEDIA_CATEGORY, "Capture", + PW_KEY_MEDIA_ROLE, "Music", + NULL); + input_stream = pw_stream_new(core, "Record", props); + pw_stream_add_listener(input_stream, &input_stream_listener, &input_stream_events, this); + set_input_device("Default"); +} + +Error AudioDriverPipeWire::init() { +#ifdef SOWRAP_ENABLED +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif // DEBUG_ENABLED + if (initialize_pipewire(dylibloader_verbose)) { + return ERR_CANT_OPEN; + } + + if (pw_check_library_version_dylibloader_wrapper_pipewire) { + if (!pw_check_library_version(PW_MAJOR, PW_MINOR, PW_MICRO)) { + print_verbose("Unsupported PipeWire library version!"); + return ERR_CANT_OPEN; + } + } else { + print_verbose("Unable to check PipeWire library version!"); + return ERR_CANT_OPEN; + } +#endif // SOWRAP_ENABLED + + mix_rate = _get_configured_mix_rate(); + + pw_init(nullptr, nullptr); + loop = pw_thread_loop_new("", nullptr); + ERR_FAIL_NULL_V(loop, ERR_CANT_OPEN); + + context = pw_context_new(pw_thread_loop_get_loop(loop), nullptr, 0); + ERR_FAIL_NULL_V(context, ERR_CANT_OPEN); + + String context_name; + if (Engine::get_singleton()->is_editor_hint()) { + context_name = GODOT_VERSION_NAME " Editor"; + } else { + context_name = GLOBAL_GET("application/config/name"); + if (context_name.is_empty()) { + context_name = GODOT_VERSION_NAME " Project"; + } + } + pw_properties *props = pw_properties_new(PW_KEY_APP_NAME, context_name.utf8().ptr(), NULL); + ERR_FAIL_NULL_V(props, ERR_CANT_OPEN); + + core = pw_context_connect(context, props, 0); + if (core == nullptr) { + print_verbose("PipeWire: Failed to connect to PipeWire instance."); + return ERR_CANT_OPEN; + } + pw_core_add_listener(core, &core_listener, &core_events, this); + + registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0); + ERR_FAIL_NULL_V(registry, ERR_CANT_OPEN); + pw_registry_add_listener(registry, ®istry_listener, ®istry_events, this); + + ERR_FAIL_COND_V(pw_thread_loop_start(loop) < 0, ERR_CANT_OPEN); + + pw_thread_loop_lock(loop); + sync_wait(); + init_output_stream(); + init_input_stream(); + pw_thread_loop_unlock(loop); + + return OK; +} + +void AudioDriverPipeWire::start() { + ERR_FAIL_NULL(output_stream); + lock(); + pw_stream_flags flags = pw_stream_flags(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS); + const struct spa_pod *param[1]; + uint8_t buffer[1024]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + uint32_t position[] = { + SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, + SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR + }; + param[0] = (spa_pod *)spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16), + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(mix_rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(output_channels), + SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, output_channels, position)); + pw_stream_connect(output_stream, PW_DIRECTION_OUTPUT, PW_ID_ANY, flags, param, 1); + unlock(); +} + +int AudioDriverPipeWire::get_mix_rate() const { + return mix_rate; +} + +AudioDriver::SpeakerMode AudioDriverPipeWire::get_speaker_mode() const { + return get_speaker_mode_by_total_channels(output_channels); +} + +void AudioDriverPipeWire::lock() { + ERR_FAIL_NULL(loop); + pw_thread_loop_lock(loop); +} + +void AudioDriverPipeWire::unlock() { + ERR_FAIL_NULL(loop); + pw_thread_loop_unlock(loop); +} + +void AudioDriverPipeWire::finish() { + if (loop) { + pw_thread_loop_lock(loop); + } + if (metadata) { + pw_proxy_destroy((struct pw_proxy *)metadata); + spa_hook_remove(&metadata_listener); + metadata = nullptr; + } + if (input_stream) { + pw_stream_disconnect(input_stream); + spa_hook_remove(&input_stream_listener); + input_stream = nullptr; + } + if (output_stream) { + pw_stream_disconnect(output_stream); + spa_hook_remove(&output_stream_listener); + output_stream = nullptr; + } + if (registry) { + pw_proxy_destroy((pw_proxy *)registry); + spa_hook_remove(®istry_listener); + registry = nullptr; + } + if (core) { + pw_core_disconnect(core); + spa_hook_remove(&core_listener); + core = nullptr; + } + if (context) { + pw_context_destroy(context); + context = nullptr; + } + if (loop) { + pw_thread_loop_unlock(loop); + pw_thread_loop_destroy(loop); + loop = nullptr; + pw_deinit(); + } +} + +PackedStringArray AudioDriverPipeWire::get_output_device_list() { + PackedStringArray devices; + lock(); + devices.push_back("Default"); + for (const PipeWireNode &node : pw_nodes) { + if (node.media_class == "Audio/Sink") { + devices.push_back(node.node_name); + } + } + unlock(); + return devices; +} + +String AudioDriverPipeWire::get_output_device() { + const char *device = "Default"; + ERR_FAIL_NULL_V(output_stream, device); + lock(); + const struct pw_properties *props = pw_stream_get_properties(output_stream); + const char *target_object = pw_properties_get(props, PW_KEY_TARGET_OBJECT); + if (target_object) { + device = target_object; + } + unlock(); + return device; +} + +void AudioDriverPipeWire::set_output_device(const String &p_name) { + const PipeWireNode *node = nullptr; + const char *target_object = nullptr; + ERR_FAIL_NULL(output_stream); + lock(); + if (p_name == "Default" || !get_output_device_list().has(p_name)) { + node = get_pw_node(default_output_device); + } else { + node = get_pw_node(p_name); + } + if (node) { + if (p_name == node->node_name) { + target_object = node->node_name.utf8().ptr(); + } + output_channels = SPA_CLAMP((int)node->channels, 2, 8); + if (output_channels % 2) { + output_channels += 1; + } + } else { + ERR_PRINT("PipeWire: Failed to get default audio sink."); + output_channels = 2; + } + struct spa_dict_item items[1]; + items[0] = SPA_DICT_ITEM_INIT(PW_KEY_TARGET_OBJECT, target_object); + spa_dict dict = SPA_DICT_INIT(items, 1); + pw_stream_update_properties(output_stream, &dict); + if (pw_stream_get_state(output_stream, nullptr) == PW_STREAM_STATE_STREAMING) { + pw_stream_disconnect(output_stream); + start(); + } + unlock(); +} + +Error AudioDriverPipeWire::input_start() { + ERR_FAIL_NULL_V(input_stream, ERR_CANT_OPEN); + lock(); + pw_stream_flags flags = pw_stream_flags(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS); + const struct spa_pod *param[1]; + uint8_t buffer[1024]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + uint32_t position[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR }; + param[0] = (spa_pod *)spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16), + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(mix_rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(input_channels), + SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, input_channels, position)); + pw_stream_connect(input_stream, PW_DIRECTION_INPUT, PW_ID_ANY, flags, param, 1); + unlock(); + return OK; +} + +Error AudioDriverPipeWire::input_stop() { + ERR_FAIL_NULL_V(input_stream, ERR_CANT_OPEN); + lock(); + pw_stream_disconnect(input_stream); + unlock(); + return OK; +} + +PackedStringArray AudioDriverPipeWire::get_input_device_list() { + PackedStringArray devices; + lock(); + devices.push_back("Default"); + for (const PipeWireNode &node : pw_nodes) { + if (node.media_class == "Audio/Source") { + devices.push_back(node.node_name); + } + } + unlock(); + return devices; +} + +String AudioDriverPipeWire::get_input_device() { + const char *device = "Default"; + ERR_FAIL_NULL_V(input_stream, device); + lock(); + const struct pw_properties *props = pw_stream_get_properties(input_stream); + const char *target_object = pw_properties_get(props, PW_KEY_TARGET_OBJECT); + if (target_object) { + device = target_object; + } + unlock(); + return device; +} + +void AudioDriverPipeWire::set_input_device(const String &p_name) { + const PipeWireNode *node = nullptr; + const char *target_object = nullptr; + ERR_FAIL_NULL(input_stream); + lock(); + if (p_name == "Default" || !get_input_device_list().has(p_name)) { + node = get_pw_node(default_input_device); + } else { + node = get_pw_node(p_name); + } + if (node) { + if (p_name == node->node_name) { + target_object = node->node_name.utf8().ptr(); + } + input_channels = (SPA_CLAMP((int)node->channels, 1, 2)); + } else { + ERR_PRINT("PipeWire: Failed to get default audio source."); + input_channels = 2; + } + struct spa_dict_item items[1]; + items[0] = SPA_DICT_ITEM_INIT(PW_KEY_TARGET_OBJECT, target_object); + spa_dict dict = SPA_DICT_INIT(items, 1); + pw_stream_update_properties(input_stream, &dict); + if (pw_stream_get_state(input_stream, nullptr) == PW_STREAM_STATE_STREAMING) { + pw_stream_disconnect(input_stream); + input_start(); + } + unlock(); +} + +#endif // PIPEWIRE_ENABLED diff --git a/drivers/pipewire/audio_driver_pipewire.h b/drivers/pipewire/audio_driver_pipewire.h new file mode 100644 index 000000000000..a8d53c45c1a2 --- /dev/null +++ b/drivers/pipewire/audio_driver_pipewire.h @@ -0,0 +1,137 @@ +/**************************************************************************/ +/* audio_driver_pipewire.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 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. */ +/**************************************************************************/ + +#pragma once + +#ifdef PIPEWIRE_ENABLED + +#include "servers/audio/audio_server.h" + +#ifdef SOWRAP_ENABLED +#include "drivers/pipewire/pipewire-so_wrap.h" // IWYU pragma: keep. For PipeWire transitive includes. +#else +#include +#endif +#include + +class AudioDriverPipeWire : public AudioDriver { + struct PipeWireNode { + uint32_t id = 0; + pw_proxy *proxy = nullptr; + spa_hook *listener = nullptr; + String media_class; + String node_name; + uint32_t channels = 0; + }; + + static const struct pw_core_events core_events; + static const struct pw_registry_events registry_events; + static const struct pw_node_events node_events; + static const struct pw_metadata_events metadata_events; + static const struct pw_stream_events output_stream_events; + static const struct pw_stream_events input_stream_events; + + pw_thread_loop *loop = nullptr; + pw_context *context = nullptr; + pw_core *core = nullptr; + pw_registry *registry = nullptr; + pw_metadata *metadata = nullptr; + pw_stream *output_stream = nullptr; + pw_stream *input_stream = nullptr; + + spa_hook core_listener = {}; + spa_hook registry_listener = {}; + spa_hook metadata_listener = {}; + spa_hook output_stream_listener = {}; + spa_hook input_stream_listener = {}; + + uint32_t pending_id = 0; + int pending_seq = 0; + + unsigned int mix_rate = 0; + + Vector pw_nodes; + + uint32_t output_channels = 0; + String default_output_device; + Vector output_buffer; + + uint32_t input_channels = 0; + String default_input_device; + + static void on_core_done(void *data, uint32_t id, int seq); + static void on_registry_event_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props); + static void on_registry_event_global_remove(void *data, uint32_t id); + static void on_node_info(void *data, const struct pw_node_info *info); + static int on_metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value); + + static void on_output_stream_destroy(void *data); + static void on_output_stream_process(void *data); + + static void on_input_stream_destroy(void *data); + static void on_input_stream_process(void *data); + + void sync_wait(); + + const PipeWireNode *get_pw_node(const String &p_name) const; + + void init_output_stream(); + void init_input_stream(); + +public: + virtual const char *get_name() const override { + return "PipeWire"; + } + + virtual Error init() override; + virtual void start() override; + virtual int get_mix_rate() const override; + virtual SpeakerMode get_speaker_mode() const override; + + virtual void lock() override; + virtual void unlock() override; + virtual void finish() override; + + virtual PackedStringArray get_output_device_list() override; + virtual String get_output_device() override; + virtual void set_output_device(const String &p_name) override; + + virtual Error input_start() override; + virtual Error input_stop() override; + + virtual PackedStringArray get_input_device_list() override; + virtual String get_input_device() override; + virtual void set_input_device(const String &p_name) override; + + AudioDriverPipeWire() {} + ~AudioDriverPipeWire() {} +}; + +#endif // PIPEWIRE_ENABLED diff --git a/drivers/pipewire/pipewire-so_wrap.c b/drivers/pipewire/pipewire-so_wrap.c new file mode 100644 index 000000000000..b61b8ba3a403 --- /dev/null +++ b/drivers/pipewire/pipewire-so_wrap.c @@ -0,0 +1,2960 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.7 on 2026-03-18 00:35:26 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h --sys-include thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h --include-dir ./thirdparty/linuxbsd_headers/pipewire/ --soname libpipewire-0.3.so.0 --omit-prefix spa_ --init-name pipewire --output-header ./drivers/pipewire/pipewire-so_wrap.h --output-implementation ./drivers/pipewire/pipewire-so_wrap.c +// +#include + +#define pw_properties_new pw_properties_new_dylibloader_orig_pipewire +#define pw_properties_new_dict pw_properties_new_dict_dylibloader_orig_pipewire +#define pw_properties_new_string pw_properties_new_string_dylibloader_orig_pipewire +#define pw_properties_copy pw_properties_copy_dylibloader_orig_pipewire +#define pw_properties_update_keys pw_properties_update_keys_dylibloader_orig_pipewire +#define pw_properties_update_ignore pw_properties_update_ignore_dylibloader_orig_pipewire +#define pw_properties_update pw_properties_update_dylibloader_orig_pipewire +#define pw_properties_update_string pw_properties_update_string_dylibloader_orig_pipewire +#define pw_properties_add pw_properties_add_dylibloader_orig_pipewire +#define pw_properties_add_keys pw_properties_add_keys_dylibloader_orig_pipewire +#define pw_properties_clear pw_properties_clear_dylibloader_orig_pipewire +#define pw_properties_free pw_properties_free_dylibloader_orig_pipewire +#define pw_properties_set pw_properties_set_dylibloader_orig_pipewire +#define pw_properties_setf pw_properties_setf_dylibloader_orig_pipewire +#define pw_properties_setva pw_properties_setva_dylibloader_orig_pipewire +#define pw_properties_get pw_properties_get_dylibloader_orig_pipewire +#define pw_properties_fetch_uint32 pw_properties_fetch_uint32_dylibloader_orig_pipewire +#define pw_properties_fetch_int32 pw_properties_fetch_int32_dylibloader_orig_pipewire +#define pw_properties_fetch_uint64 pw_properties_fetch_uint64_dylibloader_orig_pipewire +#define pw_properties_fetch_int64 pw_properties_fetch_int64_dylibloader_orig_pipewire +#define pw_properties_fetch_bool pw_properties_fetch_bool_dylibloader_orig_pipewire +#define pw_properties_iterate pw_properties_iterate_dylibloader_orig_pipewire +#define pw_properties_serialize_dict pw_properties_serialize_dict_dylibloader_orig_pipewire +#define pw_core_info_update pw_core_info_update_dylibloader_orig_pipewire +#define pw_core_info_merge pw_core_info_merge_dylibloader_orig_pipewire +#define pw_core_info_free pw_core_info_free_dylibloader_orig_pipewire +#define pw_context_connect pw_context_connect_dylibloader_orig_pipewire +#define pw_context_connect_fd pw_context_connect_fd_dylibloader_orig_pipewire +#define pw_context_connect_self pw_context_connect_self_dylibloader_orig_pipewire +#define pw_core_steal_fd pw_core_steal_fd_dylibloader_orig_pipewire +#define pw_core_set_paused pw_core_set_paused_dylibloader_orig_pipewire +#define pw_core_disconnect pw_core_disconnect_dylibloader_orig_pipewire +#define pw_core_get_user_data pw_core_get_user_data_dylibloader_orig_pipewire +#define pw_core_get_client pw_core_get_client_dylibloader_orig_pipewire +#define pw_core_get_context pw_core_get_context_dylibloader_orig_pipewire +#define pw_core_get_properties pw_core_get_properties_dylibloader_orig_pipewire +#define pw_core_update_properties pw_core_update_properties_dylibloader_orig_pipewire +#define pw_core_get_mempool pw_core_get_mempool_dylibloader_orig_pipewire +#define pw_core_find_proxy pw_core_find_proxy_dylibloader_orig_pipewire +#define pw_core_export pw_core_export_dylibloader_orig_pipewire +#define pw_loop_new pw_loop_new_dylibloader_orig_pipewire +#define pw_loop_destroy pw_loop_destroy_dylibloader_orig_pipewire +#define pw_context_new pw_context_new_dylibloader_orig_pipewire +#define pw_context_destroy pw_context_destroy_dylibloader_orig_pipewire +#define pw_context_get_user_data pw_context_get_user_data_dylibloader_orig_pipewire +#define pw_context_add_listener pw_context_add_listener_dylibloader_orig_pipewire +#define pw_context_get_properties pw_context_get_properties_dylibloader_orig_pipewire +#define pw_context_update_properties pw_context_update_properties_dylibloader_orig_pipewire +#define pw_context_get_conf_section pw_context_get_conf_section_dylibloader_orig_pipewire +#define pw_context_parse_conf_section pw_context_parse_conf_section_dylibloader_orig_pipewire +#define pw_context_conf_update_props pw_context_conf_update_props_dylibloader_orig_pipewire +#define pw_context_conf_section_for_each pw_context_conf_section_for_each_dylibloader_orig_pipewire +#define pw_context_conf_section_match_rules pw_context_conf_section_match_rules_dylibloader_orig_pipewire +#define pw_context_get_support pw_context_get_support_dylibloader_orig_pipewire +#define pw_context_get_main_loop pw_context_get_main_loop_dylibloader_orig_pipewire +#define pw_context_get_data_loop pw_context_get_data_loop_dylibloader_orig_pipewire +#define pw_context_get_work_queue pw_context_get_work_queue_dylibloader_orig_pipewire +#define pw_context_get_mempool pw_context_get_mempool_dylibloader_orig_pipewire +#define pw_context_for_each_global pw_context_for_each_global_dylibloader_orig_pipewire +#define pw_context_find_global pw_context_find_global_dylibloader_orig_pipewire +#define pw_context_add_spa_lib pw_context_add_spa_lib_dylibloader_orig_pipewire +#define pw_context_find_spa_lib pw_context_find_spa_lib_dylibloader_orig_pipewire +#define pw_context_load_spa_handle pw_context_load_spa_handle_dylibloader_orig_pipewire +#define pw_context_register_export_type pw_context_register_export_type_dylibloader_orig_pipewire +#define pw_context_find_export_type pw_context_find_export_type_dylibloader_orig_pipewire +#define pw_context_set_object pw_context_set_object_dylibloader_orig_pipewire +#define pw_context_get_object pw_context_get_object_dylibloader_orig_pipewire +#define pw_split_walk pw_split_walk_dylibloader_orig_pipewire +#define pw_split_strv pw_split_strv_dylibloader_orig_pipewire +#define pw_split_ip pw_split_ip_dylibloader_orig_pipewire +#define pw_strv_parse pw_strv_parse_dylibloader_orig_pipewire +#define pw_strv_find pw_strv_find_dylibloader_orig_pipewire +#define pw_strv_find_common pw_strv_find_common_dylibloader_orig_pipewire +#define pw_free_strv pw_free_strv_dylibloader_orig_pipewire +#define pw_strip pw_strip_dylibloader_orig_pipewire +#define pw_getrandom pw_getrandom_dylibloader_orig_pipewire +#define pw_random pw_random_dylibloader_orig_pipewire +#define pw_reallocarray pw_reallocarray_dylibloader_orig_pipewire +#define pw_protocol_new pw_protocol_new_dylibloader_orig_pipewire +#define pw_protocol_destroy pw_protocol_destroy_dylibloader_orig_pipewire +#define pw_protocol_get_context pw_protocol_get_context_dylibloader_orig_pipewire +#define pw_protocol_get_user_data pw_protocol_get_user_data_dylibloader_orig_pipewire +#define pw_protocol_get_implementation pw_protocol_get_implementation_dylibloader_orig_pipewire +#define pw_protocol_get_extension pw_protocol_get_extension_dylibloader_orig_pipewire +#define pw_protocol_add_listener pw_protocol_add_listener_dylibloader_orig_pipewire +#define pw_protocol_add_marshal pw_protocol_add_marshal_dylibloader_orig_pipewire +#define pw_protocol_get_marshal pw_protocol_get_marshal_dylibloader_orig_pipewire +#define pw_context_find_protocol pw_context_find_protocol_dylibloader_orig_pipewire +#define pw_proxy_new pw_proxy_new_dylibloader_orig_pipewire +#define pw_proxy_add_listener pw_proxy_add_listener_dylibloader_orig_pipewire +#define pw_proxy_add_object_listener pw_proxy_add_object_listener_dylibloader_orig_pipewire +#define pw_proxy_destroy pw_proxy_destroy_dylibloader_orig_pipewire +#define pw_proxy_ref pw_proxy_ref_dylibloader_orig_pipewire +#define pw_proxy_unref pw_proxy_unref_dylibloader_orig_pipewire +#define pw_proxy_get_user_data pw_proxy_get_user_data_dylibloader_orig_pipewire +#define pw_proxy_get_id pw_proxy_get_id_dylibloader_orig_pipewire +#define pw_proxy_get_type pw_proxy_get_type_dylibloader_orig_pipewire +#define pw_proxy_get_protocol pw_proxy_get_protocol_dylibloader_orig_pipewire +#define pw_proxy_sync pw_proxy_sync_dylibloader_orig_pipewire +#define pw_proxy_set_bound_id pw_proxy_set_bound_id_dylibloader_orig_pipewire +#define pw_proxy_get_bound_id pw_proxy_get_bound_id_dylibloader_orig_pipewire +#define pw_proxy_error pw_proxy_error_dylibloader_orig_pipewire +#define pw_proxy_errorf pw_proxy_errorf_dylibloader_orig_pipewire +#define pw_proxy_get_object_listeners pw_proxy_get_object_listeners_dylibloader_orig_pipewire +#define pw_proxy_get_marshal pw_proxy_get_marshal_dylibloader_orig_pipewire +#define pw_proxy_install_marshal pw_proxy_install_marshal_dylibloader_orig_pipewire +#define pw_client_info_update pw_client_info_update_dylibloader_orig_pipewire +#define pw_client_info_merge pw_client_info_merge_dylibloader_orig_pipewire +#define pw_client_info_free pw_client_info_free_dylibloader_orig_pipewire +#define pw_conf_load_conf_for_context pw_conf_load_conf_for_context_dylibloader_orig_pipewire +#define pw_conf_load_conf pw_conf_load_conf_dylibloader_orig_pipewire +#define pw_conf_load_state pw_conf_load_state_dylibloader_orig_pipewire +#define pw_conf_save_state pw_conf_save_state_dylibloader_orig_pipewire +#define pw_conf_section_update_props pw_conf_section_update_props_dylibloader_orig_pipewire +#define pw_conf_section_for_each pw_conf_section_for_each_dylibloader_orig_pipewire +#define pw_conf_match_rules pw_conf_match_rules_dylibloader_orig_pipewire +#define pw_conf_section_match_rules pw_conf_section_match_rules_dylibloader_orig_pipewire +#define pw_device_info_update pw_device_info_update_dylibloader_orig_pipewire +#define pw_device_info_merge pw_device_info_merge_dylibloader_orig_pipewire +#define pw_device_info_free pw_device_info_free_dylibloader_orig_pipewire +#define pw_mempool_new pw_mempool_new_dylibloader_orig_pipewire +#define pw_mempool_add_listener pw_mempool_add_listener_dylibloader_orig_pipewire +#define pw_mempool_clear pw_mempool_clear_dylibloader_orig_pipewire +#define pw_mempool_destroy pw_mempool_destroy_dylibloader_orig_pipewire +#define pw_mempool_alloc pw_mempool_alloc_dylibloader_orig_pipewire +#define pw_mempool_import_block pw_mempool_import_block_dylibloader_orig_pipewire +#define pw_mempool_import pw_mempool_import_dylibloader_orig_pipewire +#define pw_memblock_free pw_memblock_free_dylibloader_orig_pipewire +#define pw_mempool_remove_id pw_mempool_remove_id_dylibloader_orig_pipewire +#define pw_mempool_find_ptr pw_mempool_find_ptr_dylibloader_orig_pipewire +#define pw_mempool_find_id pw_mempool_find_id_dylibloader_orig_pipewire +#define pw_mempool_find_fd pw_mempool_find_fd_dylibloader_orig_pipewire +#define pw_memblock_map pw_memblock_map_dylibloader_orig_pipewire +#define pw_mempool_map_id pw_mempool_map_id_dylibloader_orig_pipewire +#define pw_mempool_import_map pw_mempool_import_map_dylibloader_orig_pipewire +#define pw_mempool_find_tag pw_mempool_find_tag_dylibloader_orig_pipewire +#define pw_memmap_free pw_memmap_free_dylibloader_orig_pipewire +#define pw_buffers_negotiate pw_buffers_negotiate_dylibloader_orig_pipewire +#define pw_buffers_clear pw_buffers_clear_dylibloader_orig_pipewire +#define pw_factory_info_update pw_factory_info_update_dylibloader_orig_pipewire +#define pw_factory_info_merge pw_factory_info_merge_dylibloader_orig_pipewire +#define pw_factory_info_free pw_factory_info_free_dylibloader_orig_pipewire +#define pw_log_set pw_log_set_dylibloader_orig_pipewire +#define pw_log_get pw_log_get_dylibloader_orig_pipewire +#define pw_log_set_level pw_log_set_level_dylibloader_orig_pipewire +#define pw_log_logt pw_log_logt_dylibloader_orig_pipewire +#define pw_log_logtv pw_log_logtv_dylibloader_orig_pipewire +#define pw_log_log pw_log_log_dylibloader_orig_pipewire +#define pw_log_logv pw_log_logv_dylibloader_orig_pipewire +#define pw_link_state_as_string pw_link_state_as_string_dylibloader_orig_pipewire +#define pw_link_info_update pw_link_info_update_dylibloader_orig_pipewire +#define pw_link_info_merge pw_link_info_merge_dylibloader_orig_pipewire +#define pw_link_info_free pw_link_info_free_dylibloader_orig_pipewire +#define pw_main_loop_new pw_main_loop_new_dylibloader_orig_pipewire +#define pw_main_loop_add_listener pw_main_loop_add_listener_dylibloader_orig_pipewire +#define pw_main_loop_get_loop pw_main_loop_get_loop_dylibloader_orig_pipewire +#define pw_main_loop_destroy pw_main_loop_destroy_dylibloader_orig_pipewire +#define pw_main_loop_run pw_main_loop_run_dylibloader_orig_pipewire +#define pw_main_loop_quit pw_main_loop_quit_dylibloader_orig_pipewire +#define pw_module_info_update pw_module_info_update_dylibloader_orig_pipewire +#define pw_module_info_merge pw_module_info_merge_dylibloader_orig_pipewire +#define pw_module_info_free pw_module_info_free_dylibloader_orig_pipewire +#define pw_node_state_as_string pw_node_state_as_string_dylibloader_orig_pipewire +#define pw_node_info_update pw_node_info_update_dylibloader_orig_pipewire +#define pw_node_info_merge pw_node_info_merge_dylibloader_orig_pipewire +#define pw_node_info_free pw_node_info_free_dylibloader_orig_pipewire +#define pw_direction_as_string pw_direction_as_string_dylibloader_orig_pipewire +#define pw_port_info_update pw_port_info_update_dylibloader_orig_pipewire +#define pw_port_info_merge pw_port_info_merge_dylibloader_orig_pipewire +#define pw_port_info_free pw_port_info_free_dylibloader_orig_pipewire +#define pw_stream_state_as_string pw_stream_state_as_string_dylibloader_orig_pipewire +#define pw_stream_new pw_stream_new_dylibloader_orig_pipewire +#define pw_stream_new_simple pw_stream_new_simple_dylibloader_orig_pipewire +#define pw_stream_destroy pw_stream_destroy_dylibloader_orig_pipewire +#define pw_stream_add_listener pw_stream_add_listener_dylibloader_orig_pipewire +#define pw_stream_get_state pw_stream_get_state_dylibloader_orig_pipewire +#define pw_stream_get_name pw_stream_get_name_dylibloader_orig_pipewire +#define pw_stream_get_core pw_stream_get_core_dylibloader_orig_pipewire +#define pw_stream_get_properties pw_stream_get_properties_dylibloader_orig_pipewire +#define pw_stream_update_properties pw_stream_update_properties_dylibloader_orig_pipewire +#define pw_stream_connect pw_stream_connect_dylibloader_orig_pipewire +#define pw_stream_get_node_id pw_stream_get_node_id_dylibloader_orig_pipewire +#define pw_stream_disconnect pw_stream_disconnect_dylibloader_orig_pipewire +#define pw_stream_set_error pw_stream_set_error_dylibloader_orig_pipewire +#define pw_stream_update_params pw_stream_update_params_dylibloader_orig_pipewire +#define pw_stream_set_param pw_stream_set_param_dylibloader_orig_pipewire +#define pw_stream_get_control pw_stream_get_control_dylibloader_orig_pipewire +#define pw_stream_set_control pw_stream_set_control_dylibloader_orig_pipewire +#define pw_stream_get_time_n pw_stream_get_time_n_dylibloader_orig_pipewire +#define pw_stream_get_time pw_stream_get_time_dylibloader_orig_pipewire +#define pw_stream_dequeue_buffer pw_stream_dequeue_buffer_dylibloader_orig_pipewire +#define pw_stream_queue_buffer pw_stream_queue_buffer_dylibloader_orig_pipewire +#define pw_stream_set_active pw_stream_set_active_dylibloader_orig_pipewire +#define pw_stream_flush pw_stream_flush_dylibloader_orig_pipewire +#define pw_stream_is_driving pw_stream_is_driving_dylibloader_orig_pipewire +#define pw_stream_trigger_process pw_stream_trigger_process_dylibloader_orig_pipewire +#define pw_filter_state_as_string pw_filter_state_as_string_dylibloader_orig_pipewire +#define pw_filter_new pw_filter_new_dylibloader_orig_pipewire +#define pw_filter_new_simple pw_filter_new_simple_dylibloader_orig_pipewire +#define pw_filter_destroy pw_filter_destroy_dylibloader_orig_pipewire +#define pw_filter_add_listener pw_filter_add_listener_dylibloader_orig_pipewire +#define pw_filter_get_state pw_filter_get_state_dylibloader_orig_pipewire +#define pw_filter_get_name pw_filter_get_name_dylibloader_orig_pipewire +#define pw_filter_get_core pw_filter_get_core_dylibloader_orig_pipewire +#define pw_filter_connect pw_filter_connect_dylibloader_orig_pipewire +#define pw_filter_get_node_id pw_filter_get_node_id_dylibloader_orig_pipewire +#define pw_filter_disconnect pw_filter_disconnect_dylibloader_orig_pipewire +#define pw_filter_add_port pw_filter_add_port_dylibloader_orig_pipewire +#define pw_filter_remove_port pw_filter_remove_port_dylibloader_orig_pipewire +#define pw_filter_get_properties pw_filter_get_properties_dylibloader_orig_pipewire +#define pw_filter_update_properties pw_filter_update_properties_dylibloader_orig_pipewire +#define pw_filter_set_error pw_filter_set_error_dylibloader_orig_pipewire +#define pw_filter_update_params pw_filter_update_params_dylibloader_orig_pipewire +#define pw_filter_get_time pw_filter_get_time_dylibloader_orig_pipewire +#define pw_filter_dequeue_buffer pw_filter_dequeue_buffer_dylibloader_orig_pipewire +#define pw_filter_queue_buffer pw_filter_queue_buffer_dylibloader_orig_pipewire +#define pw_filter_get_dsp_buffer pw_filter_get_dsp_buffer_dylibloader_orig_pipewire +#define pw_filter_set_active pw_filter_set_active_dylibloader_orig_pipewire +#define pw_filter_flush pw_filter_flush_dylibloader_orig_pipewire +#define pw_filter_is_driving pw_filter_is_driving_dylibloader_orig_pipewire +#define pw_filter_trigger_process pw_filter_trigger_process_dylibloader_orig_pipewire +#define pw_thread_loop_new pw_thread_loop_new_dylibloader_orig_pipewire +#define pw_thread_loop_new_full pw_thread_loop_new_full_dylibloader_orig_pipewire +#define pw_thread_loop_destroy pw_thread_loop_destroy_dylibloader_orig_pipewire +#define pw_thread_loop_add_listener pw_thread_loop_add_listener_dylibloader_orig_pipewire +#define pw_thread_loop_get_loop pw_thread_loop_get_loop_dylibloader_orig_pipewire +#define pw_thread_loop_start pw_thread_loop_start_dylibloader_orig_pipewire +#define pw_thread_loop_stop pw_thread_loop_stop_dylibloader_orig_pipewire +#define pw_thread_loop_lock pw_thread_loop_lock_dylibloader_orig_pipewire +#define pw_thread_loop_unlock pw_thread_loop_unlock_dylibloader_orig_pipewire +#define pw_thread_loop_wait pw_thread_loop_wait_dylibloader_orig_pipewire +#define pw_thread_loop_timed_wait pw_thread_loop_timed_wait_dylibloader_orig_pipewire +#define pw_thread_loop_get_time pw_thread_loop_get_time_dylibloader_orig_pipewire +#define pw_thread_loop_timed_wait_full pw_thread_loop_timed_wait_full_dylibloader_orig_pipewire +#define pw_thread_loop_signal pw_thread_loop_signal_dylibloader_orig_pipewire +#define pw_thread_loop_accept pw_thread_loop_accept_dylibloader_orig_pipewire +#define pw_thread_loop_in_thread pw_thread_loop_in_thread_dylibloader_orig_pipewire +#define pw_data_loop_new pw_data_loop_new_dylibloader_orig_pipewire +#define pw_data_loop_add_listener pw_data_loop_add_listener_dylibloader_orig_pipewire +#define pw_data_loop_wait pw_data_loop_wait_dylibloader_orig_pipewire +#define pw_data_loop_exit pw_data_loop_exit_dylibloader_orig_pipewire +#define pw_data_loop_get_loop pw_data_loop_get_loop_dylibloader_orig_pipewire +#define pw_data_loop_destroy pw_data_loop_destroy_dylibloader_orig_pipewire +#define pw_data_loop_start pw_data_loop_start_dylibloader_orig_pipewire +#define pw_data_loop_stop pw_data_loop_stop_dylibloader_orig_pipewire +#define pw_data_loop_in_thread pw_data_loop_in_thread_dylibloader_orig_pipewire +#define pw_data_loop_get_thread pw_data_loop_get_thread_dylibloader_orig_pipewire +#define pw_data_loop_invoke pw_data_loop_invoke_dylibloader_orig_pipewire +#define pw_data_loop_set_thread_utils pw_data_loop_set_thread_utils_dylibloader_orig_pipewire +#define pw_type_info pw_type_info_dylibloader_orig_pipewire +#define pw_get_library_version pw_get_library_version_dylibloader_orig_pipewire +#define pw_check_library_version pw_check_library_version_dylibloader_orig_pipewire +#define pw_init pw_init_dylibloader_orig_pipewire +#define pw_deinit pw_deinit_dylibloader_orig_pipewire +#define pw_debug_is_category_enabled pw_debug_is_category_enabled_dylibloader_orig_pipewire +#define pw_get_application_name pw_get_application_name_dylibloader_orig_pipewire +#define pw_get_prgname pw_get_prgname_dylibloader_orig_pipewire +#define pw_get_user_name pw_get_user_name_dylibloader_orig_pipewire +#define pw_get_host_name pw_get_host_name_dylibloader_orig_pipewire +#define pw_get_client_name pw_get_client_name_dylibloader_orig_pipewire +#define pw_check_option pw_check_option_dylibloader_orig_pipewire +#define pw_direction_reverse pw_direction_reverse_dylibloader_orig_pipewire +#define pw_set_domain pw_set_domain_dylibloader_orig_pipewire +#define pw_get_domain pw_get_domain_dylibloader_orig_pipewire +#define pw_get_support pw_get_support_dylibloader_orig_pipewire +#define pw_load_spa_handle pw_load_spa_handle_dylibloader_orig_pipewire +#define pw_unload_spa_handle pw_unload_spa_handle_dylibloader_orig_pipewire +#include "thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h" // IWYU pragma: export. +#undef pw_properties_new +#undef pw_properties_new_dict +#undef pw_properties_new_string +#undef pw_properties_copy +#undef pw_properties_update_keys +#undef pw_properties_update_ignore +#undef pw_properties_update +#undef pw_properties_update_string +#undef pw_properties_add +#undef pw_properties_add_keys +#undef pw_properties_clear +#undef pw_properties_free +#undef pw_properties_set +#undef pw_properties_setf +#undef pw_properties_setva +#undef pw_properties_get +#undef pw_properties_fetch_uint32 +#undef pw_properties_fetch_int32 +#undef pw_properties_fetch_uint64 +#undef pw_properties_fetch_int64 +#undef pw_properties_fetch_bool +#undef pw_properties_iterate +#undef pw_properties_serialize_dict +#undef pw_core_info_update +#undef pw_core_info_merge +#undef pw_core_info_free +#undef pw_context_connect +#undef pw_context_connect_fd +#undef pw_context_connect_self +#undef pw_core_steal_fd +#undef pw_core_set_paused +#undef pw_core_disconnect +#undef pw_core_get_user_data +#undef pw_core_get_client +#undef pw_core_get_context +#undef pw_core_get_properties +#undef pw_core_update_properties +#undef pw_core_get_mempool +#undef pw_core_find_proxy +#undef pw_core_export +#undef pw_loop_new +#undef pw_loop_destroy +#undef pw_context_new +#undef pw_context_destroy +#undef pw_context_get_user_data +#undef pw_context_add_listener +#undef pw_context_get_properties +#undef pw_context_update_properties +#undef pw_context_get_conf_section +#undef pw_context_parse_conf_section +#undef pw_context_conf_update_props +#undef pw_context_conf_section_for_each +#undef pw_context_conf_section_match_rules +#undef pw_context_get_support +#undef pw_context_get_main_loop +#undef pw_context_get_data_loop +#undef pw_context_get_work_queue +#undef pw_context_get_mempool +#undef pw_context_for_each_global +#undef pw_context_find_global +#undef pw_context_add_spa_lib +#undef pw_context_find_spa_lib +#undef pw_context_load_spa_handle +#undef pw_context_register_export_type +#undef pw_context_find_export_type +#undef pw_context_set_object +#undef pw_context_get_object +#undef pw_split_walk +#undef pw_split_strv +#undef pw_split_ip +#undef pw_strv_parse +#undef pw_strv_find +#undef pw_strv_find_common +#undef pw_free_strv +#undef pw_strip +#undef pw_getrandom +#undef pw_random +#undef pw_reallocarray +#undef pw_protocol_new +#undef pw_protocol_destroy +#undef pw_protocol_get_context +#undef pw_protocol_get_user_data +#undef pw_protocol_get_implementation +#undef pw_protocol_get_extension +#undef pw_protocol_add_listener +#undef pw_protocol_add_marshal +#undef pw_protocol_get_marshal +#undef pw_context_find_protocol +#undef pw_proxy_new +#undef pw_proxy_add_listener +#undef pw_proxy_add_object_listener +#undef pw_proxy_destroy +#undef pw_proxy_ref +#undef pw_proxy_unref +#undef pw_proxy_get_user_data +#undef pw_proxy_get_id +#undef pw_proxy_get_type +#undef pw_proxy_get_protocol +#undef pw_proxy_sync +#undef pw_proxy_set_bound_id +#undef pw_proxy_get_bound_id +#undef pw_proxy_error +#undef pw_proxy_errorf +#undef pw_proxy_get_object_listeners +#undef pw_proxy_get_marshal +#undef pw_proxy_install_marshal +#undef pw_client_info_update +#undef pw_client_info_merge +#undef pw_client_info_free +#undef pw_conf_load_conf_for_context +#undef pw_conf_load_conf +#undef pw_conf_load_state +#undef pw_conf_save_state +#undef pw_conf_section_update_props +#undef pw_conf_section_for_each +#undef pw_conf_match_rules +#undef pw_conf_section_match_rules +#undef pw_device_info_update +#undef pw_device_info_merge +#undef pw_device_info_free +#undef pw_mempool_new +#undef pw_mempool_add_listener +#undef pw_mempool_clear +#undef pw_mempool_destroy +#undef pw_mempool_alloc +#undef pw_mempool_import_block +#undef pw_mempool_import +#undef pw_memblock_free +#undef pw_mempool_remove_id +#undef pw_mempool_find_ptr +#undef pw_mempool_find_id +#undef pw_mempool_find_fd +#undef pw_memblock_map +#undef pw_mempool_map_id +#undef pw_mempool_import_map +#undef pw_mempool_find_tag +#undef pw_memmap_free +#undef pw_buffers_negotiate +#undef pw_buffers_clear +#undef pw_factory_info_update +#undef pw_factory_info_merge +#undef pw_factory_info_free +#undef pw_log_set +#undef pw_log_get +#undef pw_log_set_level +#undef pw_log_logt +#undef pw_log_logtv +#undef pw_log_log +#undef pw_log_logv +#undef pw_link_state_as_string +#undef pw_link_info_update +#undef pw_link_info_merge +#undef pw_link_info_free +#undef pw_main_loop_new +#undef pw_main_loop_add_listener +#undef pw_main_loop_get_loop +#undef pw_main_loop_destroy +#undef pw_main_loop_run +#undef pw_main_loop_quit +#undef pw_module_info_update +#undef pw_module_info_merge +#undef pw_module_info_free +#undef pw_node_state_as_string +#undef pw_node_info_update +#undef pw_node_info_merge +#undef pw_node_info_free +#undef pw_direction_as_string +#undef pw_port_info_update +#undef pw_port_info_merge +#undef pw_port_info_free +#undef pw_stream_state_as_string +#undef pw_stream_new +#undef pw_stream_new_simple +#undef pw_stream_destroy +#undef pw_stream_add_listener +#undef pw_stream_get_state +#undef pw_stream_get_name +#undef pw_stream_get_core +#undef pw_stream_get_properties +#undef pw_stream_update_properties +#undef pw_stream_connect +#undef pw_stream_get_node_id +#undef pw_stream_disconnect +#undef pw_stream_set_error +#undef pw_stream_update_params +#undef pw_stream_set_param +#undef pw_stream_get_control +#undef pw_stream_set_control +#undef pw_stream_get_time_n +#undef pw_stream_get_time +#undef pw_stream_dequeue_buffer +#undef pw_stream_queue_buffer +#undef pw_stream_set_active +#undef pw_stream_flush +#undef pw_stream_is_driving +#undef pw_stream_trigger_process +#undef pw_filter_state_as_string +#undef pw_filter_new +#undef pw_filter_new_simple +#undef pw_filter_destroy +#undef pw_filter_add_listener +#undef pw_filter_get_state +#undef pw_filter_get_name +#undef pw_filter_get_core +#undef pw_filter_connect +#undef pw_filter_get_node_id +#undef pw_filter_disconnect +#undef pw_filter_add_port +#undef pw_filter_remove_port +#undef pw_filter_get_properties +#undef pw_filter_update_properties +#undef pw_filter_set_error +#undef pw_filter_update_params +#undef pw_filter_get_time +#undef pw_filter_dequeue_buffer +#undef pw_filter_queue_buffer +#undef pw_filter_get_dsp_buffer +#undef pw_filter_set_active +#undef pw_filter_flush +#undef pw_filter_is_driving +#undef pw_filter_trigger_process +#undef pw_thread_loop_new +#undef pw_thread_loop_new_full +#undef pw_thread_loop_destroy +#undef pw_thread_loop_add_listener +#undef pw_thread_loop_get_loop +#undef pw_thread_loop_start +#undef pw_thread_loop_stop +#undef pw_thread_loop_lock +#undef pw_thread_loop_unlock +#undef pw_thread_loop_wait +#undef pw_thread_loop_timed_wait +#undef pw_thread_loop_get_time +#undef pw_thread_loop_timed_wait_full +#undef pw_thread_loop_signal +#undef pw_thread_loop_accept +#undef pw_thread_loop_in_thread +#undef pw_data_loop_new +#undef pw_data_loop_add_listener +#undef pw_data_loop_wait +#undef pw_data_loop_exit +#undef pw_data_loop_get_loop +#undef pw_data_loop_destroy +#undef pw_data_loop_start +#undef pw_data_loop_stop +#undef pw_data_loop_in_thread +#undef pw_data_loop_get_thread +#undef pw_data_loop_invoke +#undef pw_data_loop_set_thread_utils +#undef pw_type_info +#undef pw_get_library_version +#undef pw_check_library_version +#undef pw_init +#undef pw_deinit +#undef pw_debug_is_category_enabled +#undef pw_get_application_name +#undef pw_get_prgname +#undef pw_get_user_name +#undef pw_get_host_name +#undef pw_get_client_name +#undef pw_check_option +#undef pw_direction_reverse +#undef pw_set_domain +#undef pw_get_domain +#undef pw_get_support +#undef pw_load_spa_handle +#undef pw_unload_spa_handle +#include +#include +struct pw_properties *(*pw_properties_new_dylibloader_wrapper_pipewire)(const char *, ...); +struct pw_properties *(*pw_properties_new_dict_dylibloader_wrapper_pipewire)(const struct spa_dict *); +struct pw_properties *(*pw_properties_new_string_dylibloader_wrapper_pipewire)(const char *); +struct pw_properties *(*pw_properties_copy_dylibloader_wrapper_pipewire)(const struct pw_properties *); +int (*pw_properties_update_keys_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *, const char * const []); +int (*pw_properties_update_ignore_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *, const char * const []); +int (*pw_properties_update_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *); +int (*pw_properties_update_string_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, size_t); +int (*pw_properties_add_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *); +int (*pw_properties_add_keys_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *, const char * const []); +void (*pw_properties_clear_dylibloader_wrapper_pipewire)(struct pw_properties *); +void (*pw_properties_free_dylibloader_wrapper_pipewire)(struct pw_properties *); +int (*pw_properties_set_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, const char *); +int (*pw_properties_setf_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, const char *, ...); +int (*pw_properties_setva_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, const char *, va_list); +const char *(*pw_properties_get_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *); +int (*pw_properties_fetch_uint32_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, uint32_t *); +int (*pw_properties_fetch_int32_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, int32_t *); +int (*pw_properties_fetch_uint64_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, uint64_t *); +int (*pw_properties_fetch_int64_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, int64_t *); +int (*pw_properties_fetch_bool_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, bool *); +const char *(*pw_properties_iterate_dylibloader_wrapper_pipewire)(const struct pw_properties *, void **); +int (*pw_properties_serialize_dict_dylibloader_wrapper_pipewire)(FILE *, const struct spa_dict *, uint32_t); +struct pw_core_info *(*pw_core_info_update_dylibloader_wrapper_pipewire)(struct pw_core_info *, const struct pw_core_info *); +struct pw_core_info *(*pw_core_info_merge_dylibloader_wrapper_pipewire)(struct pw_core_info *, const struct pw_core_info *, bool); +void (*pw_core_info_free_dylibloader_wrapper_pipewire)(struct pw_core_info *); +struct pw_core *(*pw_context_connect_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_properties *, size_t); +struct pw_core *(*pw_context_connect_fd_dylibloader_wrapper_pipewire)(struct pw_context *, int, struct pw_properties *, size_t); +struct pw_core *(*pw_context_connect_self_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_properties *, size_t); +int (*pw_core_steal_fd_dylibloader_wrapper_pipewire)(struct pw_core *); +int (*pw_core_set_paused_dylibloader_wrapper_pipewire)(struct pw_core *, bool); +int (*pw_core_disconnect_dylibloader_wrapper_pipewire)(struct pw_core *); +void *(*pw_core_get_user_data_dylibloader_wrapper_pipewire)(struct pw_core *); +struct pw_client *(*pw_core_get_client_dylibloader_wrapper_pipewire)(struct pw_core *); +struct pw_context *(*pw_core_get_context_dylibloader_wrapper_pipewire)(struct pw_core *); +const struct pw_properties *(*pw_core_get_properties_dylibloader_wrapper_pipewire)(struct pw_core *); +int (*pw_core_update_properties_dylibloader_wrapper_pipewire)(struct pw_core *, const struct spa_dict *); +struct pw_mempool *(*pw_core_get_mempool_dylibloader_wrapper_pipewire)(struct pw_core *); +struct pw_proxy *(*pw_core_find_proxy_dylibloader_wrapper_pipewire)(struct pw_core *, uint32_t); +struct pw_proxy *(*pw_core_export_dylibloader_wrapper_pipewire)(struct pw_core *, const char *, const struct spa_dict *, void *, size_t); +struct pw_loop *(*pw_loop_new_dylibloader_wrapper_pipewire)(const struct spa_dict *); +void (*pw_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_loop *); +struct pw_context *(*pw_context_new_dylibloader_wrapper_pipewire)(struct pw_loop *, struct pw_properties *, size_t); +void (*pw_context_destroy_dylibloader_wrapper_pipewire)(struct pw_context *); +void *(*pw_context_get_user_data_dylibloader_wrapper_pipewire)(struct pw_context *); +void (*pw_context_add_listener_dylibloader_wrapper_pipewire)(struct pw_context *, struct spa_hook *, const struct pw_context_events *, void *); +const struct pw_properties *(*pw_context_get_properties_dylibloader_wrapper_pipewire)(struct pw_context *); +int (*pw_context_update_properties_dylibloader_wrapper_pipewire)(struct pw_context *, const struct spa_dict *); +const char *(*pw_context_get_conf_section_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +int (*pw_context_parse_conf_section_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_properties *, const char *); +int (*pw_context_conf_update_props_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, struct pw_properties *); +int (*pw_context_conf_section_for_each_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, int (*)(void *data, const char *location, const char *section, const char *str, size_t len), void *); +int (*pw_context_conf_section_match_rules_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, const struct spa_dict *, int (*)(void *data, const char *location, const char *action, const char *str, size_t len), void *); +const struct spa_support *(*pw_context_get_support_dylibloader_wrapper_pipewire)(struct pw_context *, uint32_t *); +struct pw_loop *(*pw_context_get_main_loop_dylibloader_wrapper_pipewire)(struct pw_context *); +struct pw_data_loop *(*pw_context_get_data_loop_dylibloader_wrapper_pipewire)(struct pw_context *); +struct pw_work_queue *(*pw_context_get_work_queue_dylibloader_wrapper_pipewire)(struct pw_context *); +struct pw_mempool *(*pw_context_get_mempool_dylibloader_wrapper_pipewire)(struct pw_context *); +int (*pw_context_for_each_global_dylibloader_wrapper_pipewire)(struct pw_context *, int (*)(void *data, struct pw_global *global), void *); +struct pw_global *(*pw_context_find_global_dylibloader_wrapper_pipewire)(struct pw_context *, uint32_t); +int (*pw_context_add_spa_lib_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, const char *); +const char *(*pw_context_find_spa_lib_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +struct spa_handle *(*pw_context_load_spa_handle_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, const struct spa_dict *); +int (*pw_context_register_export_type_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_export_type *); +const struct pw_export_type *(*pw_context_find_export_type_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +int (*pw_context_set_object_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, void *); +void *(*pw_context_get_object_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +const char *(*pw_split_walk_dylibloader_wrapper_pipewire)(const char *, const char *, size_t *, const char **); +char **(*pw_split_strv_dylibloader_wrapper_pipewire)(const char *, const char *, int, int *); +int (*pw_split_ip_dylibloader_wrapper_pipewire)(char *, const char *, int, char *[]); +char **(*pw_strv_parse_dylibloader_wrapper_pipewire)(const char *, size_t, int, int *); +int (*pw_strv_find_dylibloader_wrapper_pipewire)(char **, const char *); +int (*pw_strv_find_common_dylibloader_wrapper_pipewire)(char **, char **); +void (*pw_free_strv_dylibloader_wrapper_pipewire)(char **); +char *(*pw_strip_dylibloader_wrapper_pipewire)(char *, const char *); +ssize_t (*pw_getrandom_dylibloader_wrapper_pipewire)(void *, size_t, unsigned int); +void (*pw_random_dylibloader_wrapper_pipewire)(void *, size_t); +void *(*pw_reallocarray_dylibloader_wrapper_pipewire)(void *, size_t, size_t); +struct pw_protocol *(*pw_protocol_new_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, size_t); +void (*pw_protocol_destroy_dylibloader_wrapper_pipewire)(struct pw_protocol *); +struct pw_context *(*pw_protocol_get_context_dylibloader_wrapper_pipewire)(struct pw_protocol *); +void *(*pw_protocol_get_user_data_dylibloader_wrapper_pipewire)(struct pw_protocol *); +const struct pw_protocol_implementation *(*pw_protocol_get_implementation_dylibloader_wrapper_pipewire)(struct pw_protocol *); +const void *(*pw_protocol_get_extension_dylibloader_wrapper_pipewire)(struct pw_protocol *); +void (*pw_protocol_add_listener_dylibloader_wrapper_pipewire)(struct pw_protocol *, struct spa_hook *, const struct pw_protocol_events *, void *); +int (*pw_protocol_add_marshal_dylibloader_wrapper_pipewire)(struct pw_protocol *, const struct pw_protocol_marshal *); +const struct pw_protocol_marshal *(*pw_protocol_get_marshal_dylibloader_wrapper_pipewire)(struct pw_protocol *, const char *, uint32_t, uint32_t); +struct pw_protocol *(*pw_context_find_protocol_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +struct pw_proxy *(*pw_proxy_new_dylibloader_wrapper_pipewire)(struct pw_proxy *, const char *, uint32_t, size_t); +void (*pw_proxy_add_listener_dylibloader_wrapper_pipewire)(struct pw_proxy *, struct spa_hook *, const struct pw_proxy_events *, void *); +void (*pw_proxy_add_object_listener_dylibloader_wrapper_pipewire)(struct pw_proxy *, struct spa_hook *, const void *, void *); +void (*pw_proxy_destroy_dylibloader_wrapper_pipewire)(struct pw_proxy *); +void (*pw_proxy_ref_dylibloader_wrapper_pipewire)(struct pw_proxy *); +void (*pw_proxy_unref_dylibloader_wrapper_pipewire)(struct pw_proxy *); +void *(*pw_proxy_get_user_data_dylibloader_wrapper_pipewire)(struct pw_proxy *); +uint32_t (*pw_proxy_get_id_dylibloader_wrapper_pipewire)(struct pw_proxy *); +const char *(*pw_proxy_get_type_dylibloader_wrapper_pipewire)(struct pw_proxy *, uint32_t *); +struct pw_protocol *(*pw_proxy_get_protocol_dylibloader_wrapper_pipewire)(struct pw_proxy *); +int (*pw_proxy_sync_dylibloader_wrapper_pipewire)(struct pw_proxy *, int); +int (*pw_proxy_set_bound_id_dylibloader_wrapper_pipewire)(struct pw_proxy *, uint32_t); +uint32_t (*pw_proxy_get_bound_id_dylibloader_wrapper_pipewire)(struct pw_proxy *); +int (*pw_proxy_error_dylibloader_wrapper_pipewire)(struct pw_proxy *, int, const char *); +int (*pw_proxy_errorf_dylibloader_wrapper_pipewire)(struct pw_proxy *, int, const char *, ...); +struct spa_hook_list *(*pw_proxy_get_object_listeners_dylibloader_wrapper_pipewire)(struct pw_proxy *); +const struct pw_protocol_marshal *(*pw_proxy_get_marshal_dylibloader_wrapper_pipewire)(struct pw_proxy *); +int (*pw_proxy_install_marshal_dylibloader_wrapper_pipewire)(struct pw_proxy *, bool); +struct pw_client_info *(*pw_client_info_update_dylibloader_wrapper_pipewire)(struct pw_client_info *, const struct pw_client_info *); +struct pw_client_info *(*pw_client_info_merge_dylibloader_wrapper_pipewire)(struct pw_client_info *, const struct pw_client_info *, bool); +void (*pw_client_info_free_dylibloader_wrapper_pipewire)(struct pw_client_info *); +int (*pw_conf_load_conf_for_context_dylibloader_wrapper_pipewire)(struct pw_properties *, struct pw_properties *); +int (*pw_conf_load_conf_dylibloader_wrapper_pipewire)(const char *, const char *, struct pw_properties *); +int (*pw_conf_load_state_dylibloader_wrapper_pipewire)(const char *, const char *, struct pw_properties *); +int (*pw_conf_save_state_dylibloader_wrapper_pipewire)(const char *, const char *, const struct pw_properties *); +int (*pw_conf_section_update_props_dylibloader_wrapper_pipewire)(const struct spa_dict *, const char *, struct pw_properties *); +int (*pw_conf_section_for_each_dylibloader_wrapper_pipewire)(const struct spa_dict *, const char *, int (*)(void *data, const char *location, const char *section, const char *str, size_t len), void *); +int (*pw_conf_match_rules_dylibloader_wrapper_pipewire)(const char *, size_t, const char *, const struct spa_dict *, int (*)(void *data, const char *location, const char *action, const char *str, size_t len), void *); +int (*pw_conf_section_match_rules_dylibloader_wrapper_pipewire)(const struct spa_dict *, const char *, const struct spa_dict *, int (*)(void *data, const char *location, const char *action, const char *str, size_t len), void *); +struct pw_device_info *(*pw_device_info_update_dylibloader_wrapper_pipewire)(struct pw_device_info *, const struct pw_device_info *); +struct pw_device_info *(*pw_device_info_merge_dylibloader_wrapper_pipewire)(struct pw_device_info *, const struct pw_device_info *, bool); +void (*pw_device_info_free_dylibloader_wrapper_pipewire)(struct pw_device_info *); +struct pw_mempool *(*pw_mempool_new_dylibloader_wrapper_pipewire)(struct pw_properties *); +void (*pw_mempool_add_listener_dylibloader_wrapper_pipewire)(struct pw_mempool *, struct spa_hook *, const struct pw_mempool_events *, void *); +void (*pw_mempool_clear_dylibloader_wrapper_pipewire)(struct pw_mempool *); +void (*pw_mempool_destroy_dylibloader_wrapper_pipewire)(struct pw_mempool *); +struct pw_memblock *(*pw_mempool_alloc_dylibloader_wrapper_pipewire)(struct pw_mempool *, enum pw_memblock_flags, uint32_t, size_t); +struct pw_memblock *(*pw_mempool_import_block_dylibloader_wrapper_pipewire)(struct pw_mempool *, struct pw_memblock *); +struct pw_memblock *(*pw_mempool_import_dylibloader_wrapper_pipewire)(struct pw_mempool *, enum pw_memblock_flags, uint32_t, int); +void (*pw_memblock_free_dylibloader_wrapper_pipewire)(struct pw_memblock *); +int (*pw_mempool_remove_id_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t); +struct pw_memblock *(*pw_mempool_find_ptr_dylibloader_wrapper_pipewire)(struct pw_mempool *, const void *); +struct pw_memblock *(*pw_mempool_find_id_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t); +struct pw_memblock *(*pw_mempool_find_fd_dylibloader_wrapper_pipewire)(struct pw_mempool *, int); +struct pw_memmap *(*pw_memblock_map_dylibloader_wrapper_pipewire)(struct pw_memblock *, enum pw_memmap_flags, uint32_t, uint32_t, uint32_t [5]); +struct pw_memmap *(*pw_mempool_map_id_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t, enum pw_memmap_flags, uint32_t, uint32_t, uint32_t [5]); +struct pw_memmap *(*pw_mempool_import_map_dylibloader_wrapper_pipewire)(struct pw_mempool *, struct pw_mempool *, void *, uint32_t, uint32_t [5]); +struct pw_memmap *(*pw_mempool_find_tag_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t [5], size_t); +int (*pw_memmap_free_dylibloader_wrapper_pipewire)(struct pw_memmap *); +int (*pw_buffers_negotiate_dylibloader_wrapper_pipewire)(struct pw_context *, uint32_t, struct spa_node *, uint32_t, struct spa_node *, uint32_t, struct pw_buffers *); +void (*pw_buffers_clear_dylibloader_wrapper_pipewire)(struct pw_buffers *); +struct pw_factory_info *(*pw_factory_info_update_dylibloader_wrapper_pipewire)(struct pw_factory_info *, const struct pw_factory_info *); +struct pw_factory_info *(*pw_factory_info_merge_dylibloader_wrapper_pipewire)(struct pw_factory_info *, const struct pw_factory_info *, bool); +void (*pw_factory_info_free_dylibloader_wrapper_pipewire)(struct pw_factory_info *); +void (*pw_log_set_dylibloader_wrapper_pipewire)(struct spa_log *); +struct spa_log *(*pw_log_get_dylibloader_wrapper_pipewire)(void); +void (*pw_log_set_level_dylibloader_wrapper_pipewire)(enum spa_log_level); +void (*pw_log_logt_dylibloader_wrapper_pipewire)(enum spa_log_level, const struct spa_log_topic *, const char *, int, const char *, const char *, ...); +void (*pw_log_logtv_dylibloader_wrapper_pipewire)(enum spa_log_level, const struct spa_log_topic *, const char *, int, const char *, const char *, va_list); +void (*pw_log_log_dylibloader_wrapper_pipewire)(enum spa_log_level, const char *, int, const char *, const char *, ...); +void (*pw_log_logv_dylibloader_wrapper_pipewire)(enum spa_log_level, const char *, int, const char *, const char *, va_list); +const char *(*pw_link_state_as_string_dylibloader_wrapper_pipewire)(enum pw_link_state); +struct pw_link_info *(*pw_link_info_update_dylibloader_wrapper_pipewire)(struct pw_link_info *, const struct pw_link_info *); +struct pw_link_info *(*pw_link_info_merge_dylibloader_wrapper_pipewire)(struct pw_link_info *, const struct pw_link_info *, bool); +void (*pw_link_info_free_dylibloader_wrapper_pipewire)(struct pw_link_info *); +struct pw_main_loop *(*pw_main_loop_new_dylibloader_wrapper_pipewire)(const struct spa_dict *); +void (*pw_main_loop_add_listener_dylibloader_wrapper_pipewire)(struct pw_main_loop *, struct spa_hook *, const struct pw_main_loop_events *, void *); +struct pw_loop *(*pw_main_loop_get_loop_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +void (*pw_main_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +int (*pw_main_loop_run_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +int (*pw_main_loop_quit_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +struct pw_module_info *(*pw_module_info_update_dylibloader_wrapper_pipewire)(struct pw_module_info *, const struct pw_module_info *); +struct pw_module_info *(*pw_module_info_merge_dylibloader_wrapper_pipewire)(struct pw_module_info *, const struct pw_module_info *, bool); +void (*pw_module_info_free_dylibloader_wrapper_pipewire)(struct pw_module_info *); +const char *(*pw_node_state_as_string_dylibloader_wrapper_pipewire)(enum pw_node_state); +struct pw_node_info *(*pw_node_info_update_dylibloader_wrapper_pipewire)(struct pw_node_info *, const struct pw_node_info *); +struct pw_node_info *(*pw_node_info_merge_dylibloader_wrapper_pipewire)(struct pw_node_info *, const struct pw_node_info *, bool); +void (*pw_node_info_free_dylibloader_wrapper_pipewire)(struct pw_node_info *); +const char *(*pw_direction_as_string_dylibloader_wrapper_pipewire)(enum spa_direction); +struct pw_port_info *(*pw_port_info_update_dylibloader_wrapper_pipewire)(struct pw_port_info *, const struct pw_port_info *); +struct pw_port_info *(*pw_port_info_merge_dylibloader_wrapper_pipewire)(struct pw_port_info *, const struct pw_port_info *, bool); +void (*pw_port_info_free_dylibloader_wrapper_pipewire)(struct pw_port_info *); +const char *(*pw_stream_state_as_string_dylibloader_wrapper_pipewire)(enum pw_stream_state); +struct pw_stream *(*pw_stream_new_dylibloader_wrapper_pipewire)(struct pw_core *, const char *, struct pw_properties *); +struct pw_stream *(*pw_stream_new_simple_dylibloader_wrapper_pipewire)(struct pw_loop *, const char *, struct pw_properties *, const struct pw_stream_events *, void *); +void (*pw_stream_destroy_dylibloader_wrapper_pipewire)(struct pw_stream *); +void (*pw_stream_add_listener_dylibloader_wrapper_pipewire)(struct pw_stream *, struct spa_hook *, const struct pw_stream_events *, void *); +enum pw_stream_state (*pw_stream_get_state_dylibloader_wrapper_pipewire)(struct pw_stream *, const char **); +const char *(*pw_stream_get_name_dylibloader_wrapper_pipewire)(struct pw_stream *); +struct pw_core *(*pw_stream_get_core_dylibloader_wrapper_pipewire)(struct pw_stream *); +const struct pw_properties *(*pw_stream_get_properties_dylibloader_wrapper_pipewire)(struct pw_stream *); +int (*pw_stream_update_properties_dylibloader_wrapper_pipewire)(struct pw_stream *, const struct spa_dict *); +int (*pw_stream_connect_dylibloader_wrapper_pipewire)(struct pw_stream *, enum spa_direction, uint32_t, enum pw_stream_flags, const struct spa_pod **, uint32_t); +uint32_t (*pw_stream_get_node_id_dylibloader_wrapper_pipewire)(struct pw_stream *); +int (*pw_stream_disconnect_dylibloader_wrapper_pipewire)(struct pw_stream *); +int (*pw_stream_set_error_dylibloader_wrapper_pipewire)(struct pw_stream *, int, const char *, ...); +int (*pw_stream_update_params_dylibloader_wrapper_pipewire)(struct pw_stream *, const struct spa_pod **, uint32_t); +int (*pw_stream_set_param_dylibloader_wrapper_pipewire)(struct pw_stream *, uint32_t, const struct spa_pod *); +const struct pw_stream_control *(*pw_stream_get_control_dylibloader_wrapper_pipewire)(struct pw_stream *, uint32_t); +int (*pw_stream_set_control_dylibloader_wrapper_pipewire)(struct pw_stream *, uint32_t, uint32_t, float *, ...); +int (*pw_stream_get_time_n_dylibloader_wrapper_pipewire)(struct pw_stream *, struct pw_time *, size_t); +int (*pw_stream_get_time_dylibloader_wrapper_pipewire)(struct pw_stream *, struct pw_time *); +struct pw_buffer *(*pw_stream_dequeue_buffer_dylibloader_wrapper_pipewire)(struct pw_stream *); +int (*pw_stream_queue_buffer_dylibloader_wrapper_pipewire)(struct pw_stream *, struct pw_buffer *); +int (*pw_stream_set_active_dylibloader_wrapper_pipewire)(struct pw_stream *, bool); +int (*pw_stream_flush_dylibloader_wrapper_pipewire)(struct pw_stream *, bool); +bool (*pw_stream_is_driving_dylibloader_wrapper_pipewire)(struct pw_stream *); +int (*pw_stream_trigger_process_dylibloader_wrapper_pipewire)(struct pw_stream *); +const char *(*pw_filter_state_as_string_dylibloader_wrapper_pipewire)(enum pw_filter_state); +struct pw_filter *(*pw_filter_new_dylibloader_wrapper_pipewire)(struct pw_core *, const char *, struct pw_properties *); +struct pw_filter *(*pw_filter_new_simple_dylibloader_wrapper_pipewire)(struct pw_loop *, const char *, struct pw_properties *, const struct pw_filter_events *, void *); +void (*pw_filter_destroy_dylibloader_wrapper_pipewire)(struct pw_filter *); +void (*pw_filter_add_listener_dylibloader_wrapper_pipewire)(struct pw_filter *, struct spa_hook *, const struct pw_filter_events *, void *); +enum pw_filter_state (*pw_filter_get_state_dylibloader_wrapper_pipewire)(struct pw_filter *, const char **); +const char *(*pw_filter_get_name_dylibloader_wrapper_pipewire)(struct pw_filter *); +struct pw_core *(*pw_filter_get_core_dylibloader_wrapper_pipewire)(struct pw_filter *); +int (*pw_filter_connect_dylibloader_wrapper_pipewire)(struct pw_filter *, enum pw_filter_flags, const struct spa_pod **, uint32_t); +uint32_t (*pw_filter_get_node_id_dylibloader_wrapper_pipewire)(struct pw_filter *); +int (*pw_filter_disconnect_dylibloader_wrapper_pipewire)(struct pw_filter *); +void *(*pw_filter_add_port_dylibloader_wrapper_pipewire)(struct pw_filter *, enum spa_direction, enum pw_filter_port_flags, size_t, struct pw_properties *, const struct spa_pod **, uint32_t); +int (*pw_filter_remove_port_dylibloader_wrapper_pipewire)(void *); +const struct pw_properties *(*pw_filter_get_properties_dylibloader_wrapper_pipewire)(struct pw_filter *, void *); +int (*pw_filter_update_properties_dylibloader_wrapper_pipewire)(struct pw_filter *, void *, const struct spa_dict *); +int (*pw_filter_set_error_dylibloader_wrapper_pipewire)(struct pw_filter *, int, const char *, ...); +int (*pw_filter_update_params_dylibloader_wrapper_pipewire)(struct pw_filter *, void *, const struct spa_pod **, uint32_t); +int (*pw_filter_get_time_dylibloader_wrapper_pipewire)(struct pw_filter *, struct pw_time *); +struct pw_buffer *(*pw_filter_dequeue_buffer_dylibloader_wrapper_pipewire)(void *); +int (*pw_filter_queue_buffer_dylibloader_wrapper_pipewire)(void *, struct pw_buffer *); +void *(*pw_filter_get_dsp_buffer_dylibloader_wrapper_pipewire)(void *, uint32_t); +int (*pw_filter_set_active_dylibloader_wrapper_pipewire)(struct pw_filter *, bool); +int (*pw_filter_flush_dylibloader_wrapper_pipewire)(struct pw_filter *, bool); +bool (*pw_filter_is_driving_dylibloader_wrapper_pipewire)(struct pw_filter *); +int (*pw_filter_trigger_process_dylibloader_wrapper_pipewire)(struct pw_filter *); +struct pw_thread_loop *(*pw_thread_loop_new_dylibloader_wrapper_pipewire)(const char *, const struct spa_dict *); +struct pw_thread_loop *(*pw_thread_loop_new_full_dylibloader_wrapper_pipewire)(struct pw_loop *, const char *, const struct spa_dict *); +void (*pw_thread_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +void (*pw_thread_loop_add_listener_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, struct spa_hook *, const struct pw_thread_loop_events *, void *); +struct pw_loop *(*pw_thread_loop_get_loop_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +int (*pw_thread_loop_start_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +void (*pw_thread_loop_stop_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +void (*pw_thread_loop_lock_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +void (*pw_thread_loop_unlock_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +void (*pw_thread_loop_wait_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +int (*pw_thread_loop_timed_wait_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, int); +int (*pw_thread_loop_get_time_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, struct timespec *, int64_t); +int (*pw_thread_loop_timed_wait_full_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, const struct timespec *); +void (*pw_thread_loop_signal_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, bool); +void (*pw_thread_loop_accept_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +bool (*pw_thread_loop_in_thread_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +struct pw_data_loop *(*pw_data_loop_new_dylibloader_wrapper_pipewire)(const struct spa_dict *); +void (*pw_data_loop_add_listener_dylibloader_wrapper_pipewire)(struct pw_data_loop *, struct spa_hook *, const struct pw_data_loop_events *, void *); +int (*pw_data_loop_wait_dylibloader_wrapper_pipewire)(struct pw_data_loop *, int); +void (*pw_data_loop_exit_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +struct pw_loop *(*pw_data_loop_get_loop_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +void (*pw_data_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +int (*pw_data_loop_start_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +int (*pw_data_loop_stop_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +bool (*pw_data_loop_in_thread_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +struct spa_thread *(*pw_data_loop_get_thread_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +int (*pw_data_loop_invoke_dylibloader_wrapper_pipewire)(struct pw_data_loop *, spa_invoke_func_t, uint32_t, const void *, size_t, bool, void *); +void (*pw_data_loop_set_thread_utils_dylibloader_wrapper_pipewire)(struct pw_data_loop *, struct spa_thread_utils *); +const struct spa_type_info *(*pw_type_info_dylibloader_wrapper_pipewire)(void); +const char *(*pw_get_library_version_dylibloader_wrapper_pipewire)(void); +bool (*pw_check_library_version_dylibloader_wrapper_pipewire)(int, int, int); +void (*pw_init_dylibloader_wrapper_pipewire)(int *, char **[]); +void (*pw_deinit_dylibloader_wrapper_pipewire)(void); +bool (*pw_debug_is_category_enabled_dylibloader_wrapper_pipewire)(const char *); +const char *(*pw_get_application_name_dylibloader_wrapper_pipewire)(void); +const char *(*pw_get_prgname_dylibloader_wrapper_pipewire)(void); +const char *(*pw_get_user_name_dylibloader_wrapper_pipewire)(void); +const char *(*pw_get_host_name_dylibloader_wrapper_pipewire)(void); +const char *(*pw_get_client_name_dylibloader_wrapper_pipewire)(void); +bool (*pw_check_option_dylibloader_wrapper_pipewire)(const char *, const char *); +enum spa_direction (*pw_direction_reverse_dylibloader_wrapper_pipewire)(enum spa_direction); +int (*pw_set_domain_dylibloader_wrapper_pipewire)(const char *); +const char *(*pw_get_domain_dylibloader_wrapper_pipewire)(void); +uint32_t (*pw_get_support_dylibloader_wrapper_pipewire)(struct spa_support *, uint32_t); +struct spa_handle *(*pw_load_spa_handle_dylibloader_wrapper_pipewire)(const char *, const char *, const struct spa_dict *, uint32_t, const struct spa_support []); +int (*pw_unload_spa_handle_dylibloader_wrapper_pipewire)(struct spa_handle *); +int initialize_pipewire(int verbose) { + void *handle; + char *error; + handle = dlopen("libpipewire-0.3.so.0", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// pw_properties_new + *(void **) (&pw_properties_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_new_dict + *(void **) (&pw_properties_new_dict_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_new_dict"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_new_string + *(void **) (&pw_properties_new_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_new_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_copy + *(void **) (&pw_properties_copy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_update_keys + *(void **) (&pw_properties_update_keys_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_update_keys"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_update_ignore + *(void **) (&pw_properties_update_ignore_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_update_ignore"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_update + *(void **) (&pw_properties_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_update_string + *(void **) (&pw_properties_update_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_update_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_add + *(void **) (&pw_properties_add_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_add"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_add_keys + *(void **) (&pw_properties_add_keys_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_add_keys"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_clear + *(void **) (&pw_properties_clear_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_free + *(void **) (&pw_properties_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_set + *(void **) (&pw_properties_set_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_setf + *(void **) (&pw_properties_setf_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_setf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_setva + *(void **) (&pw_properties_setva_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_setva"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_get + *(void **) (&pw_properties_get_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_get"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_fetch_uint32 + *(void **) (&pw_properties_fetch_uint32_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_fetch_uint32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_fetch_int32 + *(void **) (&pw_properties_fetch_int32_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_fetch_int32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_fetch_uint64 + *(void **) (&pw_properties_fetch_uint64_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_fetch_uint64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_fetch_int64 + *(void **) (&pw_properties_fetch_int64_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_fetch_int64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_fetch_bool + *(void **) (&pw_properties_fetch_bool_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_fetch_bool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_iterate + *(void **) (&pw_properties_iterate_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_iterate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_properties_serialize_dict + *(void **) (&pw_properties_serialize_dict_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_properties_serialize_dict"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_info_update + *(void **) (&pw_core_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_info_merge + *(void **) (&pw_core_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_info_free + *(void **) (&pw_core_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_connect + *(void **) (&pw_context_connect_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_connect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_connect_fd + *(void **) (&pw_context_connect_fd_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_connect_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_connect_self + *(void **) (&pw_context_connect_self_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_connect_self"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_steal_fd + *(void **) (&pw_core_steal_fd_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_steal_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_set_paused + *(void **) (&pw_core_set_paused_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_set_paused"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_disconnect + *(void **) (&pw_core_disconnect_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_get_user_data + *(void **) (&pw_core_get_user_data_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_get_user_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_get_client + *(void **) (&pw_core_get_client_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_get_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_get_context + *(void **) (&pw_core_get_context_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_get_context"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_get_properties + *(void **) (&pw_core_get_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_get_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_update_properties + *(void **) (&pw_core_update_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_update_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_get_mempool + *(void **) (&pw_core_get_mempool_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_get_mempool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_find_proxy + *(void **) (&pw_core_find_proxy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_find_proxy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_core_export + *(void **) (&pw_core_export_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_core_export"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_loop_new + *(void **) (&pw_loop_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_loop_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_loop_destroy + *(void **) (&pw_loop_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_loop_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_new + *(void **) (&pw_context_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_destroy + *(void **) (&pw_context_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_user_data + *(void **) (&pw_context_get_user_data_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_user_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_add_listener + *(void **) (&pw_context_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_properties + *(void **) (&pw_context_get_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_update_properties + *(void **) (&pw_context_update_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_update_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_conf_section + *(void **) (&pw_context_get_conf_section_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_conf_section"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_parse_conf_section + *(void **) (&pw_context_parse_conf_section_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_parse_conf_section"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_conf_update_props + *(void **) (&pw_context_conf_update_props_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_conf_update_props"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_conf_section_for_each + *(void **) (&pw_context_conf_section_for_each_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_conf_section_for_each"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_conf_section_match_rules + *(void **) (&pw_context_conf_section_match_rules_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_conf_section_match_rules"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_support + *(void **) (&pw_context_get_support_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_support"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_main_loop + *(void **) (&pw_context_get_main_loop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_main_loop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_data_loop + *(void **) (&pw_context_get_data_loop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_data_loop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_work_queue + *(void **) (&pw_context_get_work_queue_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_work_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_mempool + *(void **) (&pw_context_get_mempool_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_mempool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_for_each_global + *(void **) (&pw_context_for_each_global_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_for_each_global"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_find_global + *(void **) (&pw_context_find_global_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_find_global"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_add_spa_lib + *(void **) (&pw_context_add_spa_lib_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_add_spa_lib"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_find_spa_lib + *(void **) (&pw_context_find_spa_lib_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_find_spa_lib"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_load_spa_handle + *(void **) (&pw_context_load_spa_handle_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_load_spa_handle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_register_export_type + *(void **) (&pw_context_register_export_type_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_register_export_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_find_export_type + *(void **) (&pw_context_find_export_type_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_find_export_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_set_object + *(void **) (&pw_context_set_object_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_set_object"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_get_object + *(void **) (&pw_context_get_object_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_get_object"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_split_walk + *(void **) (&pw_split_walk_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_split_walk"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_split_strv + *(void **) (&pw_split_strv_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_split_strv"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_split_ip + *(void **) (&pw_split_ip_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_split_ip"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_strv_parse + *(void **) (&pw_strv_parse_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_strv_parse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_strv_find + *(void **) (&pw_strv_find_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_strv_find"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_strv_find_common + *(void **) (&pw_strv_find_common_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_strv_find_common"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_free_strv + *(void **) (&pw_free_strv_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_free_strv"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_strip + *(void **) (&pw_strip_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_strip"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_getrandom + *(void **) (&pw_getrandom_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_getrandom"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_random + *(void **) (&pw_random_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_random"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_reallocarray + *(void **) (&pw_reallocarray_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_reallocarray"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_new + *(void **) (&pw_protocol_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_destroy + *(void **) (&pw_protocol_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_get_context + *(void **) (&pw_protocol_get_context_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_get_context"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_get_user_data + *(void **) (&pw_protocol_get_user_data_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_get_user_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_get_implementation + *(void **) (&pw_protocol_get_implementation_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_get_implementation"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_get_extension + *(void **) (&pw_protocol_get_extension_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_get_extension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_add_listener + *(void **) (&pw_protocol_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_add_marshal + *(void **) (&pw_protocol_add_marshal_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_add_marshal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_protocol_get_marshal + *(void **) (&pw_protocol_get_marshal_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_protocol_get_marshal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_context_find_protocol + *(void **) (&pw_context_find_protocol_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_context_find_protocol"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_new + *(void **) (&pw_proxy_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_add_listener + *(void **) (&pw_proxy_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_add_object_listener + *(void **) (&pw_proxy_add_object_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_add_object_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_destroy + *(void **) (&pw_proxy_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_ref + *(void **) (&pw_proxy_ref_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_unref + *(void **) (&pw_proxy_unref_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_user_data + *(void **) (&pw_proxy_get_user_data_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_user_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_id + *(void **) (&pw_proxy_get_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_type + *(void **) (&pw_proxy_get_type_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_protocol + *(void **) (&pw_proxy_get_protocol_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_protocol"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_sync + *(void **) (&pw_proxy_sync_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_sync"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_set_bound_id + *(void **) (&pw_proxy_set_bound_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_set_bound_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_bound_id + *(void **) (&pw_proxy_get_bound_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_bound_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_error + *(void **) (&pw_proxy_error_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_errorf + *(void **) (&pw_proxy_errorf_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_errorf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_object_listeners + *(void **) (&pw_proxy_get_object_listeners_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_object_listeners"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_get_marshal + *(void **) (&pw_proxy_get_marshal_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_get_marshal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_proxy_install_marshal + *(void **) (&pw_proxy_install_marshal_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_proxy_install_marshal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_client_info_update + *(void **) (&pw_client_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_client_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_client_info_merge + *(void **) (&pw_client_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_client_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_client_info_free + *(void **) (&pw_client_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_client_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_load_conf_for_context + *(void **) (&pw_conf_load_conf_for_context_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_load_conf_for_context"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_load_conf + *(void **) (&pw_conf_load_conf_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_load_conf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_load_state + *(void **) (&pw_conf_load_state_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_load_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_save_state + *(void **) (&pw_conf_save_state_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_save_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_section_update_props + *(void **) (&pw_conf_section_update_props_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_section_update_props"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_section_for_each + *(void **) (&pw_conf_section_for_each_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_section_for_each"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_match_rules + *(void **) (&pw_conf_match_rules_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_match_rules"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_conf_section_match_rules + *(void **) (&pw_conf_section_match_rules_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_conf_section_match_rules"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_device_info_update + *(void **) (&pw_device_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_device_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_device_info_merge + *(void **) (&pw_device_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_device_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_device_info_free + *(void **) (&pw_device_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_device_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_new + *(void **) (&pw_mempool_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_add_listener + *(void **) (&pw_mempool_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_clear + *(void **) (&pw_mempool_clear_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_destroy + *(void **) (&pw_mempool_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_alloc + *(void **) (&pw_mempool_alloc_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_alloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_import_block + *(void **) (&pw_mempool_import_block_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_import_block"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_import + *(void **) (&pw_mempool_import_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_import"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_memblock_free + *(void **) (&pw_memblock_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_memblock_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_remove_id + *(void **) (&pw_mempool_remove_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_remove_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_find_ptr + *(void **) (&pw_mempool_find_ptr_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_find_ptr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_find_id + *(void **) (&pw_mempool_find_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_find_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_find_fd + *(void **) (&pw_mempool_find_fd_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_find_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_memblock_map + *(void **) (&pw_memblock_map_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_memblock_map"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_map_id + *(void **) (&pw_mempool_map_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_map_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_import_map + *(void **) (&pw_mempool_import_map_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_import_map"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_mempool_find_tag + *(void **) (&pw_mempool_find_tag_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_mempool_find_tag"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_memmap_free + *(void **) (&pw_memmap_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_memmap_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_buffers_negotiate + *(void **) (&pw_buffers_negotiate_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_buffers_negotiate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_buffers_clear + *(void **) (&pw_buffers_clear_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_buffers_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_factory_info_update + *(void **) (&pw_factory_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_factory_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_factory_info_merge + *(void **) (&pw_factory_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_factory_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_factory_info_free + *(void **) (&pw_factory_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_factory_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_set + *(void **) (&pw_log_set_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_get + *(void **) (&pw_log_get_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_get"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_set_level + *(void **) (&pw_log_set_level_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_set_level"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_logt + *(void **) (&pw_log_logt_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_logt"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_logtv + *(void **) (&pw_log_logtv_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_logtv"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_log + *(void **) (&pw_log_log_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_log"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_log_logv + *(void **) (&pw_log_logv_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_log_logv"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_link_state_as_string + *(void **) (&pw_link_state_as_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_link_state_as_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_link_info_update + *(void **) (&pw_link_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_link_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_link_info_merge + *(void **) (&pw_link_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_link_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_link_info_free + *(void **) (&pw_link_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_link_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_main_loop_new + *(void **) (&pw_main_loop_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_main_loop_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_main_loop_add_listener + *(void **) (&pw_main_loop_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_main_loop_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_main_loop_get_loop + *(void **) (&pw_main_loop_get_loop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_main_loop_get_loop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_main_loop_destroy + *(void **) (&pw_main_loop_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_main_loop_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_main_loop_run + *(void **) (&pw_main_loop_run_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_main_loop_run"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_main_loop_quit + *(void **) (&pw_main_loop_quit_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_main_loop_quit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_module_info_update + *(void **) (&pw_module_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_module_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_module_info_merge + *(void **) (&pw_module_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_module_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_module_info_free + *(void **) (&pw_module_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_module_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_node_state_as_string + *(void **) (&pw_node_state_as_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_node_state_as_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_node_info_update + *(void **) (&pw_node_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_node_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_node_info_merge + *(void **) (&pw_node_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_node_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_node_info_free + *(void **) (&pw_node_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_node_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_direction_as_string + *(void **) (&pw_direction_as_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_direction_as_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_port_info_update + *(void **) (&pw_port_info_update_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_port_info_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_port_info_merge + *(void **) (&pw_port_info_merge_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_port_info_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_port_info_free + *(void **) (&pw_port_info_free_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_port_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_state_as_string + *(void **) (&pw_stream_state_as_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_state_as_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_new + *(void **) (&pw_stream_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_new_simple + *(void **) (&pw_stream_new_simple_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_new_simple"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_destroy + *(void **) (&pw_stream_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_add_listener + *(void **) (&pw_stream_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_state + *(void **) (&pw_stream_get_state_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_name + *(void **) (&pw_stream_get_name_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_core + *(void **) (&pw_stream_get_core_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_core"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_properties + *(void **) (&pw_stream_get_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_update_properties + *(void **) (&pw_stream_update_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_update_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_connect + *(void **) (&pw_stream_connect_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_connect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_node_id + *(void **) (&pw_stream_get_node_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_node_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_disconnect + *(void **) (&pw_stream_disconnect_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_set_error + *(void **) (&pw_stream_set_error_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_set_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_update_params + *(void **) (&pw_stream_update_params_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_update_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_set_param + *(void **) (&pw_stream_set_param_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_set_param"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_control + *(void **) (&pw_stream_get_control_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_control"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_set_control + *(void **) (&pw_stream_set_control_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_set_control"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_time_n + *(void **) (&pw_stream_get_time_n_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_time_n"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_get_time + *(void **) (&pw_stream_get_time_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_get_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_dequeue_buffer + *(void **) (&pw_stream_dequeue_buffer_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_dequeue_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_queue_buffer + *(void **) (&pw_stream_queue_buffer_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_queue_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_set_active + *(void **) (&pw_stream_set_active_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_set_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_flush + *(void **) (&pw_stream_flush_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_flush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_is_driving + *(void **) (&pw_stream_is_driving_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_is_driving"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_stream_trigger_process + *(void **) (&pw_stream_trigger_process_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_stream_trigger_process"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_state_as_string + *(void **) (&pw_filter_state_as_string_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_state_as_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_new + *(void **) (&pw_filter_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_new_simple + *(void **) (&pw_filter_new_simple_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_new_simple"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_destroy + *(void **) (&pw_filter_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_add_listener + *(void **) (&pw_filter_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_state + *(void **) (&pw_filter_get_state_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_name + *(void **) (&pw_filter_get_name_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_core + *(void **) (&pw_filter_get_core_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_core"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_connect + *(void **) (&pw_filter_connect_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_connect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_node_id + *(void **) (&pw_filter_get_node_id_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_node_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_disconnect + *(void **) (&pw_filter_disconnect_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_add_port + *(void **) (&pw_filter_add_port_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_add_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_remove_port + *(void **) (&pw_filter_remove_port_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_remove_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_properties + *(void **) (&pw_filter_get_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_update_properties + *(void **) (&pw_filter_update_properties_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_update_properties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_set_error + *(void **) (&pw_filter_set_error_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_set_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_update_params + *(void **) (&pw_filter_update_params_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_update_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_time + *(void **) (&pw_filter_get_time_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_dequeue_buffer + *(void **) (&pw_filter_dequeue_buffer_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_dequeue_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_queue_buffer + *(void **) (&pw_filter_queue_buffer_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_queue_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_get_dsp_buffer + *(void **) (&pw_filter_get_dsp_buffer_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_get_dsp_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_set_active + *(void **) (&pw_filter_set_active_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_set_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_flush + *(void **) (&pw_filter_flush_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_flush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_is_driving + *(void **) (&pw_filter_is_driving_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_is_driving"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_filter_trigger_process + *(void **) (&pw_filter_trigger_process_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_filter_trigger_process"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_new + *(void **) (&pw_thread_loop_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_new_full + *(void **) (&pw_thread_loop_new_full_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_new_full"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_destroy + *(void **) (&pw_thread_loop_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_add_listener + *(void **) (&pw_thread_loop_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_get_loop + *(void **) (&pw_thread_loop_get_loop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_get_loop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_start + *(void **) (&pw_thread_loop_start_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_stop + *(void **) (&pw_thread_loop_stop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_stop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_lock + *(void **) (&pw_thread_loop_lock_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_lock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_unlock + *(void **) (&pw_thread_loop_unlock_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_unlock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_wait + *(void **) (&pw_thread_loop_wait_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_timed_wait + *(void **) (&pw_thread_loop_timed_wait_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_timed_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_get_time + *(void **) (&pw_thread_loop_get_time_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_get_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_timed_wait_full + *(void **) (&pw_thread_loop_timed_wait_full_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_timed_wait_full"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_signal + *(void **) (&pw_thread_loop_signal_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_signal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_accept + *(void **) (&pw_thread_loop_accept_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_accept"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_thread_loop_in_thread + *(void **) (&pw_thread_loop_in_thread_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_thread_loop_in_thread"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_new + *(void **) (&pw_data_loop_new_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_add_listener + *(void **) (&pw_data_loop_add_listener_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_add_listener"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_wait + *(void **) (&pw_data_loop_wait_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_exit + *(void **) (&pw_data_loop_exit_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_exit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_get_loop + *(void **) (&pw_data_loop_get_loop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_get_loop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_destroy + *(void **) (&pw_data_loop_destroy_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_start + *(void **) (&pw_data_loop_start_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_stop + *(void **) (&pw_data_loop_stop_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_stop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_in_thread + *(void **) (&pw_data_loop_in_thread_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_in_thread"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_get_thread + *(void **) (&pw_data_loop_get_thread_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_get_thread"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_invoke + *(void **) (&pw_data_loop_invoke_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_invoke"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_data_loop_set_thread_utils + *(void **) (&pw_data_loop_set_thread_utils_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_data_loop_set_thread_utils"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_type_info + *(void **) (&pw_type_info_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_type_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_library_version + *(void **) (&pw_get_library_version_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_library_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_check_library_version + *(void **) (&pw_check_library_version_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_check_library_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_init + *(void **) (&pw_init_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_deinit + *(void **) (&pw_deinit_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_deinit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_debug_is_category_enabled + *(void **) (&pw_debug_is_category_enabled_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_debug_is_category_enabled"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_application_name + *(void **) (&pw_get_application_name_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_application_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_prgname + *(void **) (&pw_get_prgname_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_prgname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_user_name + *(void **) (&pw_get_user_name_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_user_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_host_name + *(void **) (&pw_get_host_name_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_host_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_client_name + *(void **) (&pw_get_client_name_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_client_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_check_option + *(void **) (&pw_check_option_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_check_option"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_direction_reverse + *(void **) (&pw_direction_reverse_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_direction_reverse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_set_domain + *(void **) (&pw_set_domain_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_set_domain"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_domain + *(void **) (&pw_get_domain_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_domain"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_get_support + *(void **) (&pw_get_support_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_get_support"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_load_spa_handle + *(void **) (&pw_load_spa_handle_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_load_spa_handle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pw_unload_spa_handle + *(void **) (&pw_unload_spa_handle_dylibloader_wrapper_pipewire) = dlsym(handle, "pw_unload_spa_handle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/drivers/pipewire/pipewire-so_wrap.h b/drivers/pipewire/pipewire-so_wrap.h new file mode 100644 index 000000000000..44247ec56f15 --- /dev/null +++ b/drivers/pipewire/pipewire-so_wrap.h @@ -0,0 +1,1086 @@ +#ifndef DYLIBLOAD_WRAPPER_PIPEWIRE +#define DYLIBLOAD_WRAPPER_PIPEWIRE +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.7 on 2026-03-18 00:35:26 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h --sys-include thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h --include-dir ./thirdparty/linuxbsd_headers/pipewire/ --soname libpipewire-0.3.so.0 --omit-prefix spa_ --init-name pipewire --output-header ./drivers/pipewire/pipewire-so_wrap.h --output-implementation ./drivers/pipewire/pipewire-so_wrap.c +// +#include + +#define pw_properties_new pw_properties_new_dylibloader_orig_pipewire +#define pw_properties_new_dict pw_properties_new_dict_dylibloader_orig_pipewire +#define pw_properties_new_string pw_properties_new_string_dylibloader_orig_pipewire +#define pw_properties_copy pw_properties_copy_dylibloader_orig_pipewire +#define pw_properties_update_keys pw_properties_update_keys_dylibloader_orig_pipewire +#define pw_properties_update_ignore pw_properties_update_ignore_dylibloader_orig_pipewire +#define pw_properties_update pw_properties_update_dylibloader_orig_pipewire +#define pw_properties_update_string pw_properties_update_string_dylibloader_orig_pipewire +#define pw_properties_add pw_properties_add_dylibloader_orig_pipewire +#define pw_properties_add_keys pw_properties_add_keys_dylibloader_orig_pipewire +#define pw_properties_clear pw_properties_clear_dylibloader_orig_pipewire +#define pw_properties_free pw_properties_free_dylibloader_orig_pipewire +#define pw_properties_set pw_properties_set_dylibloader_orig_pipewire +#define pw_properties_setf pw_properties_setf_dylibloader_orig_pipewire +#define pw_properties_setva pw_properties_setva_dylibloader_orig_pipewire +#define pw_properties_get pw_properties_get_dylibloader_orig_pipewire +#define pw_properties_fetch_uint32 pw_properties_fetch_uint32_dylibloader_orig_pipewire +#define pw_properties_fetch_int32 pw_properties_fetch_int32_dylibloader_orig_pipewire +#define pw_properties_fetch_uint64 pw_properties_fetch_uint64_dylibloader_orig_pipewire +#define pw_properties_fetch_int64 pw_properties_fetch_int64_dylibloader_orig_pipewire +#define pw_properties_fetch_bool pw_properties_fetch_bool_dylibloader_orig_pipewire +#define pw_properties_iterate pw_properties_iterate_dylibloader_orig_pipewire +#define pw_properties_serialize_dict pw_properties_serialize_dict_dylibloader_orig_pipewire +#define pw_core_info_update pw_core_info_update_dylibloader_orig_pipewire +#define pw_core_info_merge pw_core_info_merge_dylibloader_orig_pipewire +#define pw_core_info_free pw_core_info_free_dylibloader_orig_pipewire +#define pw_context_connect pw_context_connect_dylibloader_orig_pipewire +#define pw_context_connect_fd pw_context_connect_fd_dylibloader_orig_pipewire +#define pw_context_connect_self pw_context_connect_self_dylibloader_orig_pipewire +#define pw_core_steal_fd pw_core_steal_fd_dylibloader_orig_pipewire +#define pw_core_set_paused pw_core_set_paused_dylibloader_orig_pipewire +#define pw_core_disconnect pw_core_disconnect_dylibloader_orig_pipewire +#define pw_core_get_user_data pw_core_get_user_data_dylibloader_orig_pipewire +#define pw_core_get_client pw_core_get_client_dylibloader_orig_pipewire +#define pw_core_get_context pw_core_get_context_dylibloader_orig_pipewire +#define pw_core_get_properties pw_core_get_properties_dylibloader_orig_pipewire +#define pw_core_update_properties pw_core_update_properties_dylibloader_orig_pipewire +#define pw_core_get_mempool pw_core_get_mempool_dylibloader_orig_pipewire +#define pw_core_find_proxy pw_core_find_proxy_dylibloader_orig_pipewire +#define pw_core_export pw_core_export_dylibloader_orig_pipewire +#define pw_loop_new pw_loop_new_dylibloader_orig_pipewire +#define pw_loop_destroy pw_loop_destroy_dylibloader_orig_pipewire +#define pw_context_new pw_context_new_dylibloader_orig_pipewire +#define pw_context_destroy pw_context_destroy_dylibloader_orig_pipewire +#define pw_context_get_user_data pw_context_get_user_data_dylibloader_orig_pipewire +#define pw_context_add_listener pw_context_add_listener_dylibloader_orig_pipewire +#define pw_context_get_properties pw_context_get_properties_dylibloader_orig_pipewire +#define pw_context_update_properties pw_context_update_properties_dylibloader_orig_pipewire +#define pw_context_get_conf_section pw_context_get_conf_section_dylibloader_orig_pipewire +#define pw_context_parse_conf_section pw_context_parse_conf_section_dylibloader_orig_pipewire +#define pw_context_conf_update_props pw_context_conf_update_props_dylibloader_orig_pipewire +#define pw_context_conf_section_for_each pw_context_conf_section_for_each_dylibloader_orig_pipewire +#define pw_context_conf_section_match_rules pw_context_conf_section_match_rules_dylibloader_orig_pipewire +#define pw_context_get_support pw_context_get_support_dylibloader_orig_pipewire +#define pw_context_get_main_loop pw_context_get_main_loop_dylibloader_orig_pipewire +#define pw_context_get_data_loop pw_context_get_data_loop_dylibloader_orig_pipewire +#define pw_context_get_work_queue pw_context_get_work_queue_dylibloader_orig_pipewire +#define pw_context_get_mempool pw_context_get_mempool_dylibloader_orig_pipewire +#define pw_context_for_each_global pw_context_for_each_global_dylibloader_orig_pipewire +#define pw_context_find_global pw_context_find_global_dylibloader_orig_pipewire +#define pw_context_add_spa_lib pw_context_add_spa_lib_dylibloader_orig_pipewire +#define pw_context_find_spa_lib pw_context_find_spa_lib_dylibloader_orig_pipewire +#define pw_context_load_spa_handle pw_context_load_spa_handle_dylibloader_orig_pipewire +#define pw_context_register_export_type pw_context_register_export_type_dylibloader_orig_pipewire +#define pw_context_find_export_type pw_context_find_export_type_dylibloader_orig_pipewire +#define pw_context_set_object pw_context_set_object_dylibloader_orig_pipewire +#define pw_context_get_object pw_context_get_object_dylibloader_orig_pipewire +#define pw_split_walk pw_split_walk_dylibloader_orig_pipewire +#define pw_split_strv pw_split_strv_dylibloader_orig_pipewire +#define pw_split_ip pw_split_ip_dylibloader_orig_pipewire +#define pw_strv_parse pw_strv_parse_dylibloader_orig_pipewire +#define pw_strv_find pw_strv_find_dylibloader_orig_pipewire +#define pw_strv_find_common pw_strv_find_common_dylibloader_orig_pipewire +#define pw_free_strv pw_free_strv_dylibloader_orig_pipewire +#define pw_strip pw_strip_dylibloader_orig_pipewire +#define pw_getrandom pw_getrandom_dylibloader_orig_pipewire +#define pw_random pw_random_dylibloader_orig_pipewire +#define pw_reallocarray pw_reallocarray_dylibloader_orig_pipewire +#define pw_protocol_new pw_protocol_new_dylibloader_orig_pipewire +#define pw_protocol_destroy pw_protocol_destroy_dylibloader_orig_pipewire +#define pw_protocol_get_context pw_protocol_get_context_dylibloader_orig_pipewire +#define pw_protocol_get_user_data pw_protocol_get_user_data_dylibloader_orig_pipewire +#define pw_protocol_get_implementation pw_protocol_get_implementation_dylibloader_orig_pipewire +#define pw_protocol_get_extension pw_protocol_get_extension_dylibloader_orig_pipewire +#define pw_protocol_add_listener pw_protocol_add_listener_dylibloader_orig_pipewire +#define pw_protocol_add_marshal pw_protocol_add_marshal_dylibloader_orig_pipewire +#define pw_protocol_get_marshal pw_protocol_get_marshal_dylibloader_orig_pipewire +#define pw_context_find_protocol pw_context_find_protocol_dylibloader_orig_pipewire +#define pw_proxy_new pw_proxy_new_dylibloader_orig_pipewire +#define pw_proxy_add_listener pw_proxy_add_listener_dylibloader_orig_pipewire +#define pw_proxy_add_object_listener pw_proxy_add_object_listener_dylibloader_orig_pipewire +#define pw_proxy_destroy pw_proxy_destroy_dylibloader_orig_pipewire +#define pw_proxy_ref pw_proxy_ref_dylibloader_orig_pipewire +#define pw_proxy_unref pw_proxy_unref_dylibloader_orig_pipewire +#define pw_proxy_get_user_data pw_proxy_get_user_data_dylibloader_orig_pipewire +#define pw_proxy_get_id pw_proxy_get_id_dylibloader_orig_pipewire +#define pw_proxy_get_type pw_proxy_get_type_dylibloader_orig_pipewire +#define pw_proxy_get_protocol pw_proxy_get_protocol_dylibloader_orig_pipewire +#define pw_proxy_sync pw_proxy_sync_dylibloader_orig_pipewire +#define pw_proxy_set_bound_id pw_proxy_set_bound_id_dylibloader_orig_pipewire +#define pw_proxy_get_bound_id pw_proxy_get_bound_id_dylibloader_orig_pipewire +#define pw_proxy_error pw_proxy_error_dylibloader_orig_pipewire +#define pw_proxy_errorf pw_proxy_errorf_dylibloader_orig_pipewire +#define pw_proxy_get_object_listeners pw_proxy_get_object_listeners_dylibloader_orig_pipewire +#define pw_proxy_get_marshal pw_proxy_get_marshal_dylibloader_orig_pipewire +#define pw_proxy_install_marshal pw_proxy_install_marshal_dylibloader_orig_pipewire +#define pw_client_info_update pw_client_info_update_dylibloader_orig_pipewire +#define pw_client_info_merge pw_client_info_merge_dylibloader_orig_pipewire +#define pw_client_info_free pw_client_info_free_dylibloader_orig_pipewire +#define pw_conf_load_conf_for_context pw_conf_load_conf_for_context_dylibloader_orig_pipewire +#define pw_conf_load_conf pw_conf_load_conf_dylibloader_orig_pipewire +#define pw_conf_load_state pw_conf_load_state_dylibloader_orig_pipewire +#define pw_conf_save_state pw_conf_save_state_dylibloader_orig_pipewire +#define pw_conf_section_update_props pw_conf_section_update_props_dylibloader_orig_pipewire +#define pw_conf_section_for_each pw_conf_section_for_each_dylibloader_orig_pipewire +#define pw_conf_match_rules pw_conf_match_rules_dylibloader_orig_pipewire +#define pw_conf_section_match_rules pw_conf_section_match_rules_dylibloader_orig_pipewire +#define pw_device_info_update pw_device_info_update_dylibloader_orig_pipewire +#define pw_device_info_merge pw_device_info_merge_dylibloader_orig_pipewire +#define pw_device_info_free pw_device_info_free_dylibloader_orig_pipewire +#define pw_mempool_new pw_mempool_new_dylibloader_orig_pipewire +#define pw_mempool_add_listener pw_mempool_add_listener_dylibloader_orig_pipewire +#define pw_mempool_clear pw_mempool_clear_dylibloader_orig_pipewire +#define pw_mempool_destroy pw_mempool_destroy_dylibloader_orig_pipewire +#define pw_mempool_alloc pw_mempool_alloc_dylibloader_orig_pipewire +#define pw_mempool_import_block pw_mempool_import_block_dylibloader_orig_pipewire +#define pw_mempool_import pw_mempool_import_dylibloader_orig_pipewire +#define pw_memblock_free pw_memblock_free_dylibloader_orig_pipewire +#define pw_mempool_remove_id pw_mempool_remove_id_dylibloader_orig_pipewire +#define pw_mempool_find_ptr pw_mempool_find_ptr_dylibloader_orig_pipewire +#define pw_mempool_find_id pw_mempool_find_id_dylibloader_orig_pipewire +#define pw_mempool_find_fd pw_mempool_find_fd_dylibloader_orig_pipewire +#define pw_memblock_map pw_memblock_map_dylibloader_orig_pipewire +#define pw_mempool_map_id pw_mempool_map_id_dylibloader_orig_pipewire +#define pw_mempool_import_map pw_mempool_import_map_dylibloader_orig_pipewire +#define pw_mempool_find_tag pw_mempool_find_tag_dylibloader_orig_pipewire +#define pw_memmap_free pw_memmap_free_dylibloader_orig_pipewire +#define pw_buffers_negotiate pw_buffers_negotiate_dylibloader_orig_pipewire +#define pw_buffers_clear pw_buffers_clear_dylibloader_orig_pipewire +#define pw_factory_info_update pw_factory_info_update_dylibloader_orig_pipewire +#define pw_factory_info_merge pw_factory_info_merge_dylibloader_orig_pipewire +#define pw_factory_info_free pw_factory_info_free_dylibloader_orig_pipewire +#define pw_log_set pw_log_set_dylibloader_orig_pipewire +#define pw_log_get pw_log_get_dylibloader_orig_pipewire +#define pw_log_set_level pw_log_set_level_dylibloader_orig_pipewire +#define pw_log_logt pw_log_logt_dylibloader_orig_pipewire +#define pw_log_logtv pw_log_logtv_dylibloader_orig_pipewire +#define pw_log_log pw_log_log_dylibloader_orig_pipewire +#define pw_log_logv pw_log_logv_dylibloader_orig_pipewire +#define pw_link_state_as_string pw_link_state_as_string_dylibloader_orig_pipewire +#define pw_link_info_update pw_link_info_update_dylibloader_orig_pipewire +#define pw_link_info_merge pw_link_info_merge_dylibloader_orig_pipewire +#define pw_link_info_free pw_link_info_free_dylibloader_orig_pipewire +#define pw_main_loop_new pw_main_loop_new_dylibloader_orig_pipewire +#define pw_main_loop_add_listener pw_main_loop_add_listener_dylibloader_orig_pipewire +#define pw_main_loop_get_loop pw_main_loop_get_loop_dylibloader_orig_pipewire +#define pw_main_loop_destroy pw_main_loop_destroy_dylibloader_orig_pipewire +#define pw_main_loop_run pw_main_loop_run_dylibloader_orig_pipewire +#define pw_main_loop_quit pw_main_loop_quit_dylibloader_orig_pipewire +#define pw_module_info_update pw_module_info_update_dylibloader_orig_pipewire +#define pw_module_info_merge pw_module_info_merge_dylibloader_orig_pipewire +#define pw_module_info_free pw_module_info_free_dylibloader_orig_pipewire +#define pw_node_state_as_string pw_node_state_as_string_dylibloader_orig_pipewire +#define pw_node_info_update pw_node_info_update_dylibloader_orig_pipewire +#define pw_node_info_merge pw_node_info_merge_dylibloader_orig_pipewire +#define pw_node_info_free pw_node_info_free_dylibloader_orig_pipewire +#define pw_direction_as_string pw_direction_as_string_dylibloader_orig_pipewire +#define pw_port_info_update pw_port_info_update_dylibloader_orig_pipewire +#define pw_port_info_merge pw_port_info_merge_dylibloader_orig_pipewire +#define pw_port_info_free pw_port_info_free_dylibloader_orig_pipewire +#define pw_stream_state_as_string pw_stream_state_as_string_dylibloader_orig_pipewire +#define pw_stream_new pw_stream_new_dylibloader_orig_pipewire +#define pw_stream_new_simple pw_stream_new_simple_dylibloader_orig_pipewire +#define pw_stream_destroy pw_stream_destroy_dylibloader_orig_pipewire +#define pw_stream_add_listener pw_stream_add_listener_dylibloader_orig_pipewire +#define pw_stream_get_state pw_stream_get_state_dylibloader_orig_pipewire +#define pw_stream_get_name pw_stream_get_name_dylibloader_orig_pipewire +#define pw_stream_get_core pw_stream_get_core_dylibloader_orig_pipewire +#define pw_stream_get_properties pw_stream_get_properties_dylibloader_orig_pipewire +#define pw_stream_update_properties pw_stream_update_properties_dylibloader_orig_pipewire +#define pw_stream_connect pw_stream_connect_dylibloader_orig_pipewire +#define pw_stream_get_node_id pw_stream_get_node_id_dylibloader_orig_pipewire +#define pw_stream_disconnect pw_stream_disconnect_dylibloader_orig_pipewire +#define pw_stream_set_error pw_stream_set_error_dylibloader_orig_pipewire +#define pw_stream_update_params pw_stream_update_params_dylibloader_orig_pipewire +#define pw_stream_set_param pw_stream_set_param_dylibloader_orig_pipewire +#define pw_stream_get_control pw_stream_get_control_dylibloader_orig_pipewire +#define pw_stream_set_control pw_stream_set_control_dylibloader_orig_pipewire +#define pw_stream_get_time_n pw_stream_get_time_n_dylibloader_orig_pipewire +#define pw_stream_get_time pw_stream_get_time_dylibloader_orig_pipewire +#define pw_stream_dequeue_buffer pw_stream_dequeue_buffer_dylibloader_orig_pipewire +#define pw_stream_queue_buffer pw_stream_queue_buffer_dylibloader_orig_pipewire +#define pw_stream_set_active pw_stream_set_active_dylibloader_orig_pipewire +#define pw_stream_flush pw_stream_flush_dylibloader_orig_pipewire +#define pw_stream_is_driving pw_stream_is_driving_dylibloader_orig_pipewire +#define pw_stream_trigger_process pw_stream_trigger_process_dylibloader_orig_pipewire +#define pw_filter_state_as_string pw_filter_state_as_string_dylibloader_orig_pipewire +#define pw_filter_new pw_filter_new_dylibloader_orig_pipewire +#define pw_filter_new_simple pw_filter_new_simple_dylibloader_orig_pipewire +#define pw_filter_destroy pw_filter_destroy_dylibloader_orig_pipewire +#define pw_filter_add_listener pw_filter_add_listener_dylibloader_orig_pipewire +#define pw_filter_get_state pw_filter_get_state_dylibloader_orig_pipewire +#define pw_filter_get_name pw_filter_get_name_dylibloader_orig_pipewire +#define pw_filter_get_core pw_filter_get_core_dylibloader_orig_pipewire +#define pw_filter_connect pw_filter_connect_dylibloader_orig_pipewire +#define pw_filter_get_node_id pw_filter_get_node_id_dylibloader_orig_pipewire +#define pw_filter_disconnect pw_filter_disconnect_dylibloader_orig_pipewire +#define pw_filter_add_port pw_filter_add_port_dylibloader_orig_pipewire +#define pw_filter_remove_port pw_filter_remove_port_dylibloader_orig_pipewire +#define pw_filter_get_properties pw_filter_get_properties_dylibloader_orig_pipewire +#define pw_filter_update_properties pw_filter_update_properties_dylibloader_orig_pipewire +#define pw_filter_set_error pw_filter_set_error_dylibloader_orig_pipewire +#define pw_filter_update_params pw_filter_update_params_dylibloader_orig_pipewire +#define pw_filter_get_time pw_filter_get_time_dylibloader_orig_pipewire +#define pw_filter_dequeue_buffer pw_filter_dequeue_buffer_dylibloader_orig_pipewire +#define pw_filter_queue_buffer pw_filter_queue_buffer_dylibloader_orig_pipewire +#define pw_filter_get_dsp_buffer pw_filter_get_dsp_buffer_dylibloader_orig_pipewire +#define pw_filter_set_active pw_filter_set_active_dylibloader_orig_pipewire +#define pw_filter_flush pw_filter_flush_dylibloader_orig_pipewire +#define pw_filter_is_driving pw_filter_is_driving_dylibloader_orig_pipewire +#define pw_filter_trigger_process pw_filter_trigger_process_dylibloader_orig_pipewire +#define pw_thread_loop_new pw_thread_loop_new_dylibloader_orig_pipewire +#define pw_thread_loop_new_full pw_thread_loop_new_full_dylibloader_orig_pipewire +#define pw_thread_loop_destroy pw_thread_loop_destroy_dylibloader_orig_pipewire +#define pw_thread_loop_add_listener pw_thread_loop_add_listener_dylibloader_orig_pipewire +#define pw_thread_loop_get_loop pw_thread_loop_get_loop_dylibloader_orig_pipewire +#define pw_thread_loop_start pw_thread_loop_start_dylibloader_orig_pipewire +#define pw_thread_loop_stop pw_thread_loop_stop_dylibloader_orig_pipewire +#define pw_thread_loop_lock pw_thread_loop_lock_dylibloader_orig_pipewire +#define pw_thread_loop_unlock pw_thread_loop_unlock_dylibloader_orig_pipewire +#define pw_thread_loop_wait pw_thread_loop_wait_dylibloader_orig_pipewire +#define pw_thread_loop_timed_wait pw_thread_loop_timed_wait_dylibloader_orig_pipewire +#define pw_thread_loop_get_time pw_thread_loop_get_time_dylibloader_orig_pipewire +#define pw_thread_loop_timed_wait_full pw_thread_loop_timed_wait_full_dylibloader_orig_pipewire +#define pw_thread_loop_signal pw_thread_loop_signal_dylibloader_orig_pipewire +#define pw_thread_loop_accept pw_thread_loop_accept_dylibloader_orig_pipewire +#define pw_thread_loop_in_thread pw_thread_loop_in_thread_dylibloader_orig_pipewire +#define pw_data_loop_new pw_data_loop_new_dylibloader_orig_pipewire +#define pw_data_loop_add_listener pw_data_loop_add_listener_dylibloader_orig_pipewire +#define pw_data_loop_wait pw_data_loop_wait_dylibloader_orig_pipewire +#define pw_data_loop_exit pw_data_loop_exit_dylibloader_orig_pipewire +#define pw_data_loop_get_loop pw_data_loop_get_loop_dylibloader_orig_pipewire +#define pw_data_loop_destroy pw_data_loop_destroy_dylibloader_orig_pipewire +#define pw_data_loop_start pw_data_loop_start_dylibloader_orig_pipewire +#define pw_data_loop_stop pw_data_loop_stop_dylibloader_orig_pipewire +#define pw_data_loop_in_thread pw_data_loop_in_thread_dylibloader_orig_pipewire +#define pw_data_loop_get_thread pw_data_loop_get_thread_dylibloader_orig_pipewire +#define pw_data_loop_invoke pw_data_loop_invoke_dylibloader_orig_pipewire +#define pw_data_loop_set_thread_utils pw_data_loop_set_thread_utils_dylibloader_orig_pipewire +#define pw_type_info pw_type_info_dylibloader_orig_pipewire +#define pw_get_library_version pw_get_library_version_dylibloader_orig_pipewire +#define pw_check_library_version pw_check_library_version_dylibloader_orig_pipewire +#define pw_init pw_init_dylibloader_orig_pipewire +#define pw_deinit pw_deinit_dylibloader_orig_pipewire +#define pw_debug_is_category_enabled pw_debug_is_category_enabled_dylibloader_orig_pipewire +#define pw_get_application_name pw_get_application_name_dylibloader_orig_pipewire +#define pw_get_prgname pw_get_prgname_dylibloader_orig_pipewire +#define pw_get_user_name pw_get_user_name_dylibloader_orig_pipewire +#define pw_get_host_name pw_get_host_name_dylibloader_orig_pipewire +#define pw_get_client_name pw_get_client_name_dylibloader_orig_pipewire +#define pw_check_option pw_check_option_dylibloader_orig_pipewire +#define pw_direction_reverse pw_direction_reverse_dylibloader_orig_pipewire +#define pw_set_domain pw_set_domain_dylibloader_orig_pipewire +#define pw_get_domain pw_get_domain_dylibloader_orig_pipewire +#define pw_get_support pw_get_support_dylibloader_orig_pipewire +#define pw_load_spa_handle pw_load_spa_handle_dylibloader_orig_pipewire +#define pw_unload_spa_handle pw_unload_spa_handle_dylibloader_orig_pipewire +#include "thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h" // IWYU pragma: export. +#undef pw_properties_new +#undef pw_properties_new_dict +#undef pw_properties_new_string +#undef pw_properties_copy +#undef pw_properties_update_keys +#undef pw_properties_update_ignore +#undef pw_properties_update +#undef pw_properties_update_string +#undef pw_properties_add +#undef pw_properties_add_keys +#undef pw_properties_clear +#undef pw_properties_free +#undef pw_properties_set +#undef pw_properties_setf +#undef pw_properties_setva +#undef pw_properties_get +#undef pw_properties_fetch_uint32 +#undef pw_properties_fetch_int32 +#undef pw_properties_fetch_uint64 +#undef pw_properties_fetch_int64 +#undef pw_properties_fetch_bool +#undef pw_properties_iterate +#undef pw_properties_serialize_dict +#undef pw_core_info_update +#undef pw_core_info_merge +#undef pw_core_info_free +#undef pw_context_connect +#undef pw_context_connect_fd +#undef pw_context_connect_self +#undef pw_core_steal_fd +#undef pw_core_set_paused +#undef pw_core_disconnect +#undef pw_core_get_user_data +#undef pw_core_get_client +#undef pw_core_get_context +#undef pw_core_get_properties +#undef pw_core_update_properties +#undef pw_core_get_mempool +#undef pw_core_find_proxy +#undef pw_core_export +#undef pw_loop_new +#undef pw_loop_destroy +#undef pw_context_new +#undef pw_context_destroy +#undef pw_context_get_user_data +#undef pw_context_add_listener +#undef pw_context_get_properties +#undef pw_context_update_properties +#undef pw_context_get_conf_section +#undef pw_context_parse_conf_section +#undef pw_context_conf_update_props +#undef pw_context_conf_section_for_each +#undef pw_context_conf_section_match_rules +#undef pw_context_get_support +#undef pw_context_get_main_loop +#undef pw_context_get_data_loop +#undef pw_context_get_work_queue +#undef pw_context_get_mempool +#undef pw_context_for_each_global +#undef pw_context_find_global +#undef pw_context_add_spa_lib +#undef pw_context_find_spa_lib +#undef pw_context_load_spa_handle +#undef pw_context_register_export_type +#undef pw_context_find_export_type +#undef pw_context_set_object +#undef pw_context_get_object +#undef pw_split_walk +#undef pw_split_strv +#undef pw_split_ip +#undef pw_strv_parse +#undef pw_strv_find +#undef pw_strv_find_common +#undef pw_free_strv +#undef pw_strip +#undef pw_getrandom +#undef pw_random +#undef pw_reallocarray +#undef pw_protocol_new +#undef pw_protocol_destroy +#undef pw_protocol_get_context +#undef pw_protocol_get_user_data +#undef pw_protocol_get_implementation +#undef pw_protocol_get_extension +#undef pw_protocol_add_listener +#undef pw_protocol_add_marshal +#undef pw_protocol_get_marshal +#undef pw_context_find_protocol +#undef pw_proxy_new +#undef pw_proxy_add_listener +#undef pw_proxy_add_object_listener +#undef pw_proxy_destroy +#undef pw_proxy_ref +#undef pw_proxy_unref +#undef pw_proxy_get_user_data +#undef pw_proxy_get_id +#undef pw_proxy_get_type +#undef pw_proxy_get_protocol +#undef pw_proxy_sync +#undef pw_proxy_set_bound_id +#undef pw_proxy_get_bound_id +#undef pw_proxy_error +#undef pw_proxy_errorf +#undef pw_proxy_get_object_listeners +#undef pw_proxy_get_marshal +#undef pw_proxy_install_marshal +#undef pw_client_info_update +#undef pw_client_info_merge +#undef pw_client_info_free +#undef pw_conf_load_conf_for_context +#undef pw_conf_load_conf +#undef pw_conf_load_state +#undef pw_conf_save_state +#undef pw_conf_section_update_props +#undef pw_conf_section_for_each +#undef pw_conf_match_rules +#undef pw_conf_section_match_rules +#undef pw_device_info_update +#undef pw_device_info_merge +#undef pw_device_info_free +#undef pw_mempool_new +#undef pw_mempool_add_listener +#undef pw_mempool_clear +#undef pw_mempool_destroy +#undef pw_mempool_alloc +#undef pw_mempool_import_block +#undef pw_mempool_import +#undef pw_memblock_free +#undef pw_mempool_remove_id +#undef pw_mempool_find_ptr +#undef pw_mempool_find_id +#undef pw_mempool_find_fd +#undef pw_memblock_map +#undef pw_mempool_map_id +#undef pw_mempool_import_map +#undef pw_mempool_find_tag +#undef pw_memmap_free +#undef pw_buffers_negotiate +#undef pw_buffers_clear +#undef pw_factory_info_update +#undef pw_factory_info_merge +#undef pw_factory_info_free +#undef pw_log_set +#undef pw_log_get +#undef pw_log_set_level +#undef pw_log_logt +#undef pw_log_logtv +#undef pw_log_log +#undef pw_log_logv +#undef pw_link_state_as_string +#undef pw_link_info_update +#undef pw_link_info_merge +#undef pw_link_info_free +#undef pw_main_loop_new +#undef pw_main_loop_add_listener +#undef pw_main_loop_get_loop +#undef pw_main_loop_destroy +#undef pw_main_loop_run +#undef pw_main_loop_quit +#undef pw_module_info_update +#undef pw_module_info_merge +#undef pw_module_info_free +#undef pw_node_state_as_string +#undef pw_node_info_update +#undef pw_node_info_merge +#undef pw_node_info_free +#undef pw_direction_as_string +#undef pw_port_info_update +#undef pw_port_info_merge +#undef pw_port_info_free +#undef pw_stream_state_as_string +#undef pw_stream_new +#undef pw_stream_new_simple +#undef pw_stream_destroy +#undef pw_stream_add_listener +#undef pw_stream_get_state +#undef pw_stream_get_name +#undef pw_stream_get_core +#undef pw_stream_get_properties +#undef pw_stream_update_properties +#undef pw_stream_connect +#undef pw_stream_get_node_id +#undef pw_stream_disconnect +#undef pw_stream_set_error +#undef pw_stream_update_params +#undef pw_stream_set_param +#undef pw_stream_get_control +#undef pw_stream_set_control +#undef pw_stream_get_time_n +#undef pw_stream_get_time +#undef pw_stream_dequeue_buffer +#undef pw_stream_queue_buffer +#undef pw_stream_set_active +#undef pw_stream_flush +#undef pw_stream_is_driving +#undef pw_stream_trigger_process +#undef pw_filter_state_as_string +#undef pw_filter_new +#undef pw_filter_new_simple +#undef pw_filter_destroy +#undef pw_filter_add_listener +#undef pw_filter_get_state +#undef pw_filter_get_name +#undef pw_filter_get_core +#undef pw_filter_connect +#undef pw_filter_get_node_id +#undef pw_filter_disconnect +#undef pw_filter_add_port +#undef pw_filter_remove_port +#undef pw_filter_get_properties +#undef pw_filter_update_properties +#undef pw_filter_set_error +#undef pw_filter_update_params +#undef pw_filter_get_time +#undef pw_filter_dequeue_buffer +#undef pw_filter_queue_buffer +#undef pw_filter_get_dsp_buffer +#undef pw_filter_set_active +#undef pw_filter_flush +#undef pw_filter_is_driving +#undef pw_filter_trigger_process +#undef pw_thread_loop_new +#undef pw_thread_loop_new_full +#undef pw_thread_loop_destroy +#undef pw_thread_loop_add_listener +#undef pw_thread_loop_get_loop +#undef pw_thread_loop_start +#undef pw_thread_loop_stop +#undef pw_thread_loop_lock +#undef pw_thread_loop_unlock +#undef pw_thread_loop_wait +#undef pw_thread_loop_timed_wait +#undef pw_thread_loop_get_time +#undef pw_thread_loop_timed_wait_full +#undef pw_thread_loop_signal +#undef pw_thread_loop_accept +#undef pw_thread_loop_in_thread +#undef pw_data_loop_new +#undef pw_data_loop_add_listener +#undef pw_data_loop_wait +#undef pw_data_loop_exit +#undef pw_data_loop_get_loop +#undef pw_data_loop_destroy +#undef pw_data_loop_start +#undef pw_data_loop_stop +#undef pw_data_loop_in_thread +#undef pw_data_loop_get_thread +#undef pw_data_loop_invoke +#undef pw_data_loop_set_thread_utils +#undef pw_type_info +#undef pw_get_library_version +#undef pw_check_library_version +#undef pw_init +#undef pw_deinit +#undef pw_debug_is_category_enabled +#undef pw_get_application_name +#undef pw_get_prgname +#undef pw_get_user_name +#undef pw_get_host_name +#undef pw_get_client_name +#undef pw_check_option +#undef pw_direction_reverse +#undef pw_set_domain +#undef pw_get_domain +#undef pw_get_support +#undef pw_load_spa_handle +#undef pw_unload_spa_handle +#ifdef __cplusplus +extern "C" { +#endif +#define pw_properties_new pw_properties_new_dylibloader_wrapper_pipewire +#define pw_properties_new_dict pw_properties_new_dict_dylibloader_wrapper_pipewire +#define pw_properties_new_string pw_properties_new_string_dylibloader_wrapper_pipewire +#define pw_properties_copy pw_properties_copy_dylibloader_wrapper_pipewire +#define pw_properties_update_keys pw_properties_update_keys_dylibloader_wrapper_pipewire +#define pw_properties_update_ignore pw_properties_update_ignore_dylibloader_wrapper_pipewire +#define pw_properties_update pw_properties_update_dylibloader_wrapper_pipewire +#define pw_properties_update_string pw_properties_update_string_dylibloader_wrapper_pipewire +#define pw_properties_add pw_properties_add_dylibloader_wrapper_pipewire +#define pw_properties_add_keys pw_properties_add_keys_dylibloader_wrapper_pipewire +#define pw_properties_clear pw_properties_clear_dylibloader_wrapper_pipewire +#define pw_properties_free pw_properties_free_dylibloader_wrapper_pipewire +#define pw_properties_set pw_properties_set_dylibloader_wrapper_pipewire +#define pw_properties_setf pw_properties_setf_dylibloader_wrapper_pipewire +#define pw_properties_setva pw_properties_setva_dylibloader_wrapper_pipewire +#define pw_properties_get pw_properties_get_dylibloader_wrapper_pipewire +#define pw_properties_fetch_uint32 pw_properties_fetch_uint32_dylibloader_wrapper_pipewire +#define pw_properties_fetch_int32 pw_properties_fetch_int32_dylibloader_wrapper_pipewire +#define pw_properties_fetch_uint64 pw_properties_fetch_uint64_dylibloader_wrapper_pipewire +#define pw_properties_fetch_int64 pw_properties_fetch_int64_dylibloader_wrapper_pipewire +#define pw_properties_fetch_bool pw_properties_fetch_bool_dylibloader_wrapper_pipewire +#define pw_properties_iterate pw_properties_iterate_dylibloader_wrapper_pipewire +#define pw_properties_serialize_dict pw_properties_serialize_dict_dylibloader_wrapper_pipewire +#define pw_core_info_update pw_core_info_update_dylibloader_wrapper_pipewire +#define pw_core_info_merge pw_core_info_merge_dylibloader_wrapper_pipewire +#define pw_core_info_free pw_core_info_free_dylibloader_wrapper_pipewire +#define pw_context_connect pw_context_connect_dylibloader_wrapper_pipewire +#define pw_context_connect_fd pw_context_connect_fd_dylibloader_wrapper_pipewire +#define pw_context_connect_self pw_context_connect_self_dylibloader_wrapper_pipewire +#define pw_core_steal_fd pw_core_steal_fd_dylibloader_wrapper_pipewire +#define pw_core_set_paused pw_core_set_paused_dylibloader_wrapper_pipewire +#define pw_core_disconnect pw_core_disconnect_dylibloader_wrapper_pipewire +#define pw_core_get_user_data pw_core_get_user_data_dylibloader_wrapper_pipewire +#define pw_core_get_client pw_core_get_client_dylibloader_wrapper_pipewire +#define pw_core_get_context pw_core_get_context_dylibloader_wrapper_pipewire +#define pw_core_get_properties pw_core_get_properties_dylibloader_wrapper_pipewire +#define pw_core_update_properties pw_core_update_properties_dylibloader_wrapper_pipewire +#define pw_core_get_mempool pw_core_get_mempool_dylibloader_wrapper_pipewire +#define pw_core_find_proxy pw_core_find_proxy_dylibloader_wrapper_pipewire +#define pw_core_export pw_core_export_dylibloader_wrapper_pipewire +#define pw_loop_new pw_loop_new_dylibloader_wrapper_pipewire +#define pw_loop_destroy pw_loop_destroy_dylibloader_wrapper_pipewire +#define pw_context_new pw_context_new_dylibloader_wrapper_pipewire +#define pw_context_destroy pw_context_destroy_dylibloader_wrapper_pipewire +#define pw_context_get_user_data pw_context_get_user_data_dylibloader_wrapper_pipewire +#define pw_context_add_listener pw_context_add_listener_dylibloader_wrapper_pipewire +#define pw_context_get_properties pw_context_get_properties_dylibloader_wrapper_pipewire +#define pw_context_update_properties pw_context_update_properties_dylibloader_wrapper_pipewire +#define pw_context_get_conf_section pw_context_get_conf_section_dylibloader_wrapper_pipewire +#define pw_context_parse_conf_section pw_context_parse_conf_section_dylibloader_wrapper_pipewire +#define pw_context_conf_update_props pw_context_conf_update_props_dylibloader_wrapper_pipewire +#define pw_context_conf_section_for_each pw_context_conf_section_for_each_dylibloader_wrapper_pipewire +#define pw_context_conf_section_match_rules pw_context_conf_section_match_rules_dylibloader_wrapper_pipewire +#define pw_context_get_support pw_context_get_support_dylibloader_wrapper_pipewire +#define pw_context_get_main_loop pw_context_get_main_loop_dylibloader_wrapper_pipewire +#define pw_context_get_data_loop pw_context_get_data_loop_dylibloader_wrapper_pipewire +#define pw_context_get_work_queue pw_context_get_work_queue_dylibloader_wrapper_pipewire +#define pw_context_get_mempool pw_context_get_mempool_dylibloader_wrapper_pipewire +#define pw_context_for_each_global pw_context_for_each_global_dylibloader_wrapper_pipewire +#define pw_context_find_global pw_context_find_global_dylibloader_wrapper_pipewire +#define pw_context_add_spa_lib pw_context_add_spa_lib_dylibloader_wrapper_pipewire +#define pw_context_find_spa_lib pw_context_find_spa_lib_dylibloader_wrapper_pipewire +#define pw_context_load_spa_handle pw_context_load_spa_handle_dylibloader_wrapper_pipewire +#define pw_context_register_export_type pw_context_register_export_type_dylibloader_wrapper_pipewire +#define pw_context_find_export_type pw_context_find_export_type_dylibloader_wrapper_pipewire +#define pw_context_set_object pw_context_set_object_dylibloader_wrapper_pipewire +#define pw_context_get_object pw_context_get_object_dylibloader_wrapper_pipewire +#define pw_split_walk pw_split_walk_dylibloader_wrapper_pipewire +#define pw_split_strv pw_split_strv_dylibloader_wrapper_pipewire +#define pw_split_ip pw_split_ip_dylibloader_wrapper_pipewire +#define pw_strv_parse pw_strv_parse_dylibloader_wrapper_pipewire +#define pw_strv_find pw_strv_find_dylibloader_wrapper_pipewire +#define pw_strv_find_common pw_strv_find_common_dylibloader_wrapper_pipewire +#define pw_free_strv pw_free_strv_dylibloader_wrapper_pipewire +#define pw_strip pw_strip_dylibloader_wrapper_pipewire +#define pw_getrandom pw_getrandom_dylibloader_wrapper_pipewire +#define pw_random pw_random_dylibloader_wrapper_pipewire +#define pw_reallocarray pw_reallocarray_dylibloader_wrapper_pipewire +#define pw_protocol_new pw_protocol_new_dylibloader_wrapper_pipewire +#define pw_protocol_destroy pw_protocol_destroy_dylibloader_wrapper_pipewire +#define pw_protocol_get_context pw_protocol_get_context_dylibloader_wrapper_pipewire +#define pw_protocol_get_user_data pw_protocol_get_user_data_dylibloader_wrapper_pipewire +#define pw_protocol_get_implementation pw_protocol_get_implementation_dylibloader_wrapper_pipewire +#define pw_protocol_get_extension pw_protocol_get_extension_dylibloader_wrapper_pipewire +#define pw_protocol_add_listener pw_protocol_add_listener_dylibloader_wrapper_pipewire +#define pw_protocol_add_marshal pw_protocol_add_marshal_dylibloader_wrapper_pipewire +#define pw_protocol_get_marshal pw_protocol_get_marshal_dylibloader_wrapper_pipewire +#define pw_context_find_protocol pw_context_find_protocol_dylibloader_wrapper_pipewire +#define pw_proxy_new pw_proxy_new_dylibloader_wrapper_pipewire +#define pw_proxy_add_listener pw_proxy_add_listener_dylibloader_wrapper_pipewire +#define pw_proxy_add_object_listener pw_proxy_add_object_listener_dylibloader_wrapper_pipewire +#define pw_proxy_destroy pw_proxy_destroy_dylibloader_wrapper_pipewire +#define pw_proxy_ref pw_proxy_ref_dylibloader_wrapper_pipewire +#define pw_proxy_unref pw_proxy_unref_dylibloader_wrapper_pipewire +#define pw_proxy_get_user_data pw_proxy_get_user_data_dylibloader_wrapper_pipewire +#define pw_proxy_get_id pw_proxy_get_id_dylibloader_wrapper_pipewire +#define pw_proxy_get_type pw_proxy_get_type_dylibloader_wrapper_pipewire +#define pw_proxy_get_protocol pw_proxy_get_protocol_dylibloader_wrapper_pipewire +#define pw_proxy_sync pw_proxy_sync_dylibloader_wrapper_pipewire +#define pw_proxy_set_bound_id pw_proxy_set_bound_id_dylibloader_wrapper_pipewire +#define pw_proxy_get_bound_id pw_proxy_get_bound_id_dylibloader_wrapper_pipewire +#define pw_proxy_error pw_proxy_error_dylibloader_wrapper_pipewire +#define pw_proxy_errorf pw_proxy_errorf_dylibloader_wrapper_pipewire +#define pw_proxy_get_object_listeners pw_proxy_get_object_listeners_dylibloader_wrapper_pipewire +#define pw_proxy_get_marshal pw_proxy_get_marshal_dylibloader_wrapper_pipewire +#define pw_proxy_install_marshal pw_proxy_install_marshal_dylibloader_wrapper_pipewire +#define pw_client_info_update pw_client_info_update_dylibloader_wrapper_pipewire +#define pw_client_info_merge pw_client_info_merge_dylibloader_wrapper_pipewire +#define pw_client_info_free pw_client_info_free_dylibloader_wrapper_pipewire +#define pw_conf_load_conf_for_context pw_conf_load_conf_for_context_dylibloader_wrapper_pipewire +#define pw_conf_load_conf pw_conf_load_conf_dylibloader_wrapper_pipewire +#define pw_conf_load_state pw_conf_load_state_dylibloader_wrapper_pipewire +#define pw_conf_save_state pw_conf_save_state_dylibloader_wrapper_pipewire +#define pw_conf_section_update_props pw_conf_section_update_props_dylibloader_wrapper_pipewire +#define pw_conf_section_for_each pw_conf_section_for_each_dylibloader_wrapper_pipewire +#define pw_conf_match_rules pw_conf_match_rules_dylibloader_wrapper_pipewire +#define pw_conf_section_match_rules pw_conf_section_match_rules_dylibloader_wrapper_pipewire +#define pw_device_info_update pw_device_info_update_dylibloader_wrapper_pipewire +#define pw_device_info_merge pw_device_info_merge_dylibloader_wrapper_pipewire +#define pw_device_info_free pw_device_info_free_dylibloader_wrapper_pipewire +#define pw_mempool_new pw_mempool_new_dylibloader_wrapper_pipewire +#define pw_mempool_add_listener pw_mempool_add_listener_dylibloader_wrapper_pipewire +#define pw_mempool_clear pw_mempool_clear_dylibloader_wrapper_pipewire +#define pw_mempool_destroy pw_mempool_destroy_dylibloader_wrapper_pipewire +#define pw_mempool_alloc pw_mempool_alloc_dylibloader_wrapper_pipewire +#define pw_mempool_import_block pw_mempool_import_block_dylibloader_wrapper_pipewire +#define pw_mempool_import pw_mempool_import_dylibloader_wrapper_pipewire +#define pw_memblock_free pw_memblock_free_dylibloader_wrapper_pipewire +#define pw_mempool_remove_id pw_mempool_remove_id_dylibloader_wrapper_pipewire +#define pw_mempool_find_ptr pw_mempool_find_ptr_dylibloader_wrapper_pipewire +#define pw_mempool_find_id pw_mempool_find_id_dylibloader_wrapper_pipewire +#define pw_mempool_find_fd pw_mempool_find_fd_dylibloader_wrapper_pipewire +#define pw_memblock_map pw_memblock_map_dylibloader_wrapper_pipewire +#define pw_mempool_map_id pw_mempool_map_id_dylibloader_wrapper_pipewire +#define pw_mempool_import_map pw_mempool_import_map_dylibloader_wrapper_pipewire +#define pw_mempool_find_tag pw_mempool_find_tag_dylibloader_wrapper_pipewire +#define pw_memmap_free pw_memmap_free_dylibloader_wrapper_pipewire +#define pw_buffers_negotiate pw_buffers_negotiate_dylibloader_wrapper_pipewire +#define pw_buffers_clear pw_buffers_clear_dylibloader_wrapper_pipewire +#define pw_factory_info_update pw_factory_info_update_dylibloader_wrapper_pipewire +#define pw_factory_info_merge pw_factory_info_merge_dylibloader_wrapper_pipewire +#define pw_factory_info_free pw_factory_info_free_dylibloader_wrapper_pipewire +#define pw_log_set pw_log_set_dylibloader_wrapper_pipewire +#define pw_log_get pw_log_get_dylibloader_wrapper_pipewire +#define pw_log_set_level pw_log_set_level_dylibloader_wrapper_pipewire +#define pw_log_logt pw_log_logt_dylibloader_wrapper_pipewire +#define pw_log_logtv pw_log_logtv_dylibloader_wrapper_pipewire +#define pw_log_log pw_log_log_dylibloader_wrapper_pipewire +#define pw_log_logv pw_log_logv_dylibloader_wrapper_pipewire +#define pw_link_state_as_string pw_link_state_as_string_dylibloader_wrapper_pipewire +#define pw_link_info_update pw_link_info_update_dylibloader_wrapper_pipewire +#define pw_link_info_merge pw_link_info_merge_dylibloader_wrapper_pipewire +#define pw_link_info_free pw_link_info_free_dylibloader_wrapper_pipewire +#define pw_main_loop_new pw_main_loop_new_dylibloader_wrapper_pipewire +#define pw_main_loop_add_listener pw_main_loop_add_listener_dylibloader_wrapper_pipewire +#define pw_main_loop_get_loop pw_main_loop_get_loop_dylibloader_wrapper_pipewire +#define pw_main_loop_destroy pw_main_loop_destroy_dylibloader_wrapper_pipewire +#define pw_main_loop_run pw_main_loop_run_dylibloader_wrapper_pipewire +#define pw_main_loop_quit pw_main_loop_quit_dylibloader_wrapper_pipewire +#define pw_module_info_update pw_module_info_update_dylibloader_wrapper_pipewire +#define pw_module_info_merge pw_module_info_merge_dylibloader_wrapper_pipewire +#define pw_module_info_free pw_module_info_free_dylibloader_wrapper_pipewire +#define pw_node_state_as_string pw_node_state_as_string_dylibloader_wrapper_pipewire +#define pw_node_info_update pw_node_info_update_dylibloader_wrapper_pipewire +#define pw_node_info_merge pw_node_info_merge_dylibloader_wrapper_pipewire +#define pw_node_info_free pw_node_info_free_dylibloader_wrapper_pipewire +#define pw_direction_as_string pw_direction_as_string_dylibloader_wrapper_pipewire +#define pw_port_info_update pw_port_info_update_dylibloader_wrapper_pipewire +#define pw_port_info_merge pw_port_info_merge_dylibloader_wrapper_pipewire +#define pw_port_info_free pw_port_info_free_dylibloader_wrapper_pipewire +#define pw_stream_state_as_string pw_stream_state_as_string_dylibloader_wrapper_pipewire +#define pw_stream_new pw_stream_new_dylibloader_wrapper_pipewire +#define pw_stream_new_simple pw_stream_new_simple_dylibloader_wrapper_pipewire +#define pw_stream_destroy pw_stream_destroy_dylibloader_wrapper_pipewire +#define pw_stream_add_listener pw_stream_add_listener_dylibloader_wrapper_pipewire +#define pw_stream_get_state pw_stream_get_state_dylibloader_wrapper_pipewire +#define pw_stream_get_name pw_stream_get_name_dylibloader_wrapper_pipewire +#define pw_stream_get_core pw_stream_get_core_dylibloader_wrapper_pipewire +#define pw_stream_get_properties pw_stream_get_properties_dylibloader_wrapper_pipewire +#define pw_stream_update_properties pw_stream_update_properties_dylibloader_wrapper_pipewire +#define pw_stream_connect pw_stream_connect_dylibloader_wrapper_pipewire +#define pw_stream_get_node_id pw_stream_get_node_id_dylibloader_wrapper_pipewire +#define pw_stream_disconnect pw_stream_disconnect_dylibloader_wrapper_pipewire +#define pw_stream_set_error pw_stream_set_error_dylibloader_wrapper_pipewire +#define pw_stream_update_params pw_stream_update_params_dylibloader_wrapper_pipewire +#define pw_stream_set_param pw_stream_set_param_dylibloader_wrapper_pipewire +#define pw_stream_get_control pw_stream_get_control_dylibloader_wrapper_pipewire +#define pw_stream_set_control pw_stream_set_control_dylibloader_wrapper_pipewire +#define pw_stream_get_time_n pw_stream_get_time_n_dylibloader_wrapper_pipewire +#define pw_stream_get_time pw_stream_get_time_dylibloader_wrapper_pipewire +#define pw_stream_dequeue_buffer pw_stream_dequeue_buffer_dylibloader_wrapper_pipewire +#define pw_stream_queue_buffer pw_stream_queue_buffer_dylibloader_wrapper_pipewire +#define pw_stream_set_active pw_stream_set_active_dylibloader_wrapper_pipewire +#define pw_stream_flush pw_stream_flush_dylibloader_wrapper_pipewire +#define pw_stream_is_driving pw_stream_is_driving_dylibloader_wrapper_pipewire +#define pw_stream_trigger_process pw_stream_trigger_process_dylibloader_wrapper_pipewire +#define pw_filter_state_as_string pw_filter_state_as_string_dylibloader_wrapper_pipewire +#define pw_filter_new pw_filter_new_dylibloader_wrapper_pipewire +#define pw_filter_new_simple pw_filter_new_simple_dylibloader_wrapper_pipewire +#define pw_filter_destroy pw_filter_destroy_dylibloader_wrapper_pipewire +#define pw_filter_add_listener pw_filter_add_listener_dylibloader_wrapper_pipewire +#define pw_filter_get_state pw_filter_get_state_dylibloader_wrapper_pipewire +#define pw_filter_get_name pw_filter_get_name_dylibloader_wrapper_pipewire +#define pw_filter_get_core pw_filter_get_core_dylibloader_wrapper_pipewire +#define pw_filter_connect pw_filter_connect_dylibloader_wrapper_pipewire +#define pw_filter_get_node_id pw_filter_get_node_id_dylibloader_wrapper_pipewire +#define pw_filter_disconnect pw_filter_disconnect_dylibloader_wrapper_pipewire +#define pw_filter_add_port pw_filter_add_port_dylibloader_wrapper_pipewire +#define pw_filter_remove_port pw_filter_remove_port_dylibloader_wrapper_pipewire +#define pw_filter_get_properties pw_filter_get_properties_dylibloader_wrapper_pipewire +#define pw_filter_update_properties pw_filter_update_properties_dylibloader_wrapper_pipewire +#define pw_filter_set_error pw_filter_set_error_dylibloader_wrapper_pipewire +#define pw_filter_update_params pw_filter_update_params_dylibloader_wrapper_pipewire +#define pw_filter_get_time pw_filter_get_time_dylibloader_wrapper_pipewire +#define pw_filter_dequeue_buffer pw_filter_dequeue_buffer_dylibloader_wrapper_pipewire +#define pw_filter_queue_buffer pw_filter_queue_buffer_dylibloader_wrapper_pipewire +#define pw_filter_get_dsp_buffer pw_filter_get_dsp_buffer_dylibloader_wrapper_pipewire +#define pw_filter_set_active pw_filter_set_active_dylibloader_wrapper_pipewire +#define pw_filter_flush pw_filter_flush_dylibloader_wrapper_pipewire +#define pw_filter_is_driving pw_filter_is_driving_dylibloader_wrapper_pipewire +#define pw_filter_trigger_process pw_filter_trigger_process_dylibloader_wrapper_pipewire +#define pw_thread_loop_new pw_thread_loop_new_dylibloader_wrapper_pipewire +#define pw_thread_loop_new_full pw_thread_loop_new_full_dylibloader_wrapper_pipewire +#define pw_thread_loop_destroy pw_thread_loop_destroy_dylibloader_wrapper_pipewire +#define pw_thread_loop_add_listener pw_thread_loop_add_listener_dylibloader_wrapper_pipewire +#define pw_thread_loop_get_loop pw_thread_loop_get_loop_dylibloader_wrapper_pipewire +#define pw_thread_loop_start pw_thread_loop_start_dylibloader_wrapper_pipewire +#define pw_thread_loop_stop pw_thread_loop_stop_dylibloader_wrapper_pipewire +#define pw_thread_loop_lock pw_thread_loop_lock_dylibloader_wrapper_pipewire +#define pw_thread_loop_unlock pw_thread_loop_unlock_dylibloader_wrapper_pipewire +#define pw_thread_loop_wait pw_thread_loop_wait_dylibloader_wrapper_pipewire +#define pw_thread_loop_timed_wait pw_thread_loop_timed_wait_dylibloader_wrapper_pipewire +#define pw_thread_loop_get_time pw_thread_loop_get_time_dylibloader_wrapper_pipewire +#define pw_thread_loop_timed_wait_full pw_thread_loop_timed_wait_full_dylibloader_wrapper_pipewire +#define pw_thread_loop_signal pw_thread_loop_signal_dylibloader_wrapper_pipewire +#define pw_thread_loop_accept pw_thread_loop_accept_dylibloader_wrapper_pipewire +#define pw_thread_loop_in_thread pw_thread_loop_in_thread_dylibloader_wrapper_pipewire +#define pw_data_loop_new pw_data_loop_new_dylibloader_wrapper_pipewire +#define pw_data_loop_add_listener pw_data_loop_add_listener_dylibloader_wrapper_pipewire +#define pw_data_loop_wait pw_data_loop_wait_dylibloader_wrapper_pipewire +#define pw_data_loop_exit pw_data_loop_exit_dylibloader_wrapper_pipewire +#define pw_data_loop_get_loop pw_data_loop_get_loop_dylibloader_wrapper_pipewire +#define pw_data_loop_destroy pw_data_loop_destroy_dylibloader_wrapper_pipewire +#define pw_data_loop_start pw_data_loop_start_dylibloader_wrapper_pipewire +#define pw_data_loop_stop pw_data_loop_stop_dylibloader_wrapper_pipewire +#define pw_data_loop_in_thread pw_data_loop_in_thread_dylibloader_wrapper_pipewire +#define pw_data_loop_get_thread pw_data_loop_get_thread_dylibloader_wrapper_pipewire +#define pw_data_loop_invoke pw_data_loop_invoke_dylibloader_wrapper_pipewire +#define pw_data_loop_set_thread_utils pw_data_loop_set_thread_utils_dylibloader_wrapper_pipewire +#define pw_type_info pw_type_info_dylibloader_wrapper_pipewire +#define pw_get_library_version pw_get_library_version_dylibloader_wrapper_pipewire +#define pw_check_library_version pw_check_library_version_dylibloader_wrapper_pipewire +#define pw_init pw_init_dylibloader_wrapper_pipewire +#define pw_deinit pw_deinit_dylibloader_wrapper_pipewire +#define pw_debug_is_category_enabled pw_debug_is_category_enabled_dylibloader_wrapper_pipewire +#define pw_get_application_name pw_get_application_name_dylibloader_wrapper_pipewire +#define pw_get_prgname pw_get_prgname_dylibloader_wrapper_pipewire +#define pw_get_user_name pw_get_user_name_dylibloader_wrapper_pipewire +#define pw_get_host_name pw_get_host_name_dylibloader_wrapper_pipewire +#define pw_get_client_name pw_get_client_name_dylibloader_wrapper_pipewire +#define pw_check_option pw_check_option_dylibloader_wrapper_pipewire +#define pw_direction_reverse pw_direction_reverse_dylibloader_wrapper_pipewire +#define pw_set_domain pw_set_domain_dylibloader_wrapper_pipewire +#define pw_get_domain pw_get_domain_dylibloader_wrapper_pipewire +#define pw_get_support pw_get_support_dylibloader_wrapper_pipewire +#define pw_load_spa_handle pw_load_spa_handle_dylibloader_wrapper_pipewire +#define pw_unload_spa_handle pw_unload_spa_handle_dylibloader_wrapper_pipewire +extern struct pw_properties *(*pw_properties_new_dylibloader_wrapper_pipewire)(const char *, ...); +extern struct pw_properties *(*pw_properties_new_dict_dylibloader_wrapper_pipewire)(const struct spa_dict *); +extern struct pw_properties *(*pw_properties_new_string_dylibloader_wrapper_pipewire)(const char *); +extern struct pw_properties *(*pw_properties_copy_dylibloader_wrapper_pipewire)(const struct pw_properties *); +extern int (*pw_properties_update_keys_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *, const char * const []); +extern int (*pw_properties_update_ignore_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *, const char * const []); +extern int (*pw_properties_update_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *); +extern int (*pw_properties_update_string_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, size_t); +extern int (*pw_properties_add_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *); +extern int (*pw_properties_add_keys_dylibloader_wrapper_pipewire)(struct pw_properties *, const struct spa_dict *, const char * const []); +extern void (*pw_properties_clear_dylibloader_wrapper_pipewire)(struct pw_properties *); +extern void (*pw_properties_free_dylibloader_wrapper_pipewire)(struct pw_properties *); +extern int (*pw_properties_set_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, const char *); +extern int (*pw_properties_setf_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, const char *, ...); +extern int (*pw_properties_setva_dylibloader_wrapper_pipewire)(struct pw_properties *, const char *, const char *, va_list); +extern const char *(*pw_properties_get_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *); +extern int (*pw_properties_fetch_uint32_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, uint32_t *); +extern int (*pw_properties_fetch_int32_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, int32_t *); +extern int (*pw_properties_fetch_uint64_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, uint64_t *); +extern int (*pw_properties_fetch_int64_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, int64_t *); +extern int (*pw_properties_fetch_bool_dylibloader_wrapper_pipewire)(const struct pw_properties *, const char *, bool *); +extern const char *(*pw_properties_iterate_dylibloader_wrapper_pipewire)(const struct pw_properties *, void **); +extern int (*pw_properties_serialize_dict_dylibloader_wrapper_pipewire)(FILE *, const struct spa_dict *, uint32_t); +extern struct pw_core_info *(*pw_core_info_update_dylibloader_wrapper_pipewire)(struct pw_core_info *, const struct pw_core_info *); +extern struct pw_core_info *(*pw_core_info_merge_dylibloader_wrapper_pipewire)(struct pw_core_info *, const struct pw_core_info *, bool); +extern void (*pw_core_info_free_dylibloader_wrapper_pipewire)(struct pw_core_info *); +extern struct pw_core *(*pw_context_connect_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_properties *, size_t); +extern struct pw_core *(*pw_context_connect_fd_dylibloader_wrapper_pipewire)(struct pw_context *, int, struct pw_properties *, size_t); +extern struct pw_core *(*pw_context_connect_self_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_properties *, size_t); +extern int (*pw_core_steal_fd_dylibloader_wrapper_pipewire)(struct pw_core *); +extern int (*pw_core_set_paused_dylibloader_wrapper_pipewire)(struct pw_core *, bool); +extern int (*pw_core_disconnect_dylibloader_wrapper_pipewire)(struct pw_core *); +extern void *(*pw_core_get_user_data_dylibloader_wrapper_pipewire)(struct pw_core *); +extern struct pw_client *(*pw_core_get_client_dylibloader_wrapper_pipewire)(struct pw_core *); +extern struct pw_context *(*pw_core_get_context_dylibloader_wrapper_pipewire)(struct pw_core *); +extern const struct pw_properties *(*pw_core_get_properties_dylibloader_wrapper_pipewire)(struct pw_core *); +extern int (*pw_core_update_properties_dylibloader_wrapper_pipewire)(struct pw_core *, const struct spa_dict *); +extern struct pw_mempool *(*pw_core_get_mempool_dylibloader_wrapper_pipewire)(struct pw_core *); +extern struct pw_proxy *(*pw_core_find_proxy_dylibloader_wrapper_pipewire)(struct pw_core *, uint32_t); +extern struct pw_proxy *(*pw_core_export_dylibloader_wrapper_pipewire)(struct pw_core *, const char *, const struct spa_dict *, void *, size_t); +extern struct pw_loop *(*pw_loop_new_dylibloader_wrapper_pipewire)(const struct spa_dict *); +extern void (*pw_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_loop *); +extern struct pw_context *(*pw_context_new_dylibloader_wrapper_pipewire)(struct pw_loop *, struct pw_properties *, size_t); +extern void (*pw_context_destroy_dylibloader_wrapper_pipewire)(struct pw_context *); +extern void *(*pw_context_get_user_data_dylibloader_wrapper_pipewire)(struct pw_context *); +extern void (*pw_context_add_listener_dylibloader_wrapper_pipewire)(struct pw_context *, struct spa_hook *, const struct pw_context_events *, void *); +extern const struct pw_properties *(*pw_context_get_properties_dylibloader_wrapper_pipewire)(struct pw_context *); +extern int (*pw_context_update_properties_dylibloader_wrapper_pipewire)(struct pw_context *, const struct spa_dict *); +extern const char *(*pw_context_get_conf_section_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +extern int (*pw_context_parse_conf_section_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_properties *, const char *); +extern int (*pw_context_conf_update_props_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, struct pw_properties *); +extern int (*pw_context_conf_section_for_each_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, int (*)(void *data, const char *location, const char *section, const char *str, size_t len), void *); +extern int (*pw_context_conf_section_match_rules_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, const struct spa_dict *, int (*)(void *data, const char *location, const char *action, const char *str, size_t len), void *); +extern const struct spa_support *(*pw_context_get_support_dylibloader_wrapper_pipewire)(struct pw_context *, uint32_t *); +extern struct pw_loop *(*pw_context_get_main_loop_dylibloader_wrapper_pipewire)(struct pw_context *); +extern struct pw_data_loop *(*pw_context_get_data_loop_dylibloader_wrapper_pipewire)(struct pw_context *); +extern struct pw_work_queue *(*pw_context_get_work_queue_dylibloader_wrapper_pipewire)(struct pw_context *); +extern struct pw_mempool *(*pw_context_get_mempool_dylibloader_wrapper_pipewire)(struct pw_context *); +extern int (*pw_context_for_each_global_dylibloader_wrapper_pipewire)(struct pw_context *, int (*)(void *data, struct pw_global *global), void *); +extern struct pw_global *(*pw_context_find_global_dylibloader_wrapper_pipewire)(struct pw_context *, uint32_t); +extern int (*pw_context_add_spa_lib_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, const char *); +extern const char *(*pw_context_find_spa_lib_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +extern struct spa_handle *(*pw_context_load_spa_handle_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, const struct spa_dict *); +extern int (*pw_context_register_export_type_dylibloader_wrapper_pipewire)(struct pw_context *, struct pw_export_type *); +extern const struct pw_export_type *(*pw_context_find_export_type_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +extern int (*pw_context_set_object_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, void *); +extern void *(*pw_context_get_object_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +extern const char *(*pw_split_walk_dylibloader_wrapper_pipewire)(const char *, const char *, size_t *, const char **); +extern char **(*pw_split_strv_dylibloader_wrapper_pipewire)(const char *, const char *, int, int *); +extern int (*pw_split_ip_dylibloader_wrapper_pipewire)(char *, const char *, int, char *[]); +extern char **(*pw_strv_parse_dylibloader_wrapper_pipewire)(const char *, size_t, int, int *); +extern int (*pw_strv_find_dylibloader_wrapper_pipewire)(char **, const char *); +extern int (*pw_strv_find_common_dylibloader_wrapper_pipewire)(char **, char **); +extern void (*pw_free_strv_dylibloader_wrapper_pipewire)(char **); +extern char *(*pw_strip_dylibloader_wrapper_pipewire)(char *, const char *); +extern ssize_t (*pw_getrandom_dylibloader_wrapper_pipewire)(void *, size_t, unsigned int); +extern void (*pw_random_dylibloader_wrapper_pipewire)(void *, size_t); +extern void *(*pw_reallocarray_dylibloader_wrapper_pipewire)(void *, size_t, size_t); +extern struct pw_protocol *(*pw_protocol_new_dylibloader_wrapper_pipewire)(struct pw_context *, const char *, size_t); +extern void (*pw_protocol_destroy_dylibloader_wrapper_pipewire)(struct pw_protocol *); +extern struct pw_context *(*pw_protocol_get_context_dylibloader_wrapper_pipewire)(struct pw_protocol *); +extern void *(*pw_protocol_get_user_data_dylibloader_wrapper_pipewire)(struct pw_protocol *); +extern const struct pw_protocol_implementation *(*pw_protocol_get_implementation_dylibloader_wrapper_pipewire)(struct pw_protocol *); +extern const void *(*pw_protocol_get_extension_dylibloader_wrapper_pipewire)(struct pw_protocol *); +extern void (*pw_protocol_add_listener_dylibloader_wrapper_pipewire)(struct pw_protocol *, struct spa_hook *, const struct pw_protocol_events *, void *); +extern int (*pw_protocol_add_marshal_dylibloader_wrapper_pipewire)(struct pw_protocol *, const struct pw_protocol_marshal *); +extern const struct pw_protocol_marshal *(*pw_protocol_get_marshal_dylibloader_wrapper_pipewire)(struct pw_protocol *, const char *, uint32_t, uint32_t); +extern struct pw_protocol *(*pw_context_find_protocol_dylibloader_wrapper_pipewire)(struct pw_context *, const char *); +extern struct pw_proxy *(*pw_proxy_new_dylibloader_wrapper_pipewire)(struct pw_proxy *, const char *, uint32_t, size_t); +extern void (*pw_proxy_add_listener_dylibloader_wrapper_pipewire)(struct pw_proxy *, struct spa_hook *, const struct pw_proxy_events *, void *); +extern void (*pw_proxy_add_object_listener_dylibloader_wrapper_pipewire)(struct pw_proxy *, struct spa_hook *, const void *, void *); +extern void (*pw_proxy_destroy_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern void (*pw_proxy_ref_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern void (*pw_proxy_unref_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern void *(*pw_proxy_get_user_data_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern uint32_t (*pw_proxy_get_id_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern const char *(*pw_proxy_get_type_dylibloader_wrapper_pipewire)(struct pw_proxy *, uint32_t *); +extern struct pw_protocol *(*pw_proxy_get_protocol_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern int (*pw_proxy_sync_dylibloader_wrapper_pipewire)(struct pw_proxy *, int); +extern int (*pw_proxy_set_bound_id_dylibloader_wrapper_pipewire)(struct pw_proxy *, uint32_t); +extern uint32_t (*pw_proxy_get_bound_id_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern int (*pw_proxy_error_dylibloader_wrapper_pipewire)(struct pw_proxy *, int, const char *); +extern int (*pw_proxy_errorf_dylibloader_wrapper_pipewire)(struct pw_proxy *, int, const char *, ...); +extern struct spa_hook_list *(*pw_proxy_get_object_listeners_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern const struct pw_protocol_marshal *(*pw_proxy_get_marshal_dylibloader_wrapper_pipewire)(struct pw_proxy *); +extern int (*pw_proxy_install_marshal_dylibloader_wrapper_pipewire)(struct pw_proxy *, bool); +extern struct pw_client_info *(*pw_client_info_update_dylibloader_wrapper_pipewire)(struct pw_client_info *, const struct pw_client_info *); +extern struct pw_client_info *(*pw_client_info_merge_dylibloader_wrapper_pipewire)(struct pw_client_info *, const struct pw_client_info *, bool); +extern void (*pw_client_info_free_dylibloader_wrapper_pipewire)(struct pw_client_info *); +extern int (*pw_conf_load_conf_for_context_dylibloader_wrapper_pipewire)(struct pw_properties *, struct pw_properties *); +extern int (*pw_conf_load_conf_dylibloader_wrapper_pipewire)(const char *, const char *, struct pw_properties *); +extern int (*pw_conf_load_state_dylibloader_wrapper_pipewire)(const char *, const char *, struct pw_properties *); +extern int (*pw_conf_save_state_dylibloader_wrapper_pipewire)(const char *, const char *, const struct pw_properties *); +extern int (*pw_conf_section_update_props_dylibloader_wrapper_pipewire)(const struct spa_dict *, const char *, struct pw_properties *); +extern int (*pw_conf_section_for_each_dylibloader_wrapper_pipewire)(const struct spa_dict *, const char *, int (*)(void *data, const char *location, const char *section, const char *str, size_t len), void *); +extern int (*pw_conf_match_rules_dylibloader_wrapper_pipewire)(const char *, size_t, const char *, const struct spa_dict *, int (*)(void *data, const char *location, const char *action, const char *str, size_t len), void *); +extern int (*pw_conf_section_match_rules_dylibloader_wrapper_pipewire)(const struct spa_dict *, const char *, const struct spa_dict *, int (*)(void *data, const char *location, const char *action, const char *str, size_t len), void *); +extern struct pw_device_info *(*pw_device_info_update_dylibloader_wrapper_pipewire)(struct pw_device_info *, const struct pw_device_info *); +extern struct pw_device_info *(*pw_device_info_merge_dylibloader_wrapper_pipewire)(struct pw_device_info *, const struct pw_device_info *, bool); +extern void (*pw_device_info_free_dylibloader_wrapper_pipewire)(struct pw_device_info *); +extern struct pw_mempool *(*pw_mempool_new_dylibloader_wrapper_pipewire)(struct pw_properties *); +extern void (*pw_mempool_add_listener_dylibloader_wrapper_pipewire)(struct pw_mempool *, struct spa_hook *, const struct pw_mempool_events *, void *); +extern void (*pw_mempool_clear_dylibloader_wrapper_pipewire)(struct pw_mempool *); +extern void (*pw_mempool_destroy_dylibloader_wrapper_pipewire)(struct pw_mempool *); +extern struct pw_memblock *(*pw_mempool_alloc_dylibloader_wrapper_pipewire)(struct pw_mempool *, enum pw_memblock_flags, uint32_t, size_t); +extern struct pw_memblock *(*pw_mempool_import_block_dylibloader_wrapper_pipewire)(struct pw_mempool *, struct pw_memblock *); +extern struct pw_memblock *(*pw_mempool_import_dylibloader_wrapper_pipewire)(struct pw_mempool *, enum pw_memblock_flags, uint32_t, int); +extern void (*pw_memblock_free_dylibloader_wrapper_pipewire)(struct pw_memblock *); +extern int (*pw_mempool_remove_id_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t); +extern struct pw_memblock *(*pw_mempool_find_ptr_dylibloader_wrapper_pipewire)(struct pw_mempool *, const void *); +extern struct pw_memblock *(*pw_mempool_find_id_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t); +extern struct pw_memblock *(*pw_mempool_find_fd_dylibloader_wrapper_pipewire)(struct pw_mempool *, int); +extern struct pw_memmap *(*pw_memblock_map_dylibloader_wrapper_pipewire)(struct pw_memblock *, enum pw_memmap_flags, uint32_t, uint32_t, uint32_t [5]); +extern struct pw_memmap *(*pw_mempool_map_id_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t, enum pw_memmap_flags, uint32_t, uint32_t, uint32_t [5]); +extern struct pw_memmap *(*pw_mempool_import_map_dylibloader_wrapper_pipewire)(struct pw_mempool *, struct pw_mempool *, void *, uint32_t, uint32_t [5]); +extern struct pw_memmap *(*pw_mempool_find_tag_dylibloader_wrapper_pipewire)(struct pw_mempool *, uint32_t [5], size_t); +extern int (*pw_memmap_free_dylibloader_wrapper_pipewire)(struct pw_memmap *); +extern int (*pw_buffers_negotiate_dylibloader_wrapper_pipewire)(struct pw_context *, uint32_t, struct spa_node *, uint32_t, struct spa_node *, uint32_t, struct pw_buffers *); +extern void (*pw_buffers_clear_dylibloader_wrapper_pipewire)(struct pw_buffers *); +extern struct pw_factory_info *(*pw_factory_info_update_dylibloader_wrapper_pipewire)(struct pw_factory_info *, const struct pw_factory_info *); +extern struct pw_factory_info *(*pw_factory_info_merge_dylibloader_wrapper_pipewire)(struct pw_factory_info *, const struct pw_factory_info *, bool); +extern void (*pw_factory_info_free_dylibloader_wrapper_pipewire)(struct pw_factory_info *); +extern void (*pw_log_set_dylibloader_wrapper_pipewire)(struct spa_log *); +extern struct spa_log *(*pw_log_get_dylibloader_wrapper_pipewire)(void); +extern void (*pw_log_set_level_dylibloader_wrapper_pipewire)(enum spa_log_level); +extern void (*pw_log_logt_dylibloader_wrapper_pipewire)(enum spa_log_level, const struct spa_log_topic *, const char *, int, const char *, const char *, ...); +extern void (*pw_log_logtv_dylibloader_wrapper_pipewire)(enum spa_log_level, const struct spa_log_topic *, const char *, int, const char *, const char *, va_list); +extern void (*pw_log_log_dylibloader_wrapper_pipewire)(enum spa_log_level, const char *, int, const char *, const char *, ...); +extern void (*pw_log_logv_dylibloader_wrapper_pipewire)(enum spa_log_level, const char *, int, const char *, const char *, va_list); +extern const char *(*pw_link_state_as_string_dylibloader_wrapper_pipewire)(enum pw_link_state); +extern struct pw_link_info *(*pw_link_info_update_dylibloader_wrapper_pipewire)(struct pw_link_info *, const struct pw_link_info *); +extern struct pw_link_info *(*pw_link_info_merge_dylibloader_wrapper_pipewire)(struct pw_link_info *, const struct pw_link_info *, bool); +extern void (*pw_link_info_free_dylibloader_wrapper_pipewire)(struct pw_link_info *); +extern struct pw_main_loop *(*pw_main_loop_new_dylibloader_wrapper_pipewire)(const struct spa_dict *); +extern void (*pw_main_loop_add_listener_dylibloader_wrapper_pipewire)(struct pw_main_loop *, struct spa_hook *, const struct pw_main_loop_events *, void *); +extern struct pw_loop *(*pw_main_loop_get_loop_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +extern void (*pw_main_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +extern int (*pw_main_loop_run_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +extern int (*pw_main_loop_quit_dylibloader_wrapper_pipewire)(struct pw_main_loop *); +extern struct pw_module_info *(*pw_module_info_update_dylibloader_wrapper_pipewire)(struct pw_module_info *, const struct pw_module_info *); +extern struct pw_module_info *(*pw_module_info_merge_dylibloader_wrapper_pipewire)(struct pw_module_info *, const struct pw_module_info *, bool); +extern void (*pw_module_info_free_dylibloader_wrapper_pipewire)(struct pw_module_info *); +extern const char *(*pw_node_state_as_string_dylibloader_wrapper_pipewire)(enum pw_node_state); +extern struct pw_node_info *(*pw_node_info_update_dylibloader_wrapper_pipewire)(struct pw_node_info *, const struct pw_node_info *); +extern struct pw_node_info *(*pw_node_info_merge_dylibloader_wrapper_pipewire)(struct pw_node_info *, const struct pw_node_info *, bool); +extern void (*pw_node_info_free_dylibloader_wrapper_pipewire)(struct pw_node_info *); +extern const char *(*pw_direction_as_string_dylibloader_wrapper_pipewire)(enum spa_direction); +extern struct pw_port_info *(*pw_port_info_update_dylibloader_wrapper_pipewire)(struct pw_port_info *, const struct pw_port_info *); +extern struct pw_port_info *(*pw_port_info_merge_dylibloader_wrapper_pipewire)(struct pw_port_info *, const struct pw_port_info *, bool); +extern void (*pw_port_info_free_dylibloader_wrapper_pipewire)(struct pw_port_info *); +extern const char *(*pw_stream_state_as_string_dylibloader_wrapper_pipewire)(enum pw_stream_state); +extern struct pw_stream *(*pw_stream_new_dylibloader_wrapper_pipewire)(struct pw_core *, const char *, struct pw_properties *); +extern struct pw_stream *(*pw_stream_new_simple_dylibloader_wrapper_pipewire)(struct pw_loop *, const char *, struct pw_properties *, const struct pw_stream_events *, void *); +extern void (*pw_stream_destroy_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern void (*pw_stream_add_listener_dylibloader_wrapper_pipewire)(struct pw_stream *, struct spa_hook *, const struct pw_stream_events *, void *); +extern enum pw_stream_state (*pw_stream_get_state_dylibloader_wrapper_pipewire)(struct pw_stream *, const char **); +extern const char *(*pw_stream_get_name_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern struct pw_core *(*pw_stream_get_core_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern const struct pw_properties *(*pw_stream_get_properties_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern int (*pw_stream_update_properties_dylibloader_wrapper_pipewire)(struct pw_stream *, const struct spa_dict *); +extern int (*pw_stream_connect_dylibloader_wrapper_pipewire)(struct pw_stream *, enum spa_direction, uint32_t, enum pw_stream_flags, const struct spa_pod **, uint32_t); +extern uint32_t (*pw_stream_get_node_id_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern int (*pw_stream_disconnect_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern int (*pw_stream_set_error_dylibloader_wrapper_pipewire)(struct pw_stream *, int, const char *, ...); +extern int (*pw_stream_update_params_dylibloader_wrapper_pipewire)(struct pw_stream *, const struct spa_pod **, uint32_t); +extern int (*pw_stream_set_param_dylibloader_wrapper_pipewire)(struct pw_stream *, uint32_t, const struct spa_pod *); +extern const struct pw_stream_control *(*pw_stream_get_control_dylibloader_wrapper_pipewire)(struct pw_stream *, uint32_t); +extern int (*pw_stream_set_control_dylibloader_wrapper_pipewire)(struct pw_stream *, uint32_t, uint32_t, float *, ...); +extern int (*pw_stream_get_time_n_dylibloader_wrapper_pipewire)(struct pw_stream *, struct pw_time *, size_t); +extern int (*pw_stream_get_time_dylibloader_wrapper_pipewire)(struct pw_stream *, struct pw_time *); +extern struct pw_buffer *(*pw_stream_dequeue_buffer_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern int (*pw_stream_queue_buffer_dylibloader_wrapper_pipewire)(struct pw_stream *, struct pw_buffer *); +extern int (*pw_stream_set_active_dylibloader_wrapper_pipewire)(struct pw_stream *, bool); +extern int (*pw_stream_flush_dylibloader_wrapper_pipewire)(struct pw_stream *, bool); +extern bool (*pw_stream_is_driving_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern int (*pw_stream_trigger_process_dylibloader_wrapper_pipewire)(struct pw_stream *); +extern const char *(*pw_filter_state_as_string_dylibloader_wrapper_pipewire)(enum pw_filter_state); +extern struct pw_filter *(*pw_filter_new_dylibloader_wrapper_pipewire)(struct pw_core *, const char *, struct pw_properties *); +extern struct pw_filter *(*pw_filter_new_simple_dylibloader_wrapper_pipewire)(struct pw_loop *, const char *, struct pw_properties *, const struct pw_filter_events *, void *); +extern void (*pw_filter_destroy_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern void (*pw_filter_add_listener_dylibloader_wrapper_pipewire)(struct pw_filter *, struct spa_hook *, const struct pw_filter_events *, void *); +extern enum pw_filter_state (*pw_filter_get_state_dylibloader_wrapper_pipewire)(struct pw_filter *, const char **); +extern const char *(*pw_filter_get_name_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern struct pw_core *(*pw_filter_get_core_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern int (*pw_filter_connect_dylibloader_wrapper_pipewire)(struct pw_filter *, enum pw_filter_flags, const struct spa_pod **, uint32_t); +extern uint32_t (*pw_filter_get_node_id_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern int (*pw_filter_disconnect_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern void *(*pw_filter_add_port_dylibloader_wrapper_pipewire)(struct pw_filter *, enum spa_direction, enum pw_filter_port_flags, size_t, struct pw_properties *, const struct spa_pod **, uint32_t); +extern int (*pw_filter_remove_port_dylibloader_wrapper_pipewire)(void *); +extern const struct pw_properties *(*pw_filter_get_properties_dylibloader_wrapper_pipewire)(struct pw_filter *, void *); +extern int (*pw_filter_update_properties_dylibloader_wrapper_pipewire)(struct pw_filter *, void *, const struct spa_dict *); +extern int (*pw_filter_set_error_dylibloader_wrapper_pipewire)(struct pw_filter *, int, const char *, ...); +extern int (*pw_filter_update_params_dylibloader_wrapper_pipewire)(struct pw_filter *, void *, const struct spa_pod **, uint32_t); +extern int (*pw_filter_get_time_dylibloader_wrapper_pipewire)(struct pw_filter *, struct pw_time *); +extern struct pw_buffer *(*pw_filter_dequeue_buffer_dylibloader_wrapper_pipewire)(void *); +extern int (*pw_filter_queue_buffer_dylibloader_wrapper_pipewire)(void *, struct pw_buffer *); +extern void *(*pw_filter_get_dsp_buffer_dylibloader_wrapper_pipewire)(void *, uint32_t); +extern int (*pw_filter_set_active_dylibloader_wrapper_pipewire)(struct pw_filter *, bool); +extern int (*pw_filter_flush_dylibloader_wrapper_pipewire)(struct pw_filter *, bool); +extern bool (*pw_filter_is_driving_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern int (*pw_filter_trigger_process_dylibloader_wrapper_pipewire)(struct pw_filter *); +extern struct pw_thread_loop *(*pw_thread_loop_new_dylibloader_wrapper_pipewire)(const char *, const struct spa_dict *); +extern struct pw_thread_loop *(*pw_thread_loop_new_full_dylibloader_wrapper_pipewire)(struct pw_loop *, const char *, const struct spa_dict *); +extern void (*pw_thread_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern void (*pw_thread_loop_add_listener_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, struct spa_hook *, const struct pw_thread_loop_events *, void *); +extern struct pw_loop *(*pw_thread_loop_get_loop_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern int (*pw_thread_loop_start_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern void (*pw_thread_loop_stop_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern void (*pw_thread_loop_lock_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern void (*pw_thread_loop_unlock_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern void (*pw_thread_loop_wait_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern int (*pw_thread_loop_timed_wait_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, int); +extern int (*pw_thread_loop_get_time_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, struct timespec *, int64_t); +extern int (*pw_thread_loop_timed_wait_full_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, const struct timespec *); +extern void (*pw_thread_loop_signal_dylibloader_wrapper_pipewire)(struct pw_thread_loop *, bool); +extern void (*pw_thread_loop_accept_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern bool (*pw_thread_loop_in_thread_dylibloader_wrapper_pipewire)(struct pw_thread_loop *); +extern struct pw_data_loop *(*pw_data_loop_new_dylibloader_wrapper_pipewire)(const struct spa_dict *); +extern void (*pw_data_loop_add_listener_dylibloader_wrapper_pipewire)(struct pw_data_loop *, struct spa_hook *, const struct pw_data_loop_events *, void *); +extern int (*pw_data_loop_wait_dylibloader_wrapper_pipewire)(struct pw_data_loop *, int); +extern void (*pw_data_loop_exit_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern struct pw_loop *(*pw_data_loop_get_loop_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern void (*pw_data_loop_destroy_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern int (*pw_data_loop_start_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern int (*pw_data_loop_stop_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern bool (*pw_data_loop_in_thread_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern struct spa_thread *(*pw_data_loop_get_thread_dylibloader_wrapper_pipewire)(struct pw_data_loop *); +extern int (*pw_data_loop_invoke_dylibloader_wrapper_pipewire)(struct pw_data_loop *, spa_invoke_func_t, uint32_t, const void *, size_t, bool, void *); +extern void (*pw_data_loop_set_thread_utils_dylibloader_wrapper_pipewire)(struct pw_data_loop *, struct spa_thread_utils *); +extern const struct spa_type_info *(*pw_type_info_dylibloader_wrapper_pipewire)(void); +extern const char *(*pw_get_library_version_dylibloader_wrapper_pipewire)(void); +extern bool (*pw_check_library_version_dylibloader_wrapper_pipewire)(int, int, int); +extern void (*pw_init_dylibloader_wrapper_pipewire)(int *, char **[]); +extern void (*pw_deinit_dylibloader_wrapper_pipewire)(void); +extern bool (*pw_debug_is_category_enabled_dylibloader_wrapper_pipewire)(const char *); +extern const char *(*pw_get_application_name_dylibloader_wrapper_pipewire)(void); +extern const char *(*pw_get_prgname_dylibloader_wrapper_pipewire)(void); +extern const char *(*pw_get_user_name_dylibloader_wrapper_pipewire)(void); +extern const char *(*pw_get_host_name_dylibloader_wrapper_pipewire)(void); +extern const char *(*pw_get_client_name_dylibloader_wrapper_pipewire)(void); +extern bool (*pw_check_option_dylibloader_wrapper_pipewire)(const char *, const char *); +extern enum spa_direction (*pw_direction_reverse_dylibloader_wrapper_pipewire)(enum spa_direction); +extern int (*pw_set_domain_dylibloader_wrapper_pipewire)(const char *); +extern const char *(*pw_get_domain_dylibloader_wrapper_pipewire)(void); +extern uint32_t (*pw_get_support_dylibloader_wrapper_pipewire)(struct spa_support *, uint32_t); +extern struct spa_handle *(*pw_load_spa_handle_dylibloader_wrapper_pipewire)(const char *, const char *, const struct spa_dict *, uint32_t, const struct spa_support []); +extern int (*pw_unload_spa_handle_dylibloader_wrapper_pipewire)(struct spa_handle *); +int initialize_pipewire(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index dc843efc3a3b..e4b9c52a0669 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -57,6 +57,7 @@ def get_opts(): BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False), BoolVariable("use_sowrap", "Dynamically load system libraries", True), BoolVariable("alsa", "Use ALSA", True), + BoolVariable("pipewire", "Use PipeWire", True), BoolVariable("pulseaudio", "Use PulseAudio", True), BoolVariable("dbus", "Use D-Bus to handle screensaver and portal desktop settings", True), BoolVariable("speechd", "Use Speech Dispatcher for Text-to-Speech support", True), @@ -364,6 +365,17 @@ def configure(env: "SConsEnvironment"): else: env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) + if env["pipewire"]: + if not env["use_sowrap"]: + if os.system("pkg-config --exists libpipewire-0.3") == 0: # 0 means found + env.ParseConfig("pkg-config libpipewire-0.3 --cflags --libs") + env.Append(CPPDEFINES=["PIPEWIRE_ENABLED"]) + else: + print_warning("PipeWire development libraries not found. Disabling PipeWire drivers.") + env["pipewire"] = False + else: + env.Append(CPPDEFINES=["PIPEWIRE_ENABLED", "_REENTRANT"]) + if env["pulseaudio"]: if not env["use_sowrap"]: if os.system("pkg-config --exists libpulse") == 0: # 0 means found diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 43d7129579de..4623d4df1080 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -1300,6 +1300,10 @@ OS_LinuxBSD::OS_LinuxBSD() { AudioDriverManager::add_driver(&driver_pulseaudio); #endif +#ifdef PIPEWIRE_ENABLED + AudioDriverManager::add_driver(&driver_pipewire); +#endif + #ifdef ALSA_ENABLED AudioDriverManager::add_driver(&driver_alsa); #endif diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index d483e6193757..076595b38999 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -35,6 +35,7 @@ #include "core/input/input_event.h" #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" +#include "drivers/pipewire/audio_driver_pipewire.h" #include "drivers/pulseaudio/audio_driver_pulseaudio.h" #include "drivers/unix/os_unix.h" @@ -69,6 +70,10 @@ class OS_LinuxBSD : public OS_Unix { MIDIDriverALSAMidi driver_alsamidi; #endif +#ifdef PIPEWIRE_ENABLED + AudioDriverPipeWire driver_pipewire; +#endif + #ifdef PULSEAUDIO_ENABLED AudioDriverPulseAudio driver_pulseaudio; #endif diff --git a/thirdparty/linuxbsd_headers/README.md b/thirdparty/linuxbsd_headers/README.md index 36d7eb82be50..d83be9922d08 100644 --- a/thirdparty/linuxbsd_headers/README.md +++ b/thirdparty/linuxbsd_headers/README.md @@ -38,6 +38,13 @@ Patches: - License: MIT +## pipewire + +- Upstream: https://gitlab.freedesktop.org/pipewire/pipewire/ +- Version: 1.0.0 +- License: MIT + + ## pulse - Upstream: http://pulseaudio.org/ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/array.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/array.h new file mode 100644 index 000000000000..af0b59d2619c --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/array.h @@ -0,0 +1,156 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_ARRAY_H +#define PIPEWIRE_ARRAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +/** \defgroup pw_array Array + * + * \brief An array object + * + * The array is a dynamically resizable data structure that can + * hold items of the same size. + */ + +/** + * \addtogroup pw_array + * \{ + */ +struct pw_array { + void *data; /**< pointer to array data */ + size_t size; /**< length of array in bytes */ + size_t alloc; /**< number of allocated memory in \a data */ + size_t extend; /**< number of bytes to extend with */ +}; + +#define PW_ARRAY_INIT(extend) ((struct pw_array) { NULL, 0, 0, (extend) }) + +#define pw_array_get_len_s(a,s) ((a)->size / (s)) +#define pw_array_get_unchecked_s(a,idx,s,t) SPA_PTROFF((a)->data,(idx)*(s),t) +#define pw_array_check_index_s(a,idx,s) ((idx) < pw_array_get_len_s(a,s)) + +/** Get the number of items of type \a t in array */ +#define pw_array_get_len(a,t) pw_array_get_len_s(a,sizeof(t)) +/** Get the item with index \a idx and type \a t from array */ +#define pw_array_get_unchecked(a,idx,t) pw_array_get_unchecked_s(a,idx,sizeof(t),t) +/** Check if an item with index \a idx and type \a t exist in array */ +#define pw_array_check_index(a,idx,t) pw_array_check_index_s(a,idx,sizeof(t)) + +#define pw_array_first(a) ((a)->data) +#define pw_array_end(a) SPA_PTROFF((a)->data, (a)->size, void) +#define pw_array_check(a,p) (SPA_PTROFF(p,sizeof(*(p)),void) <= pw_array_end(a)) + +#define pw_array_for_each(pos, array) \ + for ((pos) = (__typeof__(pos)) pw_array_first(array); \ + pw_array_check(array, pos); \ + (pos)++) + +#define pw_array_consume(pos, array) \ + for ((pos) = (__typeof__(pos)) pw_array_first(array); \ + pw_array_check(array, pos); \ + (pos) = (__typeof__(pos)) pw_array_first(array)) + +#define pw_array_remove(a,p) \ +({ \ + (a)->size -= sizeof(*(p)); \ + memmove(p, SPA_PTROFF((p), sizeof(*(p)), void), \ + SPA_PTRDIFF(pw_array_end(a),(p))); \ +}) + +/** Initialize the array with given extend */ +static inline void pw_array_init(struct pw_array *arr, size_t extend) +{ + arr->data = NULL; + arr->size = arr->alloc = 0; + arr->extend = extend; +} + +/** Clear the array */ +static inline void pw_array_clear(struct pw_array *arr) +{ + free(arr->data); + pw_array_init(arr, arr->extend); +} + +/** Reset the array */ +static inline void pw_array_reset(struct pw_array *arr) +{ + arr->size = 0; +} + +/** Make sure \a size bytes can be added to the array */ +static inline int pw_array_ensure_size(struct pw_array *arr, size_t size) +{ + size_t alloc, need; + + alloc = arr->alloc; + need = arr->size + size; + + if (SPA_UNLIKELY(alloc < need)) { + void *data; + alloc = SPA_MAX(alloc, arr->extend); + spa_assert(alloc != 0); /* forgot pw_array_init */ + while (alloc < need) + alloc *= 2; + if (SPA_UNLIKELY((data = realloc(arr->data, alloc)) == NULL)) + return -errno; + arr->data = data; + arr->alloc = alloc; + } + return 0; +} + +/** Add \a ref size bytes to \a arr. A pointer to memory that can + * hold at least \a size bytes is returned */ +static inline void *pw_array_add(struct pw_array *arr, size_t size) +{ + void *p; + + if (pw_array_ensure_size(arr, size) < 0) + return NULL; + + p = SPA_PTROFF(arr->data, arr->size, void); + arr->size += size; + + return p; +} + +/** Add \a ref size bytes to \a arr. When there is not enough memory to + * hold \a size bytes, NULL is returned */ +static inline void *pw_array_add_fixed(struct pw_array *arr, size_t size) +{ + void *p; + + if (SPA_UNLIKELY(arr->alloc < arr->size + size)) { + errno = ENOSPC; + return NULL; + } + + p = SPA_PTROFF(arr->data, arr->size, void); + arr->size += size; + + return p; +} + +/** Add a pointer to array */ +#define pw_array_add_ptr(a,p) \ + *((void**) pw_array_add(a, sizeof(void*))) = (p) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_ARRAY_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/buffers.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/buffers.h new file mode 100644 index 000000000000..9c1ae2b78bc2 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/buffers.h @@ -0,0 +1,56 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_BUFFERS_H +#define PIPEWIRE_BUFFERS_H + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup pw_buffers Buffers + * Buffer handling + */ + +/** + * \addtogroup pw_buffers + * \{ + */ + +#define PW_BUFFERS_FLAG_NONE 0 +#define PW_BUFFERS_FLAG_NO_MEM (1<<0) /**< don't allocate buffer memory */ +#define PW_BUFFERS_FLAG_SHARED (1<<1) /**< buffers can be shared */ +#define PW_BUFFERS_FLAG_DYNAMIC (1<<2) /**< buffers have dynamic data */ +#define PW_BUFFERS_FLAG_SHARED_MEM (1<<3) /**< buffers need shared memory */ +#define PW_BUFFERS_FLAG_IN_PRIORITY (1<<4) /**< input parameters have priority */ +#define PW_BUFFERS_FLAG_ASYNC (1<<5) /**< one of the nodes is async */ + +struct pw_buffers { + struct pw_memblock *mem; /**< allocated buffer memory */ + struct spa_buffer **buffers; /**< port buffers */ + uint32_t n_buffers; /**< number of port buffers */ + uint32_t flags; /**< flags */ +}; + +int pw_buffers_negotiate(struct pw_context *context, uint32_t flags, + struct spa_node *outnode, uint32_t out_port_id, + struct spa_node *innode, uint32_t in_port_id, + struct pw_buffers *result); + +void pw_buffers_clear(struct pw_buffers *buffers); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_BUFFERS_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/client.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/client.h new file mode 100644 index 000000000000..cd119643e9d7 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/client.h @@ -0,0 +1,176 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_CLIENT_H +#define PIPEWIRE_CLIENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +/** \defgroup pw_client Client + * Client interface + */ + +/** + * \addtogroup pw_client + * \{ + */ +#define PW_TYPE_INTERFACE_Client PW_TYPE_INFO_INTERFACE_BASE "Client" + +#define PW_CLIENT_PERM_MASK PW_PERM_RWXM + +#define PW_VERSION_CLIENT 3 +struct pw_client; + +/* default ID of the current client after connect */ +#define PW_ID_CLIENT 1 + +/** The client information. Extra information can be added in later versions */ +struct pw_client_info { + uint32_t id; /**< id of the global */ +#define PW_CLIENT_CHANGE_MASK_PROPS (1 << 0) +#define PW_CLIENT_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< extra properties */ +}; + +/** Update an existing \ref pw_client_info with \a update with reset */ +struct pw_client_info * +pw_client_info_update(struct pw_client_info *info, + const struct pw_client_info *update); +/** Merge an existing \ref pw_client_info with \a update */ +struct pw_client_info * +pw_client_info_merge(struct pw_client_info *info, + const struct pw_client_info *update, bool reset); +/** Free a \ref pw_client_info */ +void pw_client_info_free(struct pw_client_info *info); + + +#define PW_CLIENT_EVENT_INFO 0 +#define PW_CLIENT_EVENT_PERMISSIONS 1 +#define PW_CLIENT_EVENT_NUM 2 + +/** Client events */ +struct pw_client_events { +#define PW_VERSION_CLIENT_EVENTS 0 + uint32_t version; + /** + * Notify client info + * + * \param info info about the client + */ + void (*info) (void *data, const struct pw_client_info *info); + /** + * Notify a client permission + * + * Event emitted as a result of the get_permissions method. + * + * \param default_permissions the default permissions + * \param index the index of the first permission entry + * \param n_permissions the number of permissions + * \param permissions the permissions + */ + void (*permissions) (void *data, + uint32_t index, + uint32_t n_permissions, + const struct pw_permission *permissions); +}; + + +#define PW_CLIENT_METHOD_ADD_LISTENER 0 +#define PW_CLIENT_METHOD_ERROR 1 +#define PW_CLIENT_METHOD_UPDATE_PROPERTIES 2 +#define PW_CLIENT_METHOD_GET_PERMISSIONS 3 +#define PW_CLIENT_METHOD_UPDATE_PERMISSIONS 4 +#define PW_CLIENT_METHOD_NUM 5 + +/** Client methods */ +struct pw_client_methods { +#define PW_VERSION_CLIENT_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_client_events *events, + void *data); + /** + * Send an error to a client + * + * \param id the global id to report the error on + * \param res an errno style error code + * \param message an error string + * + * This requires W and X permissions on the client. + */ + int (*error) (void *object, uint32_t id, int res, const char *message); + /** + * Update client properties + * + * \param props new properties + * + * This requires W and X permissions on the client. + */ + int (*update_properties) (void *object, const struct spa_dict *props); + + /** + * Get client permissions + * + * A permissions event will be emitted with the permissions. + * + * \param index the first index to query, 0 for first + * \param num the maximum number of items to get + * + * This requires W and X permissions on the client. + */ + int (*get_permissions) (void *object, uint32_t index, uint32_t num); + /** + * Manage the permissions of the global objects for this + * client + * + * Update the permissions of the global objects using the + * provided array with permissions + * + * Globals can use the default permissions or can have specific + * permissions assigned to them. + * + * \param n_permissions number of permissions + * \param permissions array of permissions + * + * This requires W and X permissions on the client. + */ + int (*update_permissions) (void *object, uint32_t n_permissions, + const struct pw_permission *permissions); +}; + +#define pw_client_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_client_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_client_add_listener(c,...) pw_client_method(c,add_listener,0,__VA_ARGS__) +#define pw_client_error(c,...) pw_client_method(c,error,0,__VA_ARGS__) +#define pw_client_update_properties(c,...) pw_client_method(c,update_properties,0,__VA_ARGS__) +#define pw_client_get_permissions(c,...) pw_client_method(c,get_permissions,0,__VA_ARGS__) +#define pw_client_update_permissions(c,...) pw_client_method(c,update_permissions,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_CLIENT_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/conf.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/conf.h new file mode 100644 index 000000000000..6031f3c44d57 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/conf.h @@ -0,0 +1,47 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_CONF_H +#define PIPEWIRE_CONF_H + +#include + +/** \defgroup pw_conf Configuration + * Loading/saving properties from/to configuration files. + */ + +/** + * \addtogroup pw_conf + * \{ + */ + +int pw_conf_load_conf_for_context(struct pw_properties *props, struct pw_properties *conf); +int pw_conf_load_conf(const char *prefix, const char *name, struct pw_properties *conf); +int pw_conf_load_state(const char *prefix, const char *name, struct pw_properties *conf); +int pw_conf_save_state(const char *prefix, const char *name, const struct pw_properties *conf); + +int pw_conf_section_update_props(const struct spa_dict *conf, + const char *section, struct pw_properties *props); + +int pw_conf_section_for_each(const struct spa_dict *conf, const char *section, + int (*callback) (void *data, const char *location, const char *section, + const char *str, size_t len), + void *data); + +int pw_conf_match_rules(const char *str, size_t len, const char *location, + const struct spa_dict *props, + int (*callback) (void *data, const char *location, const char *action, + const char *str, size_t len), + void *data); + +int pw_conf_section_match_rules(const struct spa_dict *conf, const char *section, + const struct spa_dict *props, + int (*callback) (void *data, const char *location, const char *action, + const char *str, size_t len), + void *data); +/** + * \} + */ + +#endif /* PIPEWIRE_CONF_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/context.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/context.h new file mode 100644 index 000000000000..3adfe35d6cc2 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/context.h @@ -0,0 +1,184 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_CONTEXT_H +#define PIPEWIRE_CONTEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** \defgroup pw_context Context + * + * \brief The PipeWire context object manages all locally available + * resources. It is used by both clients and servers. + * + * The context is used to: + * + * - Load modules and extend the functionality. This includes + * extending the protocol with new object types or creating + * any of the available objects. + * + * - Create implementations of various objects like nodes, + * devices, factories, modules, etc.. This will usually also + * create pw_global objects that can then be shared with + * clients. + * + * - Connect to another PipeWire instance (the main daemon, for + * example) and interact with it (See \ref page_core_api). + * + * - Export a local implementation of an object to another + * instance. + */ + +/** + * \addtogroup pw_context + * @{ + */ +struct pw_context; + +struct pw_global; +struct pw_impl_client; +struct pw_impl_node; + +#include +#include +#include + +/** context events emitted by the context object added with \ref pw_context_add_listener */ +struct pw_context_events { +#define PW_VERSION_CONTEXT_EVENTS 1 + uint32_t version; + + /** The context is being destroyed */ + void (*destroy) (void *data); + /** The context is being freed */ + void (*free) (void *data); + /** a new client object is added */ + void (*check_access) (void *data, struct pw_impl_client *client); + /** a new global object was added */ + void (*global_added) (void *data, struct pw_global *global); + /** a global object was removed */ + void (*global_removed) (void *data, struct pw_global *global); + + /** a driver was added, since 0.3.75 version:1 */ + void (*driver_added) (void *data, struct pw_impl_node *node); + /** a driver was removed, since 0.3.75 version:1 */ + void (*driver_removed) (void *data, struct pw_impl_node *node); +}; + +/** Make a new context object for a given main_loop. Ownership of the properties is taken */ +struct pw_context * pw_context_new(struct pw_loop *main_loop, /**< a main loop to run in */ + struct pw_properties *props, /**< extra properties */ + size_t user_data_size /**< extra user data size */); + +/** destroy a context object, all resources except the main_loop will be destroyed */ +void pw_context_destroy(struct pw_context *context); + +/** Get the context user data */ +void *pw_context_get_user_data(struct pw_context *context); + +/** Add a new event listener to a context */ +void pw_context_add_listener(struct pw_context *context, + struct spa_hook *listener, + const struct pw_context_events *events, + void *data); + +/** Get the context properties */ +const struct pw_properties *pw_context_get_properties(struct pw_context *context); + +/** Update the context properties */ +int pw_context_update_properties(struct pw_context *context, const struct spa_dict *dict); + +/** Get a config section for this context. Since 0.3.22, deprecated, + * use pw_context_conf_section_for_each(). */ +const char *pw_context_get_conf_section(struct pw_context *context, const char *section); +/** Parse a standard config section for this context. Since 0.3.22 */ +int pw_context_parse_conf_section(struct pw_context *context, + struct pw_properties *conf, const char *section); + +/** update properties from a section into props. Since 0.3.45 */ +int pw_context_conf_update_props(struct pw_context *context, const char *section, + struct pw_properties *props); +/** emit callback for all config sections. Since 0.3.45 */ +int pw_context_conf_section_for_each(struct pw_context *context, const char *section, + int (*callback) (void *data, const char *location, const char *section, + const char *str, size_t len), + void *data); +/** emit callback for all matched properties. Since 0.3.46 */ +int pw_context_conf_section_match_rules(struct pw_context *context, const char *section, + const struct spa_dict *props, + int (*callback) (void *data, const char *location, const char *action, + const char *str, size_t len), + void *data); + +/** Get the context support objects */ +const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support); + +/** get the context main loop */ +struct pw_loop *pw_context_get_main_loop(struct pw_context *context); + +/** get the context data loop. Since 0.3.56 */ +struct pw_data_loop *pw_context_get_data_loop(struct pw_context *context); + +/** Get the work queue from the context: Since 0.3.26 */ +struct pw_work_queue *pw_context_get_work_queue(struct pw_context *context); + +/** Get the memmory pool from the context: Since 0.3.74 */ +struct pw_mempool *pw_context_get_mempool(struct pw_context *context); + +/** Iterate the globals of the context. 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 + * globals are iterated. */ +int pw_context_for_each_global(struct pw_context *context, + int (*callback) (void *data, struct pw_global *global), + void *data); + +/** Find a context global by id */ +struct pw_global *pw_context_find_global(struct pw_context *context, /**< the context */ + uint32_t id /**< the global id */); + +/** add a spa library for the given factory_name regex */ +int pw_context_add_spa_lib(struct pw_context *context, const char *factory_regex, const char *lib); + +/** find the library name for a spa factory */ +const char * pw_context_find_spa_lib(struct pw_context *context, const char *factory_name); + +struct spa_handle *pw_context_load_spa_handle(struct pw_context *context, + const char *factory_name, + const struct spa_dict *info); + + +/** data for registering export functions */ +struct pw_export_type { + struct spa_list link; + const char *type; + struct pw_proxy * (*func) (struct pw_core *core, + const char *type, const struct spa_dict *props, void *object, + size_t user_data_size); +}; + +/** register a type that can be exported on a context_proxy. This is usually used by + * extension modules */ +int pw_context_register_export_type(struct pw_context *context, struct pw_export_type *type); +/** find information about registered export type */ +const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, const char *type); + +/** add an object to the context */ +int pw_context_set_object(struct pw_context *context, const char *type, void *value); +/** get an object from the context */ +void *pw_context_get_object(struct pw_context *context, const char *type); + +/** + * \} + */ +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_CONTEXT_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/core.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/core.h new file mode 100644 index 000000000000..2b5fa2745d44 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/core.h @@ -0,0 +1,629 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_CORE_H +#define PIPEWIRE_CORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +/** \defgroup pw_core Core + * + * \brief The core global object. + * + * This is a special singleton object. It is used for internal PipeWire + * protocol features. Connecting to a PipeWire instance returns one core + * object, the caller should then register event listeners + * using \ref pw_core_add_listener. + * + * Updates to the core object are then provided through the \ref + * pw_core_events interface. See \ref page_tutorial2 for an example. + */ + +/** + * \addtogroup pw_core + * \{ + */ +#define PW_TYPE_INTERFACE_Core PW_TYPE_INFO_INTERFACE_BASE "Core" +#define PW_TYPE_INTERFACE_Registry PW_TYPE_INFO_INTERFACE_BASE "Registry" + +#define PW_CORE_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M + +#define PW_VERSION_CORE 4 +struct pw_core; +#define PW_VERSION_REGISTRY 3 +struct pw_registry; + +/** The default remote name to connect to */ +#define PW_DEFAULT_REMOTE "pipewire-0" + +/** default ID for the core object after connect */ +#define PW_ID_CORE 0 + +/* invalid ID that matches any object when used for permissions */ +#define PW_ID_ANY (uint32_t)(0xffffffff) + +/** The core information. Extra information may be added in later versions, + * clients must not assume a constant struct size */ +struct pw_core_info { + uint32_t id; /**< id of the global */ + uint32_t cookie; /**< a random cookie for identifying this instance of PipeWire */ + const char *user_name; /**< name of the user that started the core */ + const char *host_name; /**< name of the machine the core is running on */ + const char *version; /**< version of the core */ + const char *name; /**< name of the core */ +#define PW_CORE_CHANGE_MASK_PROPS (1 << 0) +#define PW_CORE_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< extra properties */ +}; + +#include +#include +#include + +/** Update an existing \ref pw_core_info with \a update with reset */ +struct pw_core_info * +pw_core_info_update(struct pw_core_info *info, + const struct pw_core_info *update); +/** Update an existing \ref pw_core_info with \a update */ +struct pw_core_info * +pw_core_info_merge(struct pw_core_info *info, + const struct pw_core_info *update, bool reset); +/** Free a \ref pw_core_info */ +void pw_core_info_free(struct pw_core_info *info); + +/** Core */ + +#define PW_CORE_EVENT_INFO 0 +#define PW_CORE_EVENT_DONE 1 +#define PW_CORE_EVENT_PING 2 +#define PW_CORE_EVENT_ERROR 3 +#define PW_CORE_EVENT_REMOVE_ID 4 +#define PW_CORE_EVENT_BOUND_ID 5 +#define PW_CORE_EVENT_ADD_MEM 6 +#define PW_CORE_EVENT_REMOVE_MEM 7 +#define PW_CORE_EVENT_BOUND_PROPS 8 +#define PW_CORE_EVENT_NUM 9 + +/** \struct pw_core_events + * \brief Core events + */ +struct pw_core_events { +#define PW_VERSION_CORE_EVENTS 1 + uint32_t version; + + /** + * Notify new core info + * + * This event is emitted when first bound to the core or when the + * hello method is called. + * + * \param info new core info + */ + void (*info) (void *data, const struct pw_core_info *info); + /** + * Emit a done event + * + * The done event is emitted as a result of a sync method with the + * same seq number. + * + * \param seq the seq number passed to the sync method call + */ + void (*done) (void *data, uint32_t id, int seq); + + /** Emit a ping event + * + * The client should reply with a pong reply with the same seq + * number. + */ + void (*ping) (void *data, uint32_t id, int seq); + + /** + * Fatal error event + * + * The error event is sent out when a fatal (non-recoverable) + * error has occurred. The id argument is the proxy object where + * the error occurred, most often in response to a request to that + * object. The message is a brief description of the error, + * for (debugging) convenience. + * + * This event is usually also emitted on the proxy object with + * \a id. + * + * \param id object where the error occurred + * \param seq the sequence number that generated the error + * \param res error code + * \param message error description + */ + void (*error) (void *data, uint32_t id, int seq, int res, const char *message); + /** + * Remove an object ID + * + * This event is used internally by the object ID management + * logic. When a client deletes an object, the server will send + * this event to acknowledge that it has seen the delete request. + * When the client receives this event, it will know that it can + * safely reuse the object ID. + * + * \param id deleted object ID + */ + void (*remove_id) (void *data, uint32_t id); + + /** + * Notify an object binding + * + * This event is emitted when a local object ID is bound to a + * global ID. It is emitted before the global becomes visible in the + * registry. + * + * \param id bound object ID + * \param global_id the global id bound to + */ + void (*bound_id) (void *data, uint32_t id, uint32_t global_id); + + /** + * Add memory for a client + * + * Memory is given to a client as \a fd of a certain + * memory \a type. + * + * Further references to this fd will be made with the per memory + * unique identifier \a id. + * + * \param id the unique id of the memory + * \param type the memory type, one of enum spa_data_type + * \param fd the file descriptor + * \param flags extra flags + */ + void (*add_mem) (void *data, uint32_t id, uint32_t type, int fd, uint32_t flags); + + /** + * Remove memory for a client + * + * \param id the memory id to remove + */ + void (*remove_mem) (void *data, uint32_t id); + + void (*bound_props) (void *data, uint32_t id, uint32_t global_id, const struct spa_dict *props); +}; + +#define PW_CORE_METHOD_ADD_LISTENER 0 +#define PW_CORE_METHOD_HELLO 1 +#define PW_CORE_METHOD_SYNC 2 +#define PW_CORE_METHOD_PONG 3 +#define PW_CORE_METHOD_ERROR 4 +#define PW_CORE_METHOD_GET_REGISTRY 5 +#define PW_CORE_METHOD_CREATE_OBJECT 6 +#define PW_CORE_METHOD_DESTROY 7 +#define PW_CORE_METHOD_NUM 8 + +/** + * \struct pw_core_methods + * \brief Core methods + * + * The core global object. This is a singleton object used for + * creating new objects in the remote PipeWire instance. It is + * also used for internal features. + */ +struct pw_core_methods { +#define PW_VERSION_CORE_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_core_events *events, + void *data); + /** + * Start a conversation with the server. This will send + * the core info and will destroy all resources for the client + * (except the core and client resource). + * + * This requires X permissions on the core. + */ + int (*hello) (void *object, uint32_t version); + /** + * Do server roundtrip + * + * Ask the server to emit the 'done' event with \a seq. + * + * Since methods are handled in-order and events are delivered + * in-order, this can be used as a barrier to ensure all previous + * methods and the resulting events have been handled. + * + * \param seq the seq number passed to the done event + * + * This requires X permissions on the core. + */ + int (*sync) (void *object, uint32_t id, int seq); + /** + * Reply to a server ping event. + * + * Reply to the server ping event with the same seq. + * + * \param seq the seq number received in the ping event + * + * This requires X permissions on the core. + */ + int (*pong) (void *object, uint32_t id, int seq); + /** + * Fatal error event + * + * The error method is sent out when a fatal (non-recoverable) + * error has occurred. The id argument is the proxy object where + * the error occurred, most often in response to an event on that + * object. The message is a brief description of the error, + * for (debugging) convenience. + * + * This method is usually also emitted on the resource object with + * \a id. + * + * \param id resource id where the error occurred + * \param res error code + * \param message error description + * + * This requires X permissions on the core. + */ + int (*error) (void *object, uint32_t id, int seq, int res, const char *message); + /** + * Get the registry object + * + * Create a registry object that allows the client to list and bind + * the global objects available from the PipeWire server + * \param version the client version + * \param user_data_size extra size + * + * This requires X permissions on the core. + */ + struct pw_registry * (*get_registry) (void *object, uint32_t version, + size_t user_data_size); + + /** + * Create a new object on the PipeWire server from a factory. + * + * \param factory_name the factory name to use + * \param type the interface to bind to + * \param version the version of the interface + * \param props extra properties + * \param user_data_size extra size + * + * This requires X permissions on the core. + */ + void * (*create_object) (void *object, + const char *factory_name, + const char *type, + uint32_t version, + const struct spa_dict *props, + size_t user_data_size); + /** + * Destroy an resource + * + * Destroy the server resource for the given proxy. + * + * \param obj the proxy to destroy + * + * This requires X permissions on the core. + */ + int (*destroy) (void *object, void *proxy); +}; + +#define pw_core_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_core_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_core_add_listener(c,...) pw_core_method(c,add_listener,0,__VA_ARGS__) +#define pw_core_hello(c,...) pw_core_method(c,hello,0,__VA_ARGS__) +#define pw_core_sync(c,...) pw_core_method(c,sync,0,__VA_ARGS__) +#define pw_core_pong(c,...) pw_core_method(c,pong,0,__VA_ARGS__) +#define pw_core_error(c,...) pw_core_method(c,error,0,__VA_ARGS__) + + +static inline +SPA_PRINTF_FUNC(5, 0) int +pw_core_errorv(struct pw_core *core, 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'; + return pw_core_error(core, id, seq, res, buffer); +} + +static inline +SPA_PRINTF_FUNC(5, 6) int +pw_core_errorf(struct pw_core *core, uint32_t id, int seq, + int res, const char *message, ...) +{ + va_list args; + int r; + va_start(args, message); + r = pw_core_errorv(core, id, seq, res, message, args); + va_end(args); + return r; +} + +static inline struct pw_registry * +pw_core_get_registry(struct pw_core *core, uint32_t version, size_t user_data_size) +{ + struct pw_registry *res = NULL; + spa_interface_call_res((struct spa_interface*)core, + struct pw_core_methods, res, + get_registry, 0, version, user_data_size); + return res; +} + +static inline void * +pw_core_create_object(struct pw_core *core, + const char *factory_name, + const char *type, + uint32_t version, + const struct spa_dict *props, + size_t user_data_size) +{ + void *res = NULL; + spa_interface_call_res((struct spa_interface*)core, + struct pw_core_methods, res, + create_object, 0, factory_name, + type, version, props, user_data_size); + return res; +} + +#define pw_core_destroy(c,...) pw_core_method(c,destroy,0,__VA_ARGS__) + +/** + * \} + */ + +/** \defgroup pw_registry Registry + * + * The registry object is a singleton object that keeps track of + * global objects on the PipeWire instance. See also \ref pw_global. + * + * Global objects typically represent an actual object in PipeWire + * (for example, a module or node) or they are singleton + * objects such as the core. + * + * When a client creates a registry object, the registry object + * will emit a global event for each global currently in the + * registry. Globals come and go as a result of device hotplugs or + * reconfiguration or other events, and the registry will send out + * global and global_remove events to keep the client up to date + * with the changes. To mark the end of the initial burst of + * events, the client can use the pw_core.sync methosd immediately + * after calling pw_core.get_registry. + * + * A client can bind to a global object by using the bind + * request. This creates a client-side proxy that lets the object + * emit events to the client and lets the client invoke methods on + * the object. See \ref page_proxy + * + * Clients can also change the permissions of the global objects that + * it can see. This is interesting when you want to configure a + * pipewire session before handing it to another application. You + * can, for example, hide certain existing or new objects or limit + * the access permissions on an object. + */ + +/** + * \addtogroup pw_registry + * \{ + */ + +#define PW_REGISTRY_EVENT_GLOBAL 0 +#define PW_REGISTRY_EVENT_GLOBAL_REMOVE 1 +#define PW_REGISTRY_EVENT_NUM 2 + +/** Registry events */ +struct pw_registry_events { +#define PW_VERSION_REGISTRY_EVENTS 0 + uint32_t version; + /** + * Notify of a new global object + * + * The registry emits this event when a new global object is + * available. + * + * \param id the global object id + * \param permissions the permissions of the object + * \param type the type of the interface + * \param version the version of the interface + * \param props extra properties of the global + */ + void (*global) (void *data, uint32_t id, + uint32_t permissions, const char *type, uint32_t version, + const struct spa_dict *props); + /** + * Notify of a global object removal + * + * Emitted when a global object was removed from the registry. + * If the client has any bindings to the global, it should destroy + * those. + * + * \param id the id of the global that was removed + */ + void (*global_remove) (void *data, uint32_t id); +}; + +#define PW_REGISTRY_METHOD_ADD_LISTENER 0 +#define PW_REGISTRY_METHOD_BIND 1 +#define PW_REGISTRY_METHOD_DESTROY 2 +#define PW_REGISTRY_METHOD_NUM 3 + +/** Registry methods */ +struct pw_registry_methods { +#define PW_VERSION_REGISTRY_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_registry_events *events, + void *data); + /** + * Bind to a global object + * + * Bind to the global object with \a id and use the client proxy + * with new_id as the proxy. After this call, methods can be + * send to the remote global object and events can be received + * + * \param id the global id to bind to + * \param type the interface type to bind to + * \param version the interface version to use + * \returns the new object + */ + void * (*bind) (void *object, uint32_t id, const char *type, uint32_t version, + size_t use_data_size); + + /** + * Attempt to destroy a global object + * + * Try to destroy the global object. + * + * \param id the global id to destroy. The client needs X permissions + * on the global. + */ + int (*destroy) (void *object, uint32_t id); +}; + +#define pw_registry_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_registry_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +/** Registry */ +#define pw_registry_add_listener(p,...) pw_registry_method(p,add_listener,0,__VA_ARGS__) + +static inline void * +pw_registry_bind(struct pw_registry *registry, + uint32_t id, const char *type, uint32_t version, + size_t user_data_size) +{ + void *res = NULL; + spa_interface_call_res((struct spa_interface*)registry, + struct pw_registry_methods, res, + bind, 0, id, type, version, user_data_size); + return res; +} + +#define pw_registry_destroy(p,...) pw_registry_method(p,destroy,0,__VA_ARGS__) + +/** + * \} + */ + +/** + * \addtogroup pw_core + * \{ + */ + +/** Connect to a PipeWire instance + * + * \param context a \ref pw_context + * \param properties optional properties, ownership of the properties is + * taken. + * \param user_data_size extra user data size + * + * \return a \ref pw_core on success or NULL with errno set on error. The core + * will have an id of \ref PW_ID_CORE (0) + */ +struct pw_core * +pw_context_connect(struct pw_context *context, + struct pw_properties *properties, + size_t user_data_size); + +/** Connect to a PipeWire instance on the given socket + * + * \param context a \ref pw_context + * \param fd the connected socket to use, the socket will be closed + * automatically on disconnect or error. + * \param properties optional properties, ownership of the properties is + * taken. + * \param user_data_size extra user data size + * + * \return a \ref pw_core on success or NULL with errno set on error */ +struct pw_core * +pw_context_connect_fd(struct pw_context *context, + int fd, + struct pw_properties *properties, + size_t user_data_size); + +/** Connect to a given PipeWire instance + * + * \param context a \ref pw_context to connect to + * \param properties optional properties, ownership of the properties is + * taken. + * \param user_data_size extra user data size + * + * \return a \ref pw_core on success or NULL with errno set on error */ +struct pw_core * +pw_context_connect_self(struct pw_context *context, + struct pw_properties *properties, + size_t user_data_size); + +/** Steal the fd of the core connection or < 0 on error. The core + * will be disconnected after this call. */ +int pw_core_steal_fd(struct pw_core *core); + +/** Pause or resume the core. When the core is paused, no new events + * will be dispatched until the core is resumed again. */ +int pw_core_set_paused(struct pw_core *core, bool paused); + +/** disconnect and destroy a core */ +int pw_core_disconnect(struct pw_core *core); + +/** Get the user_data. It is of the size specified when this object was + * constructed */ +void *pw_core_get_user_data(struct pw_core *core); + +/** Get the client proxy of the connected core. This will have the id + * of PW_ID_CLIENT (1) */ +struct pw_client * pw_core_get_client(struct pw_core *core); + +/** Get the context object used to created this core */ +struct pw_context * pw_core_get_context(struct pw_core *core); + +/** Get properties from the core */ +const struct pw_properties *pw_core_get_properties(struct pw_core *core); + +/** Update the core properties. This updates the properties + * of the associated client. + * \return the number of properties that were updated */ +int pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict); + +/** Get the core mempool object */ +struct pw_mempool * pw_core_get_mempool(struct pw_core *core); + +/** Get the proxy with the given id */ +struct pw_proxy *pw_core_find_proxy(struct pw_core *core, uint32_t id); + +/** Export an object into the PipeWire instance associated with core */ +struct pw_proxy *pw_core_export(struct pw_core *core, /**< the core */ + const char *type, /**< the type of object */ + const struct spa_dict *props, /**< extra properties */ + void *object, /**< object to export */ + size_t user_data_size /**< extra user data */); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_CORE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/data-loop.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/data-loop.h new file mode 100644 index 000000000000..5ded69028b89 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/data-loop.h @@ -0,0 +1,93 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_DATA_LOOP_H +#define PIPEWIRE_DATA_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** \defgroup pw_data_loop Data Loop + * + * \brief PipeWire rt-loop object + * + * This loop starts a new real-time thread that + * is designed to run the processing graph. + */ + +/** + * \addtogroup pw_data_loop + * \{ + */ +struct pw_data_loop; + +#include +#include + +/** Loop events, use \ref pw_data_loop_add_listener to add a listener */ +struct pw_data_loop_events { +#define PW_VERSION_DATA_LOOP_EVENTS 0 + uint32_t version; + /** The loop is destroyed */ + void (*destroy) (void *data); +}; + +/** Make a new loop. */ +struct pw_data_loop * +pw_data_loop_new(const struct spa_dict *props); + +/** Add an event listener to loop */ +void pw_data_loop_add_listener(struct pw_data_loop *loop, + struct spa_hook *listener, + const struct pw_data_loop_events *events, + void *data); + +/** wait for activity on the loop up to \a timeout milliseconds. + * Should be called from the loop function */ +int pw_data_loop_wait(struct pw_data_loop *loop, int timeout); + +/** make sure the thread will exit. Can be called from a loop callback */ +void pw_data_loop_exit(struct pw_data_loop *loop); + +/** Get the loop implementation of this data loop */ +struct pw_loop * +pw_data_loop_get_loop(struct pw_data_loop *loop); + +/** Destroy the loop */ +void pw_data_loop_destroy(struct pw_data_loop *loop); + +/** Start the processing thread */ +int pw_data_loop_start(struct pw_data_loop *loop); + +/** Stop the processing thread */ +int pw_data_loop_stop(struct pw_data_loop *loop); + +/** Check if the current thread is the processing thread */ +bool pw_data_loop_in_thread(struct pw_data_loop *loop); +/** Get the thread object */ +struct spa_thread *pw_data_loop_get_thread(struct pw_data_loop *loop); + +/** invoke func in the context of the thread or in the caller thread when + * the loop is not running. Since 0.3.3 */ +int pw_data_loop_invoke(struct pw_data_loop *loop, + spa_invoke_func_t func, uint32_t seq, const void *data, size_t size, + bool block, void *user_data); + +/** Set a custom spa_thread_utils for this loop. Setting NULL restores the + * system default implementation. Since 0.3.50 */ +void pw_data_loop_set_thread_utils(struct pw_data_loop *loop, + struct spa_thread_utils *impl); +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_DATA_LOOP_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/device.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/device.h new file mode 100644 index 000000000000..4b546b99403e --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/device.h @@ -0,0 +1,166 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_DEVICE_H +#define PIPEWIRE_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +/** \defgroup pw_device Device + * Device interface + */ + +/** + * \addtogroup pw_device + * \{ + */ + +#define PW_TYPE_INTERFACE_Device PW_TYPE_INFO_INTERFACE_BASE "Device" + +#define PW_DEVICE_PERM_MASK PW_PERM_RWXM + +#define PW_VERSION_DEVICE 3 +struct pw_device; + +/** The device information. Extra information can be added in later versions */ +struct pw_device_info { + uint32_t id; /**< id of the global */ +#define PW_DEVICE_CHANGE_MASK_PROPS (1 << 0) +#define PW_DEVICE_CHANGE_MASK_PARAMS (1 << 1) +#define PW_DEVICE_CHANGE_MASK_ALL ((1 << 2)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< extra properties */ + struct spa_param_info *params; /**< parameters */ + uint32_t n_params; /**< number of items in \a params */ +}; + +/** Update and existing \ref pw_device_info with \a update and reset */ +struct pw_device_info * +pw_device_info_update(struct pw_device_info *info, + const struct pw_device_info *update); +/** Merge and existing \ref pw_device_info with \a update */ +struct pw_device_info * +pw_device_info_merge(struct pw_device_info *info, + const struct pw_device_info *update, bool reset); +/** Free a \ref pw_device_info */ +void pw_device_info_free(struct pw_device_info *info); + +#define PW_DEVICE_EVENT_INFO 0 +#define PW_DEVICE_EVENT_PARAM 1 +#define PW_DEVICE_EVENT_NUM 2 + +/** Device events */ +struct pw_device_events { +#define PW_VERSION_DEVICE_EVENTS 0 + uint32_t version; + /** + * Notify device info + * + * \param info info about the device + */ + void (*info) (void *data, const struct pw_device_info *info); + /** + * Notify a device param + * + * Event emitted as a result of the enum_params method. + * + * \param seq the sequence number of the request + * \param id the param id + * \param index the param index + * \param next the param index of the next param + * \param param the parameter + */ + void (*param) (void *data, int seq, + uint32_t id, uint32_t index, uint32_t next, + const struct spa_pod *param); +}; + + +#define PW_DEVICE_METHOD_ADD_LISTENER 0 +#define PW_DEVICE_METHOD_SUBSCRIBE_PARAMS 1 +#define PW_DEVICE_METHOD_ENUM_PARAMS 2 +#define PW_DEVICE_METHOD_SET_PARAM 3 +#define PW_DEVICE_METHOD_NUM 4 + +/** Device methods */ +struct pw_device_methods { +#define PW_VERSION_DEVICE_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_device_events *events, + void *data); + /** + * Subscribe to parameter changes + * + * Automatically emit param events for the given ids when + * they are changed. + * + * \param ids an array of param ids + * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the device. + */ + int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); + + /** + * Enumerate device parameters + * + * Start enumeration of device parameters. For each param, a + * param event will be emitted. + * + * \param seq a sequence number to place in the reply + * \param id the parameter id to enum or PW_ID_ANY for all + * \param start the start index or 0 for the first param + * \param num the maximum number of params to retrieve + * \param filter a param filter or NULL + * + * This requires X permissions on the device. + */ + int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter); + /** + * Set a parameter on the device + * + * \param id the parameter id to set + * \param flags extra parameter flags + * \param param the parameter to set + * + * This requires W and X permissions on the device. + */ + int (*set_param) (void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param); +}; + +#define pw_device_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_device_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_device_add_listener(c,...) pw_device_method(c,add_listener,0,__VA_ARGS__) +#define pw_device_subscribe_params(c,...) pw_device_method(c,subscribe_params,0,__VA_ARGS__) +#define pw_device_enum_params(c,...) pw_device_method(c,enum_params,0,__VA_ARGS__) +#define pw_device_set_param(c,...) pw_device_method(c,set_param,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_DEVICE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/extensions/metadata.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/extensions/metadata.h new file mode 100644 index 000000000000..8c0641fbb97e --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/extensions/metadata.h @@ -0,0 +1,117 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_EXT_METADATA_H +#define PIPEWIRE_EXT_METADATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \defgroup pw_metadata Metadata + * Metadata interface + */ + +/** + * \addtogroup pw_metadata + * \{ + */ +#define PW_TYPE_INTERFACE_Metadata PW_TYPE_INFO_INTERFACE_BASE "Metadata" + +#define PW_METADATA_PERM_MASK PW_PERM_RWX + +#define PW_VERSION_METADATA 3 +struct pw_metadata; + +#define PW_EXTENSION_MODULE_METADATA PIPEWIRE_MODULE_PREFIX "module-metadata" + +#define PW_METADATA_EVENT_PROPERTY 0 +#define PW_METADATA_EVENT_NUM 1 + + +/** \ref pw_metadata events */ +struct pw_metadata_events { +#define PW_VERSION_METADATA_EVENTS 0 + uint32_t version; + + int (*property) (void *data, + uint32_t subject, + const char *key, + const char *type, + const char *value); +}; + +#define PW_METADATA_METHOD_ADD_LISTENER 0 +#define PW_METADATA_METHOD_SET_PROPERTY 1 +#define PW_METADATA_METHOD_CLEAR 2 +#define PW_METADATA_METHOD_NUM 3 + +/** \ref pw_metadata methods */ +struct pw_metadata_methods { +#define PW_VERSION_METADATA_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_metadata_events *events, + void *data); + + /** + * Set a metadata property + * + * Automatically emit property events for the subject and key + * when they are changed. + * + * \param subject the id of the global to associate the metadata + * with. + * \param key the key of the metadata, NULL clears all metadata for + * the subject. + * \param type the type of the metadata, this can be blank + * \param value the metadata value. NULL clears the metadata. + * + * This requires X and W permissions on the metadata. It also + * requires M permissions on the subject global. + */ + int (*set_property) (void *object, + uint32_t subject, + const char *key, + const char *type, + const char *value); + + /** + * Clear all metadata + * + * This requires X and W permissions on the metadata. + */ + int (*clear) (void *object); +}; + + +#define pw_metadata_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_metadata_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_metadata_add_listener(c,...) pw_metadata_method(c,add_listener,0,__VA_ARGS__) +#define pw_metadata_set_property(c,...) pw_metadata_method(c,set_property,0,__VA_ARGS__) +#define pw_metadata_clear(c) pw_metadata_method(c,clear,0) + +#define PW_KEY_METADATA_NAME "metadata.name" +#define PW_KEY_METADATA_VALUES "metadata.values" + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_EXT_METADATA_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/factory.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/factory.h new file mode 100644 index 000000000000..6eda0420dd32 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/factory.h @@ -0,0 +1,105 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_FACTORY_H +#define PIPEWIRE_FACTORY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +#include + +/** \defgroup pw_factory Factory + * Factory interface + */ + +/** + * \addtogroup pw_factory + * \{ + */ +#define PW_TYPE_INTERFACE_Factory PW_TYPE_INFO_INTERFACE_BASE "Factory" + +#define PW_FACTORY_PERM_MASK PW_PERM_R|PW_PERM_M + +#define PW_VERSION_FACTORY 3 +struct pw_factory; + +/** The factory information. Extra information can be added in later versions */ +struct pw_factory_info { + uint32_t id; /**< id of the global */ + const char *name; /**< name the factory */ + const char *type; /**< type of the objects created by this factory */ + uint32_t version; /**< version of the objects */ +#define PW_FACTORY_CHANGE_MASK_PROPS (1 << 0) +#define PW_FACTORY_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< the properties of the factory */ +}; + +struct pw_factory_info * +pw_factory_info_update(struct pw_factory_info *info, + const struct pw_factory_info *update); +struct pw_factory_info * +pw_factory_info_merge(struct pw_factory_info *info, + const struct pw_factory_info *update, bool reset); +void +pw_factory_info_free(struct pw_factory_info *info); + + +#define PW_FACTORY_EVENT_INFO 0 +#define PW_FACTORY_EVENT_NUM 1 + +/** Factory events */ +struct pw_factory_events { +#define PW_VERSION_FACTORY_EVENTS 0 + uint32_t version; + /** + * Notify factory info + * + * \param info info about the factory + */ + void (*info) (void *data, const struct pw_factory_info *info); +}; + +#define PW_FACTORY_METHOD_ADD_LISTENER 0 +#define PW_FACTORY_METHOD_NUM 1 + +/** Factory methods */ +struct pw_factory_methods { +#define PW_VERSION_FACTORY_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_factory_events *events, + void *data); +}; + +#define pw_factory_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_factory_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_factory_add_listener(c,...) pw_factory_method(c,add_listener,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_FACTORY_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/filter.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/filter.h new file mode 100644 index 000000000000..bb5081b70765 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/filter.h @@ -0,0 +1,252 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_FILTER_H +#define PIPEWIRE_FILTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup pw_filter Filter + * + * \brief PipeWire filter object class + * + * The filter object provides a convenient way to implement + * processing filters. + * + * See also \ref api_pw_core + */ + +/** + * \addtogroup pw_filter + * \{ + */ +struct pw_filter; + +#include +#include +#include +#include + +#include +#include + +/** \enum pw_filter_state The state of a filter */ +enum pw_filter_state { + PW_FILTER_STATE_ERROR = -1, /**< the stream is in error */ + PW_FILTER_STATE_UNCONNECTED = 0, /**< unconnected */ + PW_FILTER_STATE_CONNECTING = 1, /**< connection is in progress */ + PW_FILTER_STATE_PAUSED = 2, /**< filter is connected and paused */ + PW_FILTER_STATE_STREAMING = 3 /**< filter is streaming */ +}; + +#if 0 +struct pw_buffer { + struct spa_buffer *buffer; /**< the spa buffer */ + void *user_data; /**< user data attached to the buffer */ + uint64_t size; /**< For input ports, this field is set by pw_filter + * with the duration of the buffer in ticks. + * For output ports, this field is set by the user. + * This field is added for all queued buffers and + * returned in the time info. */ +}; +#endif + +/** Events for a filter. These events are always called from the mainloop + * unless explicitly documented otherwise. */ +struct pw_filter_events { +#define PW_VERSION_FILTER_EVENTS 1 + uint32_t version; + + void (*destroy) (void *data); + /** when the filter state changes */ + void (*state_changed) (void *data, enum pw_filter_state old, + enum pw_filter_state state, const char *error); + + /** when io changed on a port of the filter (when port_data is NULL). */ + void (*io_changed) (void *data, void *port_data, + uint32_t id, void *area, uint32_t size); + /** when a parameter changed on a port of the filter (when port_data is NULL). */ + void (*param_changed) (void *data, void *port_data, + uint32_t id, const struct spa_pod *param); + + /** when a new buffer was created for a port */ + void (*add_buffer) (void *data, void *port_data, struct pw_buffer *buffer); + /** when a buffer was destroyed for a port */ + void (*remove_buffer) (void *data, void *port_data, struct pw_buffer *buffer); + + /** do processing. This is normally called from the + * mainloop but can also be called directly from the realtime data + * thread if the user is prepared to deal with this. */ + void (*process) (void *data, struct spa_io_position *position); + + /** The filter is drained */ + void (*drained) (void *data); + + /** A command notify, Since 0.3.39:1 */ + void (*command) (void *data, const struct spa_command *command); +}; + +/** Convert a filter state to a readable string */ +const char * pw_filter_state_as_string(enum pw_filter_state state); + +/** \enum pw_filter_flags Extra flags that can be used in \ref pw_filter_connect() */ +enum pw_filter_flags { + PW_FILTER_FLAG_NONE = 0, /**< no flags */ + PW_FILTER_FLAG_INACTIVE = (1 << 0), /**< start the filter inactive, + * pw_filter_set_active() needs to be + * called explicitly */ + PW_FILTER_FLAG_DRIVER = (1 << 1), /**< be a driver */ + PW_FILTER_FLAG_RT_PROCESS = (1 << 2), /**< call process from the realtime + * thread */ + PW_FILTER_FLAG_CUSTOM_LATENCY = (1 << 3), /**< don't call the default latency algorithm + * but emit the param_changed event for the + * ports when Latency params are received. */ + PW_FILTER_FLAG_TRIGGER = (1 << 4), /**< the filter will not be scheduled + * automatically but _trigger_process() + * needs to be called. This can be used + * when the filter depends on processing + * of other filters. */ + PW_FILTER_FLAG_ASYNC = (1 << 5), /**< Buffers will not be dequeued/queued from + * the realtime process() function. This is + * assumed when RT_PROCESS is unset but can + * also be the case when the process() function + * does a trigger_process() that will then + * dequeue/queue a buffer from another process() + * function. since 0.3.73 */ +}; + +enum pw_filter_port_flags { + PW_FILTER_PORT_FLAG_NONE = 0, /**< no flags */ + PW_FILTER_PORT_FLAG_MAP_BUFFERS = (1 << 0), /**< mmap the buffers except DmaBuf */ + PW_FILTER_PORT_FLAG_ALLOC_BUFFERS = (1 << 1), /**< the application will allocate buffer + * memory. In the add_buffer event, the + * data of the buffer should be set */ +}; + +/** Create a new unconneced \ref pw_filter + * \return a newly allocated \ref pw_filter */ +struct pw_filter * +pw_filter_new(struct pw_core *core, /**< a \ref pw_core */ + const char *name, /**< a filter media name */ + struct pw_properties *props /**< filter properties, ownership is taken */); + +struct pw_filter * +pw_filter_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use */ + const char *name, /**< a filter media name */ + struct pw_properties *props, /**< filter properties, ownership is taken */ + const struct pw_filter_events *events, /**< filter events */ + void *data /**< data passed to events */); + +/** Destroy a filter */ +void pw_filter_destroy(struct pw_filter *filter); + +void pw_filter_add_listener(struct pw_filter *filter, + struct spa_hook *listener, + const struct pw_filter_events *events, + void *data); + +enum pw_filter_state pw_filter_get_state(struct pw_filter *filter, const char **error); + +const char *pw_filter_get_name(struct pw_filter *filter); + +struct pw_core *pw_filter_get_core(struct pw_filter *filter); + +/** Connect a filter for processing. + * \return 0 on success < 0 on error. + * + * You should connect to the process event and use pw_filter_dequeue_buffer() + * to get the latest metadata and data. */ +int +pw_filter_connect(struct pw_filter *filter, /**< a \ref pw_filter */ + enum pw_filter_flags flags, /**< filter flags */ + const struct spa_pod **params, /**< an array with params. */ + uint32_t n_params /**< number of items in \a params */); + +/** Get the node ID of the filter. + * \return node ID. */ +uint32_t +pw_filter_get_node_id(struct pw_filter *filter); + +/** Disconnect \a filter */ +int pw_filter_disconnect(struct pw_filter *filter); + +/** add a port to the filter, returns user data of port_data_size. */ +void *pw_filter_add_port(struct pw_filter *filter, /**< a \ref pw_filter */ + enum pw_direction direction, /**< port direction */ + enum pw_filter_port_flags flags, /**< port flags */ + size_t port_data_size, /**< allocated and given to the user as port_data */ + struct pw_properties *props, /**< port properties, ownership is taken */ + const struct spa_pod **params, /**< an array of params. The params should + * ideally contain the supported formats */ + uint32_t n_params /**< number of elements in \a params */); + +/** remove a port from the filter */ +int pw_filter_remove_port(void *port_data /**< data associated with port */); + +/** get properties, port_data of NULL will give global properties */ +const struct pw_properties *pw_filter_get_properties(struct pw_filter *filter, + void *port_data); + +/** Update properties, use NULL port_data for global filter properties */ +int pw_filter_update_properties(struct pw_filter *filter, + void *port_data, const struct spa_dict *dict); + +/** Set the filter in error state */ +int pw_filter_set_error(struct pw_filter *filter, /**< a \ref pw_filter */ + int res, /**< a result code */ + const char *error, /**< an error message */ + ... + ) SPA_PRINTF_FUNC(3, 4); + +/** Update params, use NULL port_data for global filter params */ +int +pw_filter_update_params(struct pw_filter *filter, /**< a \ref pw_filter */ + void *port_data, /**< data associated with port */ + const struct spa_pod **params, /**< an array of params. */ + uint32_t n_params /**< number of elements in \a params */); + + +/** Query the time on the filter, deprecated, use the spa_io_position in the + * process() method for timing information. */ +SPA_DEPRECATED +int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time); + +/** Get a buffer that can be filled for output ports or consumed + * for input ports. */ +struct pw_buffer *pw_filter_dequeue_buffer(void *port_data); + +/** Submit a buffer for playback or recycle a buffer for capture. */ +int pw_filter_queue_buffer(void *port_data, struct pw_buffer *buffer); + +/** Get a data pointer to the buffer data */ +void *pw_filter_get_dsp_buffer(void *port_data, uint32_t n_samples); + +/** Activate or deactivate the filter */ +int pw_filter_set_active(struct pw_filter *filter, bool active); + +/** Flush a filter. When \a drain is true, the drained callback will + * be called when all data is played or recorded */ +int pw_filter_flush(struct pw_filter *filter, bool drain); + +/** Check if the filter is driving. The filter needs to have the + * PW_FILTER_FLAG_DRIVER set. When the filter is driving, + * pw_filter_trigger_process() needs to be called when data is + * available (output) or needed (input). Since 0.3.66 */ +bool pw_filter_is_driving(struct pw_filter *filter); + +/** Trigger a push/pull on the filter. One iteration of the graph will + * be scheduled and process() will be called. Since 0.3.66 */ +int pw_filter_trigger_process(struct pw_filter *filter); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_FILTER_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/keys.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/keys.h new file mode 100644 index 000000000000..fe96f10f3df5 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/keys.h @@ -0,0 +1,354 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_KEYS_H +#define PIPEWIRE_KEYS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * \defgroup pw_keys Key Names + * + * A collection of keys that are used to add extra information on objects. + * + * Keys that start with "pipewire." are in general set-once and then + * read-only. They are usually used for security sensitive information that + * needs to be fixed. + * + * Properties from other objects can also appear. This usually suggests some + * sort of parent/child or owner/owned relationship. + * + * \addtogroup pw_keys + * \{ + */ +#define PW_KEY_PROTOCOL "pipewire.protocol" /**< protocol used for connection */ +#define PW_KEY_ACCESS "pipewire.access" /**< how the client access is controlled */ +#define PW_KEY_CLIENT_ACCESS "pipewire.client.access"/**< how the client wants to be access + * controlled */ + +/** Various keys related to the identity of a client process and its security. + * Must be obtained from trusted sources by the protocol and placed as + * read-only properties. */ +#define PW_KEY_SEC_PID "pipewire.sec.pid" /**< Client pid, set by protocol */ +#define PW_KEY_SEC_UID "pipewire.sec.uid" /**< Client uid, set by protocol*/ +#define PW_KEY_SEC_GID "pipewire.sec.gid" /**< client gid, set by protocol*/ +#define PW_KEY_SEC_LABEL "pipewire.sec.label" /**< client security label, set by protocol*/ + +#define PW_KEY_SEC_SOCKET "pipewire.sec.socket" /**< client socket name, set by protocol */ + +#define PW_KEY_LIBRARY_NAME_SYSTEM "library.name.system" /**< name of the system library to use */ +#define PW_KEY_LIBRARY_NAME_LOOP "library.name.loop" /**< name of the loop library to use */ +#define PW_KEY_LIBRARY_NAME_DBUS "library.name.dbus" /**< name of the dbus library to use */ + +/** object properties */ +#define PW_KEY_OBJECT_PATH "object.path" /**< unique path to construct the object */ +#define PW_KEY_OBJECT_ID "object.id" /**< a global object id */ +#define PW_KEY_OBJECT_SERIAL "object.serial" /**< a 64 bit object serial number. This is a number + * incremented for each object that is created. + * The lower 32 bits are guaranteed to never be + * SPA_ID_INVALID. */ +#define PW_KEY_OBJECT_LINGER "object.linger" /**< the object lives on even after the client + * that created it has been destroyed */ +#define PW_KEY_OBJECT_REGISTER "object.register" /**< If the object should be registered. */ +#define PW_KEY_OBJECT_EXPORT "object.export" /**< If the object should be exported, + * since 0.3.72 */ + +/* config */ +#define PW_KEY_CONFIG_PREFIX "config.prefix" /**< a config prefix directory */ +#define PW_KEY_CONFIG_NAME "config.name" /**< a config file name */ +#define PW_KEY_CONFIG_OVERRIDE_PREFIX "config.override.prefix" /**< a config override prefix directory */ +#define PW_KEY_CONFIG_OVERRIDE_NAME "config.override.name" /**< a config override file name */ + +/* context */ +#define PW_KEY_CONTEXT_PROFILE_MODULES "context.profile.modules" /**< a context profile for modules, deprecated */ +#define PW_KEY_USER_NAME "context.user-name" /**< The user name that runs pipewire */ +#define PW_KEY_HOST_NAME "context.host-name" /**< The host name of the machine */ + +/* core */ +#define PW_KEY_CORE_NAME "core.name" /**< The name of the core. Default is + * `pipewire--`, overwritten + * by env(PIPEWIRE_CORE) */ +#define PW_KEY_CORE_VERSION "core.version" /**< The version of the core. */ +#define PW_KEY_CORE_DAEMON "core.daemon" /**< If the core is listening for connections. */ + +#define PW_KEY_CORE_ID "core.id" /**< the core id */ +#define PW_KEY_CORE_MONITORS "core.monitors" /**< the apis monitored by core. */ + +/* cpu */ +#define PW_KEY_CPU_MAX_ALIGN "cpu.max-align" /**< maximum alignment needed to support + * all CPU optimizations */ +#define PW_KEY_CPU_CORES "cpu.cores" /**< number of cores */ + +/* priorities */ +#define PW_KEY_PRIORITY_SESSION "priority.session" /**< priority in session manager */ +#define PW_KEY_PRIORITY_DRIVER "priority.driver" /**< priority to be a driver */ + +/* remote keys */ +#define PW_KEY_REMOTE_NAME "remote.name" /**< The name of the remote to connect to, + * default pipewire-0, overwritten by + * env(PIPEWIRE_REMOTE). May also be + * a SPA-JSON array of sockets, to be tried + * in order. */ +#define PW_KEY_REMOTE_INTENTION "remote.intention" /**< The intention of the remote connection, + * "generic", "screencast" */ + +/** application keys */ +#define PW_KEY_APP_NAME "application.name" /**< application name. Ex: "Totem Music Player" */ +#define PW_KEY_APP_ID "application.id" /**< a textual id for identifying an + * application logically. Ex: "org.gnome.Totem" */ +#define PW_KEY_APP_VERSION "application.version" /**< application version. Ex: "1.2.0" */ +#define PW_KEY_APP_ICON "application.icon" /**< aa base64 blob with PNG image data */ +#define PW_KEY_APP_ICON_NAME "application.icon-name" /**< an XDG icon name for the application. + * Ex: "totem" */ +#define PW_KEY_APP_LANGUAGE "application.language" /**< application language if applicable, in + * standard POSIX format. Ex: "en_GB" */ + +#define PW_KEY_APP_PROCESS_ID "application.process.id" /**< process id (pid)*/ +#define PW_KEY_APP_PROCESS_BINARY "application.process.binary" /**< binary name */ +#define PW_KEY_APP_PROCESS_USER "application.process.user" /**< user name */ +#define PW_KEY_APP_PROCESS_HOST "application.process.host" /**< host name */ +#define PW_KEY_APP_PROCESS_MACHINE_ID "application.process.machine-id" /**< the D-Bus host id the + * application runs on */ +#define PW_KEY_APP_PROCESS_SESSION_ID "application.process.session-id" /**< login session of the + * application, on Unix the + * value of $XDG_SESSION_ID. */ +/** window system */ +#define PW_KEY_WINDOW_X11_DISPLAY "window.x11.display" /**< the X11 display string. Ex. ":0.0" */ + +/** Client properties */ +#define PW_KEY_CLIENT_ID "client.id" /**< a client id */ +#define PW_KEY_CLIENT_NAME "client.name" /**< the client name */ +#define PW_KEY_CLIENT_API "client.api" /**< the client api used to access + * PipeWire */ + +/** Node keys */ +#define PW_KEY_NODE_ID "node.id" /**< node id */ +#define PW_KEY_NODE_NAME "node.name" /**< node name */ +#define PW_KEY_NODE_NICK "node.nick" /**< short node name */ +#define PW_KEY_NODE_DESCRIPTION "node.description" /**< localized human readable node one-line + * description. Ex. "Foobar USB Headset" */ +#define PW_KEY_NODE_PLUGGED "node.plugged" /**< when the node was created. As a uint64 in + * nanoseconds. */ + +#define PW_KEY_NODE_SESSION "node.session" /**< the session id this node is part of */ +#define PW_KEY_NODE_GROUP "node.group" /**< the group id this node is part of. Nodes + * in the same group are always scheduled + * with the same driver. Can be an array of + * group names. */ +#define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */ +#define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected + * to a compatible node */ +#define PW_KEY_NODE_LATENCY "node.latency" /**< the requested latency of the node as + * a fraction. Ex: 128/48000 */ +#define PW_KEY_NODE_MAX_LATENCY "node.max-latency" /**< the maximum supported latency of the + * node as a fraction. Ex: 1024/48000 */ +#define PW_KEY_NODE_LOCK_QUANTUM "node.lock-quantum" /**< don't change quantum when this node + * is active */ +#define PW_KEY_NODE_FORCE_QUANTUM "node.force-quantum" /**< force a quantum while the node is + * active */ +#define PW_KEY_NODE_RATE "node.rate" /**< the requested rate of the graph as + * a fraction. Ex: 1/48000 */ +#define PW_KEY_NODE_LOCK_RATE "node.lock-rate" /**< don't change rate when this node + * is active */ +#define PW_KEY_NODE_FORCE_RATE "node.force-rate" /**< force a rate while the node is + * active. A value of 0 takes the denominator + * of node.rate */ + +#define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node. The node is + * initially linked to target.object or the + * default node. If the target is removed, + * the node is destroyed */ +#define PW_KEY_NODE_ALWAYS_PROCESS "node.always-process" /**< process even when unlinked */ +#define PW_KEY_NODE_WANT_DRIVER "node.want-driver" /**< the node wants to be grouped with a driver + * node in order to schedule the graph. */ +#define PW_KEY_NODE_PAUSE_ON_IDLE "node.pause-on-idle" /**< pause the node when idle */ +#define PW_KEY_NODE_SUSPEND_ON_IDLE "node.suspend-on-idle" /**< suspend the node when idle */ +#define PW_KEY_NODE_CACHE_PARAMS "node.cache-params" /**< cache the node params */ +#define PW_KEY_NODE_TRANSPORT_SYNC "node.transport.sync" /**< the node handles transport sync */ +#define PW_KEY_NODE_DRIVER "node.driver" /**< node can drive the graph */ +#define PW_KEY_NODE_STREAM "node.stream" /**< node is a stream, the server side should + * add a converter */ +#define PW_KEY_NODE_VIRTUAL "node.virtual" /**< the node is some sort of virtual + * object */ +#define PW_KEY_NODE_PASSIVE "node.passive" /**< indicate that a node wants passive links + * on output/input/all ports when the value is + * "out"/"in"/"true" respectively */ +#define PW_KEY_NODE_LINK_GROUP "node.link-group" /**< the node is internally linked to + * nodes with the same link-group. Can be an + * array of group names. */ +#define PW_KEY_NODE_NETWORK "node.network" /**< the node is on a network */ +#define PW_KEY_NODE_TRIGGER "node.trigger" /**< the node is not scheduled automatically + * based on the dependencies in the graph + * but it will be triggered explicitly. */ +#define PW_KEY_NODE_CHANNELNAMES "node.channel-names" /**< names of node's + * channels (unrelated to positions) */ +#define PW_KEY_NODE_DEVICE_PORT_NAME_PREFIX "node.device-port-name-prefix" /** override + * port name prefix for device ports, like capture and playback + * or disable the prefix completely if an empty string is provided */ + +/** Port keys */ +#define PW_KEY_PORT_ID "port.id" /**< port id */ +#define PW_KEY_PORT_NAME "port.name" /**< port name */ +#define PW_KEY_PORT_DIRECTION "port.direction" /**< the port direction, one of "in" or "out" + * or "control" and "notify" for control ports */ +#define PW_KEY_PORT_ALIAS "port.alias" /**< port alias */ +#define PW_KEY_PORT_PHYSICAL "port.physical" /**< if this is a physical port */ +#define PW_KEY_PORT_TERMINAL "port.terminal" /**< if this port consumes the data */ +#define PW_KEY_PORT_CONTROL "port.control" /**< if this port is a control port */ +#define PW_KEY_PORT_MONITOR "port.monitor" /**< if this port is a monitor port */ +#define PW_KEY_PORT_CACHE_PARAMS "port.cache-params" /**< cache the node port params */ +#define PW_KEY_PORT_EXTRA "port.extra" /**< api specific extra port info, API name + * should be prefixed. "jack:flags:56" */ +#define PW_KEY_PORT_PASSIVE "port.passive" /**< the ports wants passive links, since 0.3.67 */ +#define PW_KEY_PORT_IGNORE_LATENCY "port.ignore-latency" /**< latency ignored by peers, since 0.3.71 */ + +/** link properties */ +#define PW_KEY_LINK_ID "link.id" /**< a link id */ +#define PW_KEY_LINK_INPUT_NODE "link.input.node" /**< input node id of a link */ +#define PW_KEY_LINK_INPUT_PORT "link.input.port" /**< input port id of a link */ +#define PW_KEY_LINK_OUTPUT_NODE "link.output.node" /**< output node id of a link */ +#define PW_KEY_LINK_OUTPUT_PORT "link.output.port" /**< output port id of a link */ +#define PW_KEY_LINK_PASSIVE "link.passive" /**< indicate that a link is passive and + * does not cause the graph to be + * runnable. */ +#define PW_KEY_LINK_FEEDBACK "link.feedback" /**< indicate that a link is a feedback + * link and the target will receive data + * in the next cycle */ + +/** device properties */ +#define PW_KEY_DEVICE_ID "device.id" /**< device id */ +#define PW_KEY_DEVICE_NAME "device.name" /**< device name */ +#define PW_KEY_DEVICE_PLUGGED "device.plugged" /**< when the device was created. As a uint64 in + * nanoseconds. */ +#define PW_KEY_DEVICE_NICK "device.nick" /**< a short device nickname */ +#define PW_KEY_DEVICE_STRING "device.string" /**< device string in the underlying layer's + * format. Ex. "surround51:0" */ +#define PW_KEY_DEVICE_API "device.api" /**< API this device is accessed with. + * Ex. "alsa", "v4l2" */ +#define PW_KEY_DEVICE_DESCRIPTION "device.description" /**< localized human readable device one-line + * description. Ex. "Foobar USB Headset" */ +#define PW_KEY_DEVICE_BUS_PATH "device.bus-path" /**< bus path to the device in the OS' + * format. Ex. "pci-0000:00:14.0-usb-0:3.2:1.0" */ +#define PW_KEY_DEVICE_SERIAL "device.serial" /**< Serial number if applicable */ +#define PW_KEY_DEVICE_VENDOR_ID "device.vendor.id" /**< vendor ID if applicable */ +#define PW_KEY_DEVICE_VENDOR_NAME "device.vendor.name" /**< vendor name if applicable */ +#define PW_KEY_DEVICE_PRODUCT_ID "device.product.id" /**< product ID if applicable */ +#define PW_KEY_DEVICE_PRODUCT_NAME "device.product.name" /**< product name if applicable */ +#define PW_KEY_DEVICE_CLASS "device.class" /**< device class */ +#define PW_KEY_DEVICE_FORM_FACTOR "device.form-factor" /**< form factor if applicable. One of + * "internal", "speaker", "handset", "tv", + * "webcam", "microphone", "headset", + * "headphone", "hands-free", "car", "hifi", + * "computer", "portable" */ +#define PW_KEY_DEVICE_BUS "device.bus" /**< bus of the device if applicable. One of + * "isa", "pci", "usb", "firewire", + * "bluetooth" */ +#define PW_KEY_DEVICE_SUBSYSTEM "device.subsystem" /**< device subsystem */ +#define PW_KEY_DEVICE_SYSFS_PATH "device.sysfs.path" /**< device sysfs path */ +#define PW_KEY_DEVICE_ICON "device.icon" /**< icon for the device. A base64 blob + * containing PNG image data */ +#define PW_KEY_DEVICE_ICON_NAME "device.icon-name" /**< an XDG icon name for the device. + * Ex. "sound-card-speakers-usb" */ +#define PW_KEY_DEVICE_INTENDED_ROLES "device.intended-roles" /**< intended use. A space separated list of + * roles (see PW_KEY_MEDIA_ROLE) this device + * is particularly well suited for, due to + * latency, quality or form factor. */ +#define PW_KEY_DEVICE_CACHE_PARAMS "device.cache-params" /**< cache the device spa params */ + +/** module properties */ +#define PW_KEY_MODULE_ID "module.id" /**< the module id */ +#define PW_KEY_MODULE_NAME "module.name" /**< the name of the module */ +#define PW_KEY_MODULE_AUTHOR "module.author" /**< the author's name */ +#define PW_KEY_MODULE_DESCRIPTION "module.description" /**< a human readable one-line description + * of the module's purpose.*/ +#define PW_KEY_MODULE_USAGE "module.usage" /**< a human readable usage description of + * the module's arguments. */ +#define PW_KEY_MODULE_VERSION "module.version" /**< a version string for the module. */ + +/** Factory properties */ +#define PW_KEY_FACTORY_ID "factory.id" /**< the factory id */ +#define PW_KEY_FACTORY_NAME "factory.name" /**< the name of the factory */ +#define PW_KEY_FACTORY_USAGE "factory.usage" /**< the usage of the factory */ +#define PW_KEY_FACTORY_TYPE_NAME "factory.type.name" /**< the name of the type created by a factory */ +#define PW_KEY_FACTORY_TYPE_VERSION "factory.type.version" /**< the version of the type created by a factory */ + +/** Stream properties */ +#define PW_KEY_STREAM_IS_LIVE "stream.is-live" /**< Indicates that the stream is live. */ +#define PW_KEY_STREAM_LATENCY_MIN "stream.latency.min" /**< The minimum latency of the stream. */ +#define PW_KEY_STREAM_LATENCY_MAX "stream.latency.max" /**< The maximum latency of the stream */ +#define PW_KEY_STREAM_MONITOR "stream.monitor" /**< Indicates that the stream is monitoring + * and might select a less accurate but faster + * conversion algorithm. Monitor streams are also + * ignored when calculating the latency of their peer + * ports (since 0.3.71). + */ +#define PW_KEY_STREAM_DONT_REMIX "stream.dont-remix" /**< don't remix channels */ +#define PW_KEY_STREAM_CAPTURE_SINK "stream.capture.sink" /**< Try to capture the sink output instead of + * source output */ + +/** Media */ +#define PW_KEY_MEDIA_TYPE "media.type" /**< Media type, one of + * Audio, Video, Midi */ +#define PW_KEY_MEDIA_CATEGORY "media.category" /**< Media Category: + * Playback, Capture, Duplex, Monitor, Manager */ +#define PW_KEY_MEDIA_ROLE "media.role" /**< Role: Movie, Music, Camera, + * Screen, Communication, Game, + * Notification, DSP, Production, + * Accessibility, Test */ +#define PW_KEY_MEDIA_CLASS "media.class" /**< class Ex: "Video/Source" */ +#define PW_KEY_MEDIA_NAME "media.name" /**< media name. Ex: "Pink Floyd: Time" */ +#define PW_KEY_MEDIA_TITLE "media.title" /**< title. Ex: "Time" */ +#define PW_KEY_MEDIA_ARTIST "media.artist" /**< artist. Ex: "Pink Floyd" */ +#define PW_KEY_MEDIA_COPYRIGHT "media.copyright" /**< copyright string */ +#define PW_KEY_MEDIA_SOFTWARE "media.software" /**< generator software */ +#define PW_KEY_MEDIA_LANGUAGE "media.language" /**< language in POSIX format. Ex: en_GB */ +#define PW_KEY_MEDIA_FILENAME "media.filename" /**< filename */ +#define PW_KEY_MEDIA_ICON "media.icon" /**< icon for the media, a base64 blob with + * PNG image data */ +#define PW_KEY_MEDIA_ICON_NAME "media.icon-name" /**< an XDG icon name for the media. + * Ex: "audio-x-mp3" */ +#define PW_KEY_MEDIA_COMMENT "media.comment" /**< extra comment */ +#define PW_KEY_MEDIA_DATE "media.date" /**< date of the media */ +#define PW_KEY_MEDIA_FORMAT "media.format" /**< format of the media */ + +/** format related properties */ +#define PW_KEY_FORMAT_DSP "format.dsp" /**< a dsp format. + * Ex: "32 bit float mono audio" */ +/** audio related properties */ +#define PW_KEY_AUDIO_CHANNEL "audio.channel" /**< an audio channel. Ex: "FL" */ +#define PW_KEY_AUDIO_RATE "audio.rate" /**< an audio samplerate */ +#define PW_KEY_AUDIO_CHANNELS "audio.channels" /**< number of audio channels */ +#define PW_KEY_AUDIO_FORMAT "audio.format" /**< an audio format. Ex: "S16LE" */ +#define PW_KEY_AUDIO_ALLOWED_RATES "audio.allowed-rates" /**< a list of allowed samplerates + * ex. "[ 44100 48000 ]" */ + +/** video related properties */ +#define PW_KEY_VIDEO_RATE "video.framerate" /**< a video framerate */ +#define PW_KEY_VIDEO_FORMAT "video.format" /**< a video format */ +#define PW_KEY_VIDEO_SIZE "video.size" /**< a video size as "x +#include + +#include + +/** \defgroup pw_link Link + * + * A link is the connection between 2 nodes (\ref pw_node). Nodes are + * linked together on ports. + * + * The link is responsible for negotiating the format and buffers for + * the nodes. + * + */ + +/** + * \addtogroup pw_link + * \{ + */ + +#define PW_TYPE_INTERFACE_Link PW_TYPE_INFO_INTERFACE_BASE "Link" + +#define PW_LINK_PERM_MASK PW_PERM_R | PW_PERM_X + +#define PW_VERSION_LINK 3 +struct pw_link; + +/** \enum pw_link_state The different link states */ +enum pw_link_state { + PW_LINK_STATE_ERROR = -2, /**< the link is in error */ + PW_LINK_STATE_UNLINKED = -1, /**< the link is unlinked */ + PW_LINK_STATE_INIT = 0, /**< the link is initialized */ + PW_LINK_STATE_NEGOTIATING = 1, /**< the link is negotiating formats */ + PW_LINK_STATE_ALLOCATING = 2, /**< the link is allocating buffers */ + PW_LINK_STATE_PAUSED = 3, /**< the link is paused */ + PW_LINK_STATE_ACTIVE = 4, /**< the link is active */ +}; + +/** Convert a \ref pw_link_state to a readable string */ +const char * pw_link_state_as_string(enum pw_link_state state); +/** The link information. Extra information can be added in later versions */ +struct pw_link_info { + uint32_t id; /**< id of the global */ + uint32_t output_node_id; /**< server side output node id */ + uint32_t output_port_id; /**< output port id */ + uint32_t input_node_id; /**< server side input node id */ + uint32_t input_port_id; /**< input port id */ +#define PW_LINK_CHANGE_MASK_STATE (1 << 0) +#define PW_LINK_CHANGE_MASK_FORMAT (1 << 1) +#define PW_LINK_CHANGE_MASK_PROPS (1 << 2) +#define PW_LINK_CHANGE_MASK_ALL ((1 << 3)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + enum pw_link_state state; /**< the current state of the link */ + const char *error; /**< an error reason if \a state is error */ + struct spa_pod *format; /**< format over link */ + struct spa_dict *props; /**< the properties of the link */ +}; + +struct pw_link_info * +pw_link_info_update(struct pw_link_info *info, + const struct pw_link_info *update); + +struct pw_link_info * +pw_link_info_merge(struct pw_link_info *info, + const struct pw_link_info *update, bool reset); + +void +pw_link_info_free(struct pw_link_info *info); + + +#define PW_LINK_EVENT_INFO 0 +#define PW_LINK_EVENT_NUM 1 + +/** Link events */ +struct pw_link_events { +#define PW_VERSION_LINK_EVENTS 0 + uint32_t version; + /** + * Notify link info + * + * \param info info about the link + */ + void (*info) (void *data, const struct pw_link_info *info); +}; + +#define PW_LINK_METHOD_ADD_LISTENER 0 +#define PW_LINK_METHOD_NUM 1 + +/** Link methods */ +struct pw_link_methods { +#define PW_VERSION_LINK_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_link_events *events, + void *data); +}; + +#define pw_link_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_link_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_link_add_listener(c,...) pw_link_method(c,add_listener,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_LINK_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/log.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/log.h new file mode 100644 index 000000000000..b1cdc4c525cd --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/log.h @@ -0,0 +1,151 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_LOG_H +#define PIPEWIRE_LOG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup pw_log Logging + * + * \brief Logging functions of PipeWire + * + * Logging is performed to stdout and stderr. Trace logging is performed + * in a lockfree ringbuffer and written out from the main thread as to not + * block the realtime threads. + */ + +/** + * \addtogroup pw_log + * \{ + */ +/** The global log level */ +extern enum spa_log_level pw_log_level; + +extern struct spa_log_topic *PW_LOG_TOPIC_DEFAULT; + +/** Configure a logging module. This is usually done automatically + * in pw_init() but you can install a custom logger before calling + * pw_init(). */ +void pw_log_set(struct spa_log *log); + +/** Get the log interface */ +struct spa_log *pw_log_get(void); + +/** Configure the logging level */ +void pw_log_set_level(enum spa_log_level level); + +/** Log a message for a topic */ +void +pw_log_logt(enum spa_log_level level, + const struct spa_log_topic *topic, + const char *file, + int line, const char *func, + const char *fmt, ...) SPA_PRINTF_FUNC(6, 7); + +/** Log a message for a topic */ +void +pw_log_logtv(enum spa_log_level level, + const struct spa_log_topic *topic, + const char *file, + int line, const char *func, + const char *fmt, va_list args) SPA_PRINTF_FUNC(6, 0); + + + +/** Log a message for the default topic */ +void +pw_log_log(enum spa_log_level level, + const char *file, + int line, const char *func, + const char *fmt, ...) SPA_PRINTF_FUNC(5, 6); + +/** Log a message for the default topic */ +void +pw_log_logv(enum spa_log_level level, + const char *file, + int line, const char *func, + const char *fmt, va_list args) SPA_PRINTF_FUNC(5, 0); + +/** + * Declare a static log topic named \a var. The usual usage is: + * \code + * PW_LOG_TOPIC_STATIC(my_topic); + * #define PW_LOG_TOPIC_DEFAULT my_topic + * + * void foo() { + * pw_log_debug("bar"); + * } + * \endcode + */ +#define PW_LOG_TOPIC_STATIC(var, topic) \ + static struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \ + static struct spa_log_topic *var = &(var##__LINE__) + +/** + * Declare a static log topic named \a var. + * See \ref PW_LOG_TOPIC_STATIC for an example usage. + */ +#define PW_LOG_TOPIC_EXTERN(var) \ + extern struct spa_log_topic *var + +/** + * Declare a static log topic named \a var. + * See \ref PW_LOG_TOPIC_STATIC for an example usage. + */ +#define PW_LOG_TOPIC(var, topic) \ + struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \ + struct spa_log_topic *var = &(var##__LINE__) + +#define PW_LOG_TOPIC_INIT(var) \ + spa_log_topic_init(pw_log_get(), var); + +/** Check if a loglevel is enabled */ +#define pw_log_level_enabled(lev) (pw_log_level >= (lev)) +#define pw_log_topic_enabled(lev,t) ((t) && (t)->has_custom_level ? (t)->level >= (lev) : pw_log_level_enabled((lev))) + +#define pw_logtv(lev,topic,fmt,ap) \ +({ \ + if (SPA_UNLIKELY(pw_log_topic_enabled(lev,topic))) \ + pw_log_logtv(lev,topic,__FILE__,__LINE__,__func__,fmt,ap); \ +}) + +#define pw_logt(lev,topic,...) \ +({ \ + if (SPA_UNLIKELY(pw_log_topic_enabled(lev,topic))) \ + pw_log_logt(lev,topic,__FILE__,__LINE__,__func__,__VA_ARGS__); \ +}) + +#define pw_log(lev,...) pw_logt(lev,PW_LOG_TOPIC_DEFAULT,__VA_ARGS__) + +#define pw_log_error(...) pw_log(SPA_LOG_LEVEL_ERROR,__VA_ARGS__) +#define pw_log_warn(...) pw_log(SPA_LOG_LEVEL_WARN,__VA_ARGS__) +#define pw_log_info(...) pw_log(SPA_LOG_LEVEL_INFO,__VA_ARGS__) +#define pw_log_debug(...) pw_log(SPA_LOG_LEVEL_DEBUG,__VA_ARGS__) +#define pw_log_trace(...) pw_log(SPA_LOG_LEVEL_TRACE,__VA_ARGS__) + +#define pw_logt_error(t,...) pw_logt(SPA_LOG_LEVEL_ERROR,t,__VA_ARGS__) +#define pw_logt_warn(t,...) pw_logt(SPA_LOG_LEVEL_WARN,t,__VA_ARGS__) +#define pw_logt_info(t,...) pw_logt(SPA_LOG_LEVEL_INFO,t,__VA_ARGS__) +#define pw_logt_debug(t,...) pw_logt(SPA_LOG_LEVEL_DEBUG,t,__VA_ARGS__) +#define pw_logt_trace(t,...) pw_logt(SPA_LOG_LEVEL_TRACE,t,__VA_ARGS__) + +#ifndef FASTPATH +#define pw_log_trace_fp(...) pw_log(SPA_LOG_LEVEL_TRACE,__VA_ARGS__) +#else +#define pw_log_trace_fp(...) +#endif + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif +#endif /* PIPEWIRE_LOG_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/loop.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/loop.h new file mode 100644 index 000000000000..25f5cfb22f02 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/loop.h @@ -0,0 +1,70 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_LOOP_H +#define PIPEWIRE_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** \defgroup pw_loop Loop + * + * PipeWire loop object provides an implementation of + * the spa loop interfaces. It can be used to implement various + * event loops. + */ + +/** + * \addtogroup pw_loop + * \{ + */ + +struct pw_loop { + struct spa_system *system; /**< system utils */ + struct spa_loop *loop; /**< wrapped loop */ + struct spa_loop_control *control; /**< loop control */ + struct spa_loop_utils *utils; /**< loop utils */ +}; + +struct pw_loop * +pw_loop_new(const struct spa_dict *props); + +void +pw_loop_destroy(struct pw_loop *loop); + +#define pw_loop_add_source(l,...) spa_loop_add_source((l)->loop,__VA_ARGS__) +#define pw_loop_update_source(l,...) spa_loop_update_source((l)->loop,__VA_ARGS__) +#define pw_loop_remove_source(l,...) spa_loop_remove_source((l)->loop,__VA_ARGS__) +#define pw_loop_invoke(l,...) spa_loop_invoke((l)->loop,__VA_ARGS__) + +#define pw_loop_get_fd(l) spa_loop_control_get_fd((l)->control) +#define pw_loop_add_hook(l,...) spa_loop_control_add_hook((l)->control,__VA_ARGS__) +#define pw_loop_enter(l) spa_loop_control_enter((l)->control) +#define pw_loop_leave(l) spa_loop_control_leave((l)->control) +#define pw_loop_iterate(l,...) spa_loop_control_iterate_fast((l)->control,__VA_ARGS__) + +#define pw_loop_add_io(l,...) spa_loop_utils_add_io((l)->utils,__VA_ARGS__) +#define pw_loop_update_io(l,...) spa_loop_utils_update_io((l)->utils,__VA_ARGS__) +#define pw_loop_add_idle(l,...) spa_loop_utils_add_idle((l)->utils,__VA_ARGS__) +#define pw_loop_enable_idle(l,...) spa_loop_utils_enable_idle((l)->utils,__VA_ARGS__) +#define pw_loop_add_event(l,...) spa_loop_utils_add_event((l)->utils,__VA_ARGS__) +#define pw_loop_signal_event(l,...) spa_loop_utils_signal_event((l)->utils,__VA_ARGS__) +#define pw_loop_add_timer(l,...) spa_loop_utils_add_timer((l)->utils,__VA_ARGS__) +#define pw_loop_update_timer(l,...) spa_loop_utils_update_timer((l)->utils,__VA_ARGS__) +#define pw_loop_add_signal(l,...) spa_loop_utils_add_signal((l)->utils,__VA_ARGS__) +#define pw_loop_destroy_source(l,...) spa_loop_utils_destroy_source((l)->utils,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_LOOP_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/main-loop.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/main-loop.h new file mode 100644 index 000000000000..78ab644e6565 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/main-loop.h @@ -0,0 +1,66 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_MAIN_LOOP_H +#define PIPEWIRE_MAIN_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup pw_main_loop Main Loop + * + * A main loop object + */ + +/** + * \addtogroup pw_main_loop + * \{ + */ + +/** A main loop object */ +struct pw_main_loop; + +#include + +/** Events of the main loop */ +struct pw_main_loop_events { +#define PW_VERSION_MAIN_LOOP_EVENTS 0 + uint32_t version; + + /** Emitted when the main loop is destroyed */ + void (*destroy) (void *data); +}; + +/** Create a new main loop. */ +struct pw_main_loop * +pw_main_loop_new(const struct spa_dict *props); + +/** Add an event listener */ +void pw_main_loop_add_listener(struct pw_main_loop *loop, + struct spa_hook *listener, + const struct pw_main_loop_events *events, + void *data); + +/** Get the loop implementation */ +struct pw_loop * pw_main_loop_get_loop(struct pw_main_loop *loop); + +/** Destroy a loop */ +void pw_main_loop_destroy(struct pw_main_loop *loop); + +/** Run a main loop. This blocks until \ref pw_main_loop_quit is called */ +int pw_main_loop_run(struct pw_main_loop *loop); + +/** Quit a main loop */ +int pw_main_loop_quit(struct pw_main_loop *loop); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_MAIN_LOOP_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/map.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/map.h new file mode 100644 index 000000000000..39d6d08482f6 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/map.h @@ -0,0 +1,232 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_MAP_H +#define PIPEWIRE_MAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +/** \defgroup pw_map Map + * + * \brief A map that holds pointers to objects indexed by id + * + * The map is a sparse version of the \ref pw_array "pw_array" that manages the + * indices of elements for the caller. Adding items with + * pw_map_insert_new() returns the assigned index for that item; if items + * are removed the map re-uses indices to keep the array at the minimum + * required size. + * + * \code{.c} + * struct pw_map map = PW_MAP_INIT(4); + * + * idx1 = pw_map_insert_new(&map, ptr1); + * idx2 = pw_map_insert_new(&map, ptr2); + * // the map is now [ptr1, ptr2], size 2 + * pw_map_remove(&map, idx1); + * // the map is now [, ptr2], size 2 + * pw_map_insert_new(&map, ptr3); + * // the map is now [ptr3, ptr2], size 2 + * \endcode + */ + +/** + * \addtogroup pw_map + * \{ + */ + +/** \private + * An entry in the map. This is used internally only. Each element in the + * backing pw_array is a union pw_map_item. For real items, the data pointer + * points to the item. If an element has been removed, pw_map->free_list + * is the index of the most recently removed item. That item contains + * the index of the next removed item until item->next is SPA_ID_INVALID. + * + * The free list is prepended only, the last item to be removed will be the + * first item to get re-used on the next insert. + */ +union pw_map_item { + uintptr_t next; /* next free index */ + void *data; /* data of this item, must be an even address */ +}; + +/** A map. This struct should be treated as opaque by the caller. */ +struct pw_map { + struct pw_array items; /* an array with the map items */ + uint32_t free_list; /* first free index */ +}; + +/** \param extend the amount of bytes to grow the map with when needed */ +#define PW_MAP_INIT(extend) ((struct pw_map) { PW_ARRAY_INIT(extend), SPA_ID_INVALID }) + +/** + * Get the number of currently allocated elements in the map. + * \note pw_map_get_size() returns the currently allocated number of + * elements in the map, not the number of actually set elements. + * \return the number of available elements before the map needs to grow + */ +#define pw_map_get_size(m) pw_array_get_len(&(m)->items, union pw_map_item) +#define pw_map_get_item(m,id) pw_array_get_unchecked(&(m)->items,id,union pw_map_item) +#define pw_map_item_is_free(item) ((item)->next & 0x1) +#define pw_map_id_is_free(m,id) (pw_map_item_is_free(pw_map_get_item(m,id))) +/** \return true if the id fits within the current map size */ +#define pw_map_check_id(m,id) ((id) < pw_map_get_size(m)) +/** \return true if there is a valid item at \a id */ +#define pw_map_has_item(m,id) (pw_map_check_id(m,id) && !pw_map_id_is_free(m, id)) +#define pw_map_lookup_unchecked(m,id) pw_map_get_item(m,id)->data + +/** Convert an id to a pointer that can be inserted into the map */ +#define PW_MAP_ID_TO_PTR(id) (SPA_UINT32_TO_PTR((id)<<1)) +/** Convert a pointer to an id that can be retrieved from the map */ +#define PW_MAP_PTR_TO_ID(p) (SPA_PTR_TO_UINT32(p)>>1) + +/** Initialize a map + * \param map the map to initialize + * \param size the initial size of the map + * \param extend the amount to bytes to grow the map with when needed + */ +static inline void pw_map_init(struct pw_map *map, size_t size, size_t extend) +{ + pw_array_init(&map->items, extend * sizeof(union pw_map_item)); + pw_array_ensure_size(&map->items, size * sizeof(union pw_map_item)); + map->free_list = SPA_ID_INVALID; +} + +/** Clear a map and free the data storage. All previously returned ids + * must be treated as invalid. + */ +static inline void pw_map_clear(struct pw_map *map) +{ + pw_array_clear(&map->items); +} + +/** Reset a map but keep previously allocated storage. All previously + * returned ids must be treated as invalid. + */ +static inline void pw_map_reset(struct pw_map *map) +{ + pw_array_reset(&map->items); + map->free_list = SPA_ID_INVALID; +} + +/** Insert data in the map. This function causes the map to grow if required. + * \param map the map to insert into + * \param data the item to add + * \return the id where the item was inserted or SPA_ID_INVALID when the + * item can not be inserted. + */ +static inline uint32_t pw_map_insert_new(struct pw_map *map, void *data) +{ + union pw_map_item *start, *item; + uint32_t id; + + if (map->free_list != SPA_ID_INVALID) { + start = (union pw_map_item *) map->items.data; + item = &start[map->free_list >> 1]; /* lsb always 1, see pw_map_remove */ + map->free_list = item->next; + } else { + item = (union pw_map_item *) pw_array_add(&map->items, sizeof(union pw_map_item)); + if (item == NULL) + return SPA_ID_INVALID; + start = (union pw_map_item *) map->items.data; + } + item->data = data; + id = (item - start); + return id; +} + +/** Replace the data in the map at an index. + * + * \param map the map to insert into + * \param id the index to insert at, must be less or equal to pw_map_get_size() + * \param data the data to insert + * \return 0 on success, -ENOSPC value when the index is invalid or a negative errno + */ +static inline int pw_map_insert_at(struct pw_map *map, uint32_t id, void *data) +{ + size_t size = pw_map_get_size(map); + union pw_map_item *item; + + if (id > size) + return -ENOSPC; + else if (id == size) { + item = (union pw_map_item *) pw_array_add(&map->items, sizeof(union pw_map_item)); + if (item == NULL) + return -errno; + } else { + item = pw_map_get_item(map, id); + if (pw_map_item_is_free(item)) + return -EINVAL; + } + item->data = data; + return 0; +} + +/** Remove an item at index. The id may get re-used in the future. + * + * \param map the map to remove from + * \param id the index to remove + */ +static inline void pw_map_remove(struct pw_map *map, uint32_t id) +{ + if (pw_map_id_is_free(map, id)) + return; + + pw_map_get_item(map, id)->next = map->free_list; + map->free_list = (id << 1) | 1; +} + +/** Find an item in the map + * \param map the map to use + * \param id the index to look at + * \return the item at \a id or NULL when no such item exists + */ +static inline void *pw_map_lookup(const struct pw_map *map, uint32_t id) +{ + if (SPA_LIKELY(pw_map_check_id(map, id))) { + union pw_map_item *item = pw_map_get_item(map, id); + if (!pw_map_item_is_free(item)) + return item->data; + } + return NULL; +} + +/** Iterate all map items + * \param map the map to iterate + * \param func the function to call for each item, the item data and \a data is + * passed to the function. When \a func returns a non-zero result, + * iteration ends and the result is returned. + * \param data data to pass to \a func + * \return the result of the last call to \a func or 0 when all callbacks returned 0. + */ +static inline int pw_map_for_each(const struct pw_map *map, + int (*func) (void *item_data, void *data), void *data) +{ + union pw_map_item *item; + int res = 0; + + pw_array_for_each(item, &map->items) { + if (!pw_map_item_is_free(item)) + if ((res = func(item->data, data)) != 0) + break; + } + return res; +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_MAP_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/mem.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/mem.h new file mode 100644 index 000000000000..55e260c22ffd --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/mem.h @@ -0,0 +1,192 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_MEM_H +#define PIPEWIRE_MEM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup pw_memblock Memory Blocks + * Memory allocation and pools. + */ + +/** + * \addtogroup pw_memblock + * \{ + */ + +/** Flags passed to \ref pw_mempool_alloc() */ +enum pw_memblock_flags { + PW_MEMBLOCK_FLAG_NONE = 0, + PW_MEMBLOCK_FLAG_READABLE = (1 << 0), /**< memory is readable */ + PW_MEMBLOCK_FLAG_WRITABLE = (1 << 1), /**< memory is writable */ + PW_MEMBLOCK_FLAG_SEAL = (1 << 2), /**< seal the fd */ + PW_MEMBLOCK_FLAG_MAP = (1 << 3), /**< mmap the fd */ + PW_MEMBLOCK_FLAG_DONT_CLOSE = (1 << 4), /**< don't close fd */ + PW_MEMBLOCK_FLAG_DONT_NOTIFY = (1 << 5), /**< don't notify events */ + + PW_MEMBLOCK_FLAG_READWRITE = PW_MEMBLOCK_FLAG_READABLE | PW_MEMBLOCK_FLAG_WRITABLE, +}; + +enum pw_memmap_flags { + PW_MEMMAP_FLAG_NONE = 0, + PW_MEMMAP_FLAG_READ = (1 << 0), /**< map in read mode */ + PW_MEMMAP_FLAG_WRITE = (1 << 1), /**< map in write mode */ + PW_MEMMAP_FLAG_TWICE = (1 << 2), /**< map the same area twice after each other, + * creating a circular ringbuffer */ + PW_MEMMAP_FLAG_PRIVATE = (1 << 3), /**< writes will be private */ + PW_MEMMAP_FLAG_LOCKED = (1 << 4), /**< lock the memory into RAM */ + PW_MEMMAP_FLAG_READWRITE = PW_MEMMAP_FLAG_READ | PW_MEMMAP_FLAG_WRITE, +}; + +struct pw_memchunk; + +/** + * + * A memory pool is a collection of pw_memblocks */ +struct pw_mempool { + struct pw_properties *props; +}; + +/** + * Memory block structure */ +struct pw_memblock { + struct pw_mempool *pool; /**< owner pool */ + uint32_t id; /**< unique id */ + int ref; /**< refcount */ + uint32_t flags; /**< flags for the memory block on of enum pw_memblock_flags */ + uint32_t type; /**< type of the fd, one of enum spa_data_type */ + int fd; /**< fd */ + uint32_t size; /**< size of memory */ + struct pw_memmap *map; /**< optional map when PW_MEMBLOCK_FLAG_MAP was given */ +}; + +/** a mapped region of a pw_memblock */ +struct pw_memmap { + struct pw_memblock *block; /**< owner memblock */ + void *ptr; /**< mapped pointer */ + uint32_t flags; /**< flags for the mapping on of enum pw_memmap_flags */ + uint32_t offset; /**< offset in memblock */ + uint32_t size; /**< size in memblock */ + uint32_t tag[5]; /**< user tag */ +}; + +struct pw_mempool_events { +#define PW_VERSION_MEMPOOL_EVENTS 0 + uint32_t version; + + /** the pool is destroyed */ + void (*destroy) (void *data); + + /** a new memory block is added to the pool */ + void (*added) (void *data, struct pw_memblock *block); + + /** a memory block is removed from the pool */ + void (*removed) (void *data, struct pw_memblock *block); +}; + +/** Create a new memory pool */ +struct pw_mempool *pw_mempool_new(struct pw_properties *props); + +/** Listen for events */ +void pw_mempool_add_listener(struct pw_mempool *pool, + struct spa_hook *listener, + const struct pw_mempool_events *events, + void *data); + +/** Clear a pool */ +void pw_mempool_clear(struct pw_mempool *pool); + +/** Clear and destroy a pool */ +void pw_mempool_destroy(struct pw_mempool *pool); + + +/** Allocate a memory block from the pool */ +struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, + enum pw_memblock_flags flags, uint32_t type, size_t size); + +/** Import a block from another pool */ +struct pw_memblock * pw_mempool_import_block(struct pw_mempool *pool, + struct pw_memblock *mem); + +/** Import an fd into the pool */ +struct pw_memblock * pw_mempool_import(struct pw_mempool *pool, + enum pw_memblock_flags flags, uint32_t type, int fd); + +/** Free a memblock regardless of the refcount and destroy all mappings */ +void pw_memblock_free(struct pw_memblock *mem); + +/** Unref a memblock */ +static inline void pw_memblock_unref(struct pw_memblock *mem) +{ + if (--mem->ref == 0) + pw_memblock_free(mem); +} + +/** Remove a memblock for given \a id */ +int pw_mempool_remove_id(struct pw_mempool *pool, uint32_t id); + +/** Find memblock for given \a ptr */ +struct pw_memblock * pw_mempool_find_ptr(struct pw_mempool *pool, const void *ptr); + +/** Find memblock for given \a id */ +struct pw_memblock * pw_mempool_find_id(struct pw_mempool *pool, uint32_t id); + +/** Find memblock for given \a fd */ +struct pw_memblock * pw_mempool_find_fd(struct pw_mempool *pool, int fd); + + +/** Map a region of a memory block */ +struct pw_memmap * pw_memblock_map(struct pw_memblock *block, + enum pw_memmap_flags flags, uint32_t offset, uint32_t size, + uint32_t tag[5]); + +/** Map a region of a memory block with \a id */ +struct pw_memmap * pw_mempool_map_id(struct pw_mempool *pool, uint32_t id, + enum pw_memmap_flags flags, uint32_t offset, uint32_t size, + uint32_t tag[5]); + +struct pw_memmap * pw_mempool_import_map(struct pw_mempool *pool, + struct pw_mempool *other, void *data, uint32_t size, uint32_t tag[5]); + +/** find a map with the given tag */ +struct pw_memmap * pw_mempool_find_tag(struct pw_mempool *pool, uint32_t tag[5], size_t size); + +/** Unmap a region */ +int pw_memmap_free(struct pw_memmap *map); + + +/** parameters to map a memory range */ +struct pw_map_range { + uint32_t start; /** offset in first page with start of data */ + uint32_t offset; /** page aligned offset to map */ + uint32_t size; /** size to map */ +}; + +#define PW_MAP_RANGE_INIT (struct pw_map_range){ 0, } + +/** Calculate parameters to mmap() memory into \a range so that + * \a size bytes at \a offset can be mapped with mmap(). */ +static inline void pw_map_range_init(struct pw_map_range *range, + uint32_t offset, uint32_t size, + uint32_t page_size) +{ + range->offset = SPA_ROUND_DOWN_N(offset, page_size); + range->start = offset - range->offset; + range->size = SPA_ROUND_UP_N(range->start + size, page_size); +} + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_MEM_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/module.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/module.h new file mode 100644 index 000000000000..bd4eca61645d --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/module.h @@ -0,0 +1,103 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_MODULE_H +#define PIPEWIRE_MODULE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +/** \defgroup pw_module Module + * Module interface + */ + +/** + * \addtogroup pw_module + * \{ + */ +#define PW_TYPE_INTERFACE_Module PW_TYPE_INFO_INTERFACE_BASE "Module" + +#define PW_MODULE_PERM_MASK PW_PERM_R|PW_PERM_M + +#define PW_VERSION_MODULE 3 +struct pw_module; + +/** The module information. Extra information can be added in later versions */ +struct pw_module_info { + uint32_t id; /**< id of the global */ + const char *name; /**< name of the module */ + const char *filename; /**< filename of the module */ + const char *args; /**< arguments passed to the module */ +#define PW_MODULE_CHANGE_MASK_PROPS (1 << 0) +#define PW_MODULE_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< extra properties */ +}; + +/** Update and existing \ref pw_module_info with \a update with reset */ +struct pw_module_info * +pw_module_info_update(struct pw_module_info *info, + const struct pw_module_info *update); +/** Merge and existing \ref pw_module_info with \a update */ +struct pw_module_info * +pw_module_info_merge(struct pw_module_info *info, + const struct pw_module_info *update, bool reset); +/** Free a \ref pw_module_info */ +void pw_module_info_free(struct pw_module_info *info); + +#define PW_MODULE_EVENT_INFO 0 +#define PW_MODULE_EVENT_NUM 1 + +/** Module events */ +struct pw_module_events { +#define PW_VERSION_MODULE_EVENTS 0 + uint32_t version; + /** + * Notify module info + * + * \param info info about the module + */ + void (*info) (void *data, const struct pw_module_info *info); +}; + +#define PW_MODULE_METHOD_ADD_LISTENER 0 +#define PW_MODULE_METHOD_NUM 1 + +/** Module methods */ +struct pw_module_methods { +#define PW_VERSION_MODULE_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_module_events *events, + void *data); +}; + +#define pw_module_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_module_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_module_add_listener(c,...) pw_module_method(c,add_listener,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_MODULE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/node.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/node.h new file mode 100644 index 000000000000..87ba1a06ed53 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/node.h @@ -0,0 +1,206 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_NODE_H +#define PIPEWIRE_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include +#include +#include + +#include + +/** \defgroup pw_node Node + * Node interface + */ + +/** + * \addtogroup pw_node + * \{ + */ +#define PW_TYPE_INTERFACE_Node PW_TYPE_INFO_INTERFACE_BASE "Node" + +#define PW_NODE_PERM_MASK PW_PERM_RWXML + +#define PW_VERSION_NODE 3 +struct pw_node; + +/** \enum pw_node_state The different node states */ +enum pw_node_state { + PW_NODE_STATE_ERROR = -1, /**< error state */ + PW_NODE_STATE_CREATING = 0, /**< the node is being created */ + PW_NODE_STATE_SUSPENDED = 1, /**< the node is suspended, the device might + * be closed */ + PW_NODE_STATE_IDLE = 2, /**< the node is running but there is no active + * port */ + PW_NODE_STATE_RUNNING = 3, /**< the node is running */ +}; + +/** Convert a \ref pw_node_state to a readable string */ +const char * pw_node_state_as_string(enum pw_node_state state); + +/** The node information. Extra information can be added in later versions */ +struct pw_node_info { + uint32_t id; /**< id of the global */ + uint32_t max_input_ports; /**< maximum number of inputs */ + uint32_t max_output_ports; /**< maximum number of outputs */ +#define PW_NODE_CHANGE_MASK_INPUT_PORTS (1 << 0) +#define PW_NODE_CHANGE_MASK_OUTPUT_PORTS (1 << 1) +#define PW_NODE_CHANGE_MASK_STATE (1 << 2) +#define PW_NODE_CHANGE_MASK_PROPS (1 << 3) +#define PW_NODE_CHANGE_MASK_PARAMS (1 << 4) +#define PW_NODE_CHANGE_MASK_ALL ((1 << 5)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + uint32_t n_input_ports; /**< number of inputs */ + uint32_t n_output_ports; /**< number of outputs */ + enum pw_node_state state; /**< the current state of the node */ + const char *error; /**< an error reason if \a state is error */ + struct spa_dict *props; /**< the properties of the node */ + struct spa_param_info *params; /**< parameters */ + uint32_t n_params; /**< number of items in \a params */ +}; + +struct pw_node_info * +pw_node_info_update(struct pw_node_info *info, + const struct pw_node_info *update); + +struct pw_node_info * +pw_node_info_merge(struct pw_node_info *info, + const struct pw_node_info *update, bool reset); + +void +pw_node_info_free(struct pw_node_info *info); + +#define PW_NODE_EVENT_INFO 0 +#define PW_NODE_EVENT_PARAM 1 +#define PW_NODE_EVENT_NUM 2 + +/** Node events */ +struct pw_node_events { +#define PW_VERSION_NODE_EVENTS 0 + uint32_t version; + /** + * Notify node info + * + * \param info info about the node + */ + void (*info) (void *data, const struct pw_node_info *info); + /** + * Notify a node param + * + * Event emitted as a result of the enum_params method. + * + * \param seq the sequence number of the request + * \param id the param id + * \param index the param index + * \param next the param index of the next param + * \param param the parameter + */ + void (*param) (void *data, int seq, + uint32_t id, uint32_t index, uint32_t next, + const struct spa_pod *param); +}; + +#define PW_NODE_METHOD_ADD_LISTENER 0 +#define PW_NODE_METHOD_SUBSCRIBE_PARAMS 1 +#define PW_NODE_METHOD_ENUM_PARAMS 2 +#define PW_NODE_METHOD_SET_PARAM 3 +#define PW_NODE_METHOD_SEND_COMMAND 4 +#define PW_NODE_METHOD_NUM 5 + +/** Node methods */ +struct pw_node_methods { +#define PW_VERSION_NODE_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_node_events *events, + void *data); + /** + * Subscribe to parameter changes + * + * Automatically emit param events for the given ids when + * they are changed. + * + * \param ids an array of param ids + * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the node. + */ + int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); + + /** + * Enumerate node parameters + * + * Start enumeration of node parameters. For each param, a + * param event will be emitted. + * + * \param seq a sequence number to place in the reply + * \param id the parameter id to enum or PW_ID_ANY for all + * \param start the start index or 0 for the first param + * \param num the maximum number of params to retrieve + * \param filter a param filter or NULL + * + * This requires X permissions on the node. + */ + int (*enum_params) (void *object, int seq, uint32_t id, + uint32_t start, uint32_t num, + const struct spa_pod *filter); + + /** + * Set a parameter on the node + * + * \param id the parameter id to set + * \param flags extra parameter flags + * \param param the parameter to set + * + * This requires X and W permissions on the node. + */ + int (*set_param) (void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param); + + /** + * Send a command to the node + * + * \param command the command to send + * + * This requires X and W permissions on the node. + */ + int (*send_command) (void *object, const struct spa_command *command); +}; + +#define pw_node_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_node_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +/** Node */ +#define pw_node_add_listener(c,...) pw_node_method(c,add_listener,0,__VA_ARGS__) +#define pw_node_subscribe_params(c,...) pw_node_method(c,subscribe_params,0,__VA_ARGS__) +#define pw_node_enum_params(c,...) pw_node_method(c,enum_params,0,__VA_ARGS__) +#define pw_node_set_param(c,...) pw_node_method(c,set_param,0,__VA_ARGS__) +#define pw_node_send_command(c,...) pw_node_method(c,send_command,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_NODE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/permission.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/permission.h new file mode 100644 index 000000000000..22eebdb26caa --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/permission.h @@ -0,0 +1,72 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_PERMISSION_H +#define PIPEWIRE_PERMISSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \defgroup pw_permission Permission + * + * Permissions are kept for a client and describe what the client is + * allowed to do with an object. + * + * See \ref page_core_api + */ + +/** + * \addtogroup pw_permission + * \{ + */ + +#define PW_PERM_R 0400 /**< object can be seen and events can be received */ +#define PW_PERM_W 0200 /**< methods can be called that modify the object */ +#define PW_PERM_X 0100 /**< methods can be called on the object. The W flag must be + * present in order to call methods that modify the object. */ +#define PW_PERM_M 0010 /**< metadata can be set on object, Since 0.3.9 */ +#define PW_PERM_L 0020 /**< a link can be made between a node that doesn't have + * permission to see the other node, Since 0.3.77 */ + +#define PW_PERM_RW (PW_PERM_R|PW_PERM_W) +#define PW_PERM_RWX (PW_PERM_RW|PW_PERM_X) +#define PW_PERM_RWXM (PW_PERM_RWX|PW_PERM_M) +#define PW_PERM_RWXML (PW_PERM_RWXM|PW_PERM_L) + +#define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R) +#define PW_PERM_IS_W(p) (((p)&PW_PERM_W) == PW_PERM_W) +#define PW_PERM_IS_X(p) (((p)&PW_PERM_X) == PW_PERM_X) +#define PW_PERM_IS_M(p) (((p)&PW_PERM_M) == PW_PERM_M) +#define PW_PERM_IS_L(p) (((p)&PW_PERM_L) == PW_PERM_L) + +#define PW_PERM_ALL PW_PERM_RWXM +#define PW_PERM_INVALID (uint32_t)(0xffffffff) + +struct pw_permission { + uint32_t id; /**< id of object, PW_ID_ANY for default permission */ + uint32_t permissions; /**< bitmask of above permissions */ +}; + +#define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) }) + +#define PW_PERMISSION_FORMAT "%c%c%c%c%c" +#define PW_PERMISSION_ARGS(permission) \ + (permission) & PW_PERM_R ? 'r' : '-', \ + (permission) & PW_PERM_W ? 'w' : '-', \ + (permission) & PW_PERM_X ? 'x' : '-', \ + (permission) & PW_PERM_M ? 'm' : '-', \ + (permission) & PW_PERM_L ? 'l' : '-' + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_PERMISSION_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h new file mode 100644 index 000000000000..0c495ed39f22 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/pipewire.h @@ -0,0 +1,101 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_H +#define PIPEWIRE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** \defgroup pw_pipewire Initialization + * Initializing PipeWire and loading SPA modules. + */ + +/** + * \addtogroup pw_pipewire + * \{ + */ +void +pw_init(int *argc, char **argv[]); + +void pw_deinit(void); + +bool +pw_debug_is_category_enabled(const char *name); + +const char * +pw_get_application_name(void); + +const char * +pw_get_prgname(void); + +const char * +pw_get_user_name(void); + +const char * +pw_get_host_name(void); + +const char * +pw_get_client_name(void); + +bool pw_check_option(const char *option, const char *value); + +enum pw_direction +pw_direction_reverse(enum pw_direction direction); + +int pw_set_domain(const char *domain); +const char *pw_get_domain(void); + +uint32_t pw_get_support(struct spa_support *support, uint32_t max_support); + +struct spa_handle *pw_load_spa_handle(const char *lib, + const char *factory_name, + const struct spa_dict *info, + uint32_t n_support, + const struct spa_support support[]); + +int pw_unload_spa_handle(struct spa_handle *handle); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/port.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/port.h new file mode 100644 index 000000000000..d0ada8b73e0d --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/port.h @@ -0,0 +1,165 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_PORT_H +#define PIPEWIRE_PORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include +#include + +#include + +/** \defgroup pw_port Port + * Port interface + */ + +/** + * \addtogroup pw_port + * \{ + */ + +#define PW_TYPE_INTERFACE_Port PW_TYPE_INFO_INTERFACE_BASE "Port" + +#define PW_PORT_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M + +#define PW_VERSION_PORT 3 +struct pw_port; + +/** The direction of a port */ +#define pw_direction spa_direction +#define PW_DIRECTION_INPUT SPA_DIRECTION_INPUT +#define PW_DIRECTION_OUTPUT SPA_DIRECTION_OUTPUT + +/** Convert a \ref pw_direction to a readable string */ +const char * pw_direction_as_string(enum pw_direction direction); + +struct pw_port_info { + uint32_t id; /**< id of the global */ + enum pw_direction direction; /**< port direction */ +#define PW_PORT_CHANGE_MASK_PROPS (1 << 0) +#define PW_PORT_CHANGE_MASK_PARAMS (1 << 1) +#define PW_PORT_CHANGE_MASK_ALL ((1 << 2)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< the properties of the port */ + struct spa_param_info *params; /**< parameters */ + uint32_t n_params; /**< number of items in \a params */ +}; + +struct pw_port_info * +pw_port_info_update(struct pw_port_info *info, + const struct pw_port_info *update); + +struct pw_port_info * +pw_port_info_merge(struct pw_port_info *info, + const struct pw_port_info *update, bool reset); + +void +pw_port_info_free(struct pw_port_info *info); + +#define PW_PORT_EVENT_INFO 0 +#define PW_PORT_EVENT_PARAM 1 +#define PW_PORT_EVENT_NUM 2 + +/** Port events */ +struct pw_port_events { +#define PW_VERSION_PORT_EVENTS 0 + uint32_t version; + /** + * Notify port info + * + * \param info info about the port + */ + void (*info) (void *data, const struct pw_port_info *info); + /** + * Notify a port param + * + * Event emitted as a result of the enum_params method. + * + * \param seq the sequence number of the request + * \param id the param id + * \param index the param index + * \param next the param index of the next param + * \param param the parameter + */ + void (*param) (void *data, int seq, + uint32_t id, uint32_t index, uint32_t next, + const struct spa_pod *param); +}; + +#define PW_PORT_METHOD_ADD_LISTENER 0 +#define PW_PORT_METHOD_SUBSCRIBE_PARAMS 1 +#define PW_PORT_METHOD_ENUM_PARAMS 2 +#define PW_PORT_METHOD_NUM 3 + +/** Port methods */ +struct pw_port_methods { +#define PW_VERSION_PORT_METHODS 0 + uint32_t version; + + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct pw_port_events *events, + void *data); + /** + * Subscribe to parameter changes + * + * Automatically emit param events for the given ids when + * they are changed. + * + * \param ids an array of param ids + * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the port. + */ + int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); + + /** + * Enumerate port parameters + * + * Start enumeration of port parameters. For each param, a + * param event will be emitted. + * + * \param seq a sequence number returned in the reply + * \param id the parameter id to enumerate + * \param start the start index or 0 for the first param + * \param num the maximum number of params to retrieve + * \param filter a param filter or NULL + * + * This requires X permissions on the port. + */ + int (*enum_params) (void *object, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter); +}; + +#define pw_port_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)o, \ + struct pw_port_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define pw_port_add_listener(c,...) pw_port_method(c,add_listener,0,__VA_ARGS__) +#define pw_port_subscribe_params(c,...) pw_port_method(c,subscribe_params,0,__VA_ARGS__) +#define pw_port_enum_params(c,...) pw_port_method(c,enum_params,0,__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_PORT_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/properties.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/properties.h new file mode 100644 index 000000000000..13963c1cdae0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/properties.h @@ -0,0 +1,183 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_PROPERTIES_H +#define PIPEWIRE_PROPERTIES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +/** \defgroup pw_properties Properties + * + * Properties are used to pass around arbitrary key/value pairs. + * Both keys and values are strings which keeps things simple. + * Encoding of arbitrary values should be done by using a string + * serialization such as base64 for binary blobs. + */ + +/** + * \addtogroup pw_properties + * \{ + */ +struct pw_properties { + struct spa_dict dict; /**< dictionary of key/values */ + uint32_t flags; /**< extra flags */ +}; + +struct pw_properties * +pw_properties_new(const char *key, ...) SPA_SENTINEL; + +struct pw_properties * +pw_properties_new_dict(const struct spa_dict *dict); + +struct pw_properties * +pw_properties_new_string(const char *args); + +struct pw_properties * +pw_properties_copy(const struct pw_properties *properties); + +int pw_properties_update_keys(struct pw_properties *props, + const struct spa_dict *dict, const char * const keys[]); +int pw_properties_update_ignore(struct pw_properties *props, + const struct spa_dict *dict, const char * const ignore[]); + +/* Update props with all key/value pairs from dict */ +int pw_properties_update(struct pw_properties *props, + const struct spa_dict *dict); +/* Update props with all key/value pairs from str */ +int pw_properties_update_string(struct pw_properties *props, + const char *str, size_t size); + +int pw_properties_add(struct pw_properties *oldprops, + const struct spa_dict *dict); +int pw_properties_add_keys(struct pw_properties *oldprops, + const struct spa_dict *dict, const char * const keys[]); + +void pw_properties_clear(struct pw_properties *properties); + +void +pw_properties_free(struct pw_properties *properties); + +int +pw_properties_set(struct pw_properties *properties, const char *key, const char *value); + +int +pw_properties_setf(struct pw_properties *properties, + const char *key, const char *format, ...) SPA_PRINTF_FUNC(3, 4); +int +pw_properties_setva(struct pw_properties *properties, + const char *key, const char *format, va_list args) SPA_PRINTF_FUNC(3,0); +const char * +pw_properties_get(const struct pw_properties *properties, const char *key); + +int +pw_properties_fetch_uint32(const struct pw_properties *properties, const char *key, uint32_t *value); + +int +pw_properties_fetch_int32(const struct pw_properties *properties, const char *key, int32_t *value); + +int +pw_properties_fetch_uint64(const struct pw_properties *properties, const char *key, uint64_t *value); + +int +pw_properties_fetch_int64(const struct pw_properties *properties, const char *key, int64_t *value); + +int +pw_properties_fetch_bool(const struct pw_properties *properties, const char *key, bool *value); + +static inline uint32_t +pw_properties_get_uint32(const struct pw_properties *properties, const char *key, uint32_t deflt) +{ + uint32_t val = deflt; + pw_properties_fetch_uint32(properties, key, &val); + return val; +} + +static inline int32_t +pw_properties_get_int32(const struct pw_properties *properties, const char *key, int32_t deflt) +{ + int32_t val = deflt; + pw_properties_fetch_int32(properties, key, &val); + return val; +} + +static inline uint64_t +pw_properties_get_uint64(const struct pw_properties *properties, const char *key, uint64_t deflt) +{ + uint64_t val = deflt; + pw_properties_fetch_uint64(properties, key, &val); + return val; +} + +static inline int64_t +pw_properties_get_int64(const struct pw_properties *properties, const char *key, int64_t deflt) +{ + int64_t val = deflt; + pw_properties_fetch_int64(properties, key, &val); + return val; +} + + +static inline bool +pw_properties_get_bool(const struct pw_properties *properties, const char *key, bool deflt) +{ + bool val = deflt; + pw_properties_fetch_bool(properties, key, &val); + return val; +} + +const char * +pw_properties_iterate(const struct pw_properties *properties, void **state); + +#define PW_PROPERTIES_FLAG_NL (1<<0) +#define PW_PROPERTIES_FLAG_RECURSE (1<<1) +#define PW_PROPERTIES_FLAG_ENCLOSE (1<<2) +#define PW_PROPERTIES_FLAG_ARRAY (1<<3) +#define PW_PROPERTIES_FLAG_COLORS (1<<4) +int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t flags); + +static inline bool pw_properties_parse_bool(const char *value) { + return spa_atob(value); +} + +static inline int pw_properties_parse_int(const char *value) { + int v; + return spa_atoi32(value, &v, 0) ? v: 0; +} + +static inline int64_t pw_properties_parse_int64(const char *value) { + int64_t v; + return spa_atoi64(value, &v, 0) ? v : 0; +} + +static inline uint64_t pw_properties_parse_uint64(const char *value) { + uint64_t v; + return spa_atou64(value, &v, 0) ? v : 0; +} + +static inline float pw_properties_parse_float(const char *value) { + float v; + return spa_atof(value, &v) ? v : 0.0f; +} + +static inline double pw_properties_parse_double(const char *value) { + double v; + return spa_atod(value, &v) ? v : 0.0; +} + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_PROPERTIES_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/protocol.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/protocol.h new file mode 100644 index 000000000000..8cd9c7bcf58f --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/protocol.h @@ -0,0 +1,142 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_PROTOCOL_H +#define PIPEWIRE_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \defgroup pw_protocol Protocol + * + * \brief Manages protocols and their implementation + */ + +/** + * \addtogroup pw_protocol + * \{ + */ + +struct pw_protocol; + +#include +#include +#include + +#define PW_TYPE_INFO_Protocol "PipeWire:Protocol" +#define PW_TYPE_INFO_PROTOCOL_BASE PW_TYPE_INFO_Protocol ":" + +struct pw_protocol_client { + struct spa_list link; /**< link in protocol client_list */ + struct pw_protocol *protocol; /**< the owner protocol */ + + struct pw_core *core; + + int (*connect) (struct pw_protocol_client *client, + const struct spa_dict *props, + void (*done_callback) (void *data, int result), + void *data); + int (*connect_fd) (struct pw_protocol_client *client, int fd, bool close); + int (*steal_fd) (struct pw_protocol_client *client); + void (*disconnect) (struct pw_protocol_client *client); + void (*destroy) (struct pw_protocol_client *client); + int (*set_paused) (struct pw_protocol_client *client, bool paused); +}; + +#define pw_protocol_client_connect(c,p,cb,d) ((c)->connect(c,p,cb,d)) +#define pw_protocol_client_connect_fd(c,fd,cl) ((c)->connect_fd(c,fd,cl)) +#define pw_protocol_client_steal_fd(c) ((c)->steal_fd(c)) +#define pw_protocol_client_disconnect(c) ((c)->disconnect(c)) +#define pw_protocol_client_destroy(c) ((c)->destroy(c)) +#define pw_protocol_client_set_paused(c,p) ((c)->set_paused(c,p)) + +struct pw_protocol_server { + struct spa_list link; /**< link in protocol server_list */ + struct pw_protocol *protocol; /**< the owner protocol */ + + struct pw_impl_core *core; + + struct spa_list client_list; /**< list of clients of this protocol */ + + void (*destroy) (struct pw_protocol_server *listen); +}; + +#define pw_protocol_server_destroy(l) ((l)->destroy(l)) + +struct pw_protocol_marshal { + const char *type; /**< interface type */ + uint32_t version; /**< version */ +#define PW_PROTOCOL_MARSHAL_FLAG_IMPL (1 << 0) /**< marshal for implementations */ + uint32_t flags; /**< version */ + uint32_t n_client_methods; /**< number of client methods */ + uint32_t n_server_methods; /**< number of server methods */ + const void *client_marshal; + const void *server_demarshal; + const void *server_marshal; + const void *client_demarshal; +}; + +struct pw_protocol_implementation { +#define PW_VERSION_PROTOCOL_IMPLEMENTATION 0 + uint32_t version; + + struct pw_protocol_client * (*new_client) (struct pw_protocol *protocol, + struct pw_core *core, + const struct spa_dict *props); + struct pw_protocol_server * (*add_server) (struct pw_protocol *protocol, + struct pw_impl_core *core, + const struct spa_dict *props); +}; + +struct pw_protocol_events { +#define PW_VERSION_PROTOCOL_EVENTS 0 + uint32_t version; + + void (*destroy) (void *data); +}; + +#define pw_protocol_new_client(p,...) (pw_protocol_get_implementation(p)->new_client(p,__VA_ARGS__)) +#define pw_protocol_add_server(p,...) (pw_protocol_get_implementation(p)->add_server(p,__VA_ARGS__)) +#define pw_protocol_ext(p,type,method,...) (((type*)pw_protocol_get_extension(p))->method( __VA_ARGS__)) + +struct pw_protocol *pw_protocol_new(struct pw_context *context, const char *name, size_t user_data_size); + +void pw_protocol_destroy(struct pw_protocol *protocol); + +struct pw_context *pw_protocol_get_context(struct pw_protocol *protocol); + +void *pw_protocol_get_user_data(struct pw_protocol *protocol); + +const struct pw_protocol_implementation * +pw_protocol_get_implementation(struct pw_protocol *protocol); + +const void * +pw_protocol_get_extension(struct pw_protocol *protocol); + + +void pw_protocol_add_listener(struct pw_protocol *protocol, + struct spa_hook *listener, + const struct pw_protocol_events *events, + void *data); + +int pw_protocol_add_marshal(struct pw_protocol *protocol, + const struct pw_protocol_marshal *marshal); + +const struct pw_protocol_marshal * +pw_protocol_get_marshal(struct pw_protocol *protocol, const char *type, uint32_t version, uint32_t flags); + +struct pw_protocol * pw_context_find_protocol(struct pw_context *context, const char *name); + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_PROTOCOL_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/proxy.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/proxy.h new file mode 100644 index 000000000000..b46c417253f4 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/proxy.h @@ -0,0 +1,203 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_PROXY_H +#define PIPEWIRE_PROXY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \page page_proxy Proxy + * + * \see \ref pw_proxy + * + * \section sec_page_proxy_overview Overview + * + * The proxy object is a client side representation of a resource + * that lives on a remote PipeWire instance. + * + * It is used to communicate with the remote object. + * + * \section sec_page_proxy_core Core proxy + * + * A proxy for a remote core object can be obtained by making + * a remote connection with \ref pw_context_connect. + * See \ref pw_proxy + * + * Some methods on proxy object allow creation of more proxy objects or + * create a binding between a local proxy and global resource. + * + * \section sec_page_proxy_create Create + * + * A client first creates a new proxy object with pw_proxy_new(). A + * type must be provided for this object. + * + * The protocol of the context will usually install an interface to + * translate method calls and events to the wire format. + * + * The creator of the proxy will usually also install an event + * implementation of the particular object type. + * + * \section sec_page_proxy_bind Bind + * + * To actually use the proxy object, one needs to create a server + * side resource for it. This can be done by, for example, binding + * to a global object or by calling a method that creates and binds + * to a new remote object. In all cases, the local id is passed to + * the server and is used to create a resource with the same id. + * + * \section sec_page_proxy_methods Methods + * + * To call a method on the proxy use the interface methods. Calling + * any interface method will result in a request to the server to + * perform the requested action on the corresponding resource. + * + * \section sec_page_proxy_events Events + * + * Events send from the server to the proxy will be demarshalled by + * the protocol and will then result in a call to the installed + * implementation of the proxy. + * + * \section sec_page_proxy_destroy Destroy + * + * Use pw_proxy_destroy() to destroy the client side object. This + * is usually done automatically when the server removes the resource + * associated to the proxy. + */ + +/** \defgroup pw_proxy Proxy + * + * \brief Represents an object on the client side. + * + * A pw_proxy acts as a client side proxy to an object existing in a remote + * pipewire instance. The proxy is responsible for converting interface functions + * invoked by the client to PipeWire messages. Events will call the handlers + * set in listener. + * + * \see \ref page_proxy + */ + +/** + * \addtogroup pw_proxy + * \{ + */ +struct pw_proxy; + +#include + +/** Proxy events, use \ref pw_proxy_add_listener */ +struct pw_proxy_events { +#define PW_VERSION_PROXY_EVENTS 1 + uint32_t version; + + /** The proxy is destroyed */ + void (*destroy) (void *data); + + /** a proxy is bound to a global id */ + void (*bound) (void *data, uint32_t global_id); + + /** a proxy is removed from the server. Use pw_proxy_destroy to + * free the proxy. */ + void (*removed) (void *data); + + /** a reply to a sync method completed */ + void (*done) (void *data, int seq); + + /** an error occurred on the proxy */ + void (*error) (void *data, int seq, int res, const char *message); + + void (*bound_props) (void *data, uint32_t global_id, const struct spa_dict *props); +}; + +/* Make a new proxy object. The id can be used to bind to a remote object and + * can be retrieved with \ref pw_proxy_get_id . */ +struct pw_proxy * +pw_proxy_new(struct pw_proxy *factory, + const char *type, /* interface type */ + uint32_t version, /* interface version */ + size_t user_data_size /* size of user data */); + +/** Add an event listener to proxy */ +void pw_proxy_add_listener(struct pw_proxy *proxy, + struct spa_hook *listener, + const struct pw_proxy_events *events, + void *data); + +/** Add a listener for the events received from the remote object. The + * events depend on the type of the remote object type. */ +void pw_proxy_add_object_listener(struct pw_proxy *proxy, /**< the proxy */ + struct spa_hook *listener, /**< listener */ + const void *funcs, /**< proxied functions */ + void *data /**< data passed to events */); + +/** destroy a proxy */ +void pw_proxy_destroy(struct pw_proxy *proxy); + +void pw_proxy_ref(struct pw_proxy *proxy); +void pw_proxy_unref(struct pw_proxy *proxy); + +/** Get the user_data. The size was given in \ref pw_proxy_new */ +void *pw_proxy_get_user_data(struct pw_proxy *proxy); + +/** Get the local id of the proxy */ +uint32_t pw_proxy_get_id(struct pw_proxy *proxy); + +/** Get the type and version of the proxy */ +const char *pw_proxy_get_type(struct pw_proxy *proxy, uint32_t *version); + +/** Get the protocol used for the proxy */ +struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy); + +/** Generate an sync method for a proxy. This will generate a done event + * with the same seq number of the reply. */ +int pw_proxy_sync(struct pw_proxy *proxy, int seq); + +/** Set the global id this proxy is bound to. This is usually used internally + * and will also emit the bound event */ +int pw_proxy_set_bound_id(struct pw_proxy *proxy, uint32_t global_id); +/** Get the global id bound to this proxy of SPA_ID_INVALID when not bound + * to a global */ +uint32_t pw_proxy_get_bound_id(struct pw_proxy *proxy); + +/** Generate an error for a proxy */ +int pw_proxy_error(struct pw_proxy *proxy, int res, const char *error); +int pw_proxy_errorf(struct pw_proxy *proxy, int res, const char *error, ...) SPA_PRINTF_FUNC(3, 4); + +/** Get the listener of proxy */ +struct spa_hook_list *pw_proxy_get_object_listeners(struct pw_proxy *proxy); + +/** Get the marshal functions for the proxy */ +const struct pw_protocol_marshal *pw_proxy_get_marshal(struct pw_proxy *proxy); + +/** Install a marshal function on a proxy */ +int pw_proxy_install_marshal(struct pw_proxy *proxy, bool implementor); + +#define pw_proxy_notify(p,type,event,version,...) \ + spa_hook_list_call(pw_proxy_get_object_listeners(p), \ + type, event, version, ## __VA_ARGS__) + +#define pw_proxy_call(p,type,method,version,...) \ + spa_interface_call((struct spa_interface*)p, \ + type, method, version, ##__VA_ARGS__) + +#define pw_proxy_call_res(p,type,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + spa_interface_call_res((struct spa_interface*)p, \ + type, _res, method, version, ##__VA_ARGS__); \ + _res; \ +}) + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_PROXY_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/stream.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/stream.h new file mode 100644 index 000000000000..bea90b45880c --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/stream.h @@ -0,0 +1,536 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_STREAM_H +#define PIPEWIRE_STREAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \page page_streams Streams + * + * \see \ref pw_stream + * + * \section sec_overview Overview + * + * \ref pw_stream "Streams" are used to exchange data with the + * PipeWire server. A stream is a wrapper around a proxy for a pw_client_node + * with an adapter. This means the stream will automatically do conversion + * to the type required by the server. + * + * Streams can be used to: + * + * \li Consume a stream from PipeWire. This is a PW_DIRECTION_INPUT stream. + * \li Produce a stream to PipeWire. This is a PW_DIRECTION_OUTPUT stream + * + * You can connect the stream port to a specific server port or let PipeWire + * choose a port for you. + * + * For more complicated nodes such as filters or ports with multiple + * inputs and/or outputs you will need to use the pw_filter or make + * a pw_node yourself and export it with \ref pw_core_export. + * + * Streams can also be used to: + * + * \li Implement a Sink in PipeWire. This is a PW_DIRECTION_INPUT stream. + * \li Implement a Source in PipeWire. This is a PW_DIRECTION_OUTPUT stream + * + * In this case, the PW_KEY_MEDIA_CLASS property needs to be set to + * "Audio/Sink" or "Audio/Source" respectively. + * + * \section sec_create Create + * + * Make a new stream with \ref pw_stream_new(). You will need to specify + * a name for the stream and extra properties. The basic set of properties + * each stream must provide is filled in automatically. + * + * Once the stream is created, the state_changed event should be used to + * track the state of the stream. + * + * \section sec_connect Connect + * + * The stream is initially unconnected. To connect the stream, use + * \ref pw_stream_connect(). Pass the desired direction as an argument. + * + * The direction is: + + * \li PW_DIRECTION_INPUT for a stream that *consumes* data. This can be a + * stream that captures from a Source or a when the stream is used to + * implement a Sink. + * + * \li PW_DIRECTION_OUTPUT for a stream that *produces* data. This can be a + * stream that plays to a Sink or when the stream is used to implement + * a Source. + * + * \subsection ssec_stream_target Stream target + * + * To make the newly connected stream automatically connect to an existing + * PipeWire node, use the \ref PW_STREAM_FLAG_AUTOCONNECT and set the + * PW_KEY_OBJECT_SERIAL or the PW_KEY_NODE_NAME value of the target node + * in the PW_KEY_TARGET_OBJECT property before connecting. + * + * \subsection ssec_stream_formats Stream formats + * + * An array of possible formats that this stream can consume or provide + * must be specified. + * + * \section sec_format Format negotiation + * + * After connecting the stream, the server will want to configure some + * parameters on the stream. You will be notified of these changes + * with the param_changed event. + * + * When a format param change is emitted, the client should now prepare + * itself to deal with the format and complete the negotiation procedure + * with a call to \ref pw_stream_update_params(). + * + * As arguments to \ref pw_stream_update_params() an array of spa_param + * structures must be given. They contain parameters such as buffer size, + * number of buffers, required metadata and other parameters for the + * media buffers. + * + * \section sec_buffers Buffer negotiation + * + * After completing the format negotiation, PipeWire will allocate and + * notify the stream of the buffers that will be used to exchange data + * between client and server. + * + * With the add_buffer event, a stream will be notified of a new buffer + * that can be used for data transport. You can attach user_data to these + * buffers. The buffers can only be used with the stream that emitted + * the add_buffer event. + * + * After the buffers are negotiated, the stream will transition to the + * \ref PW_STREAM_STATE_PAUSED state. + * + * \section sec_streaming Streaming + * + * From the \ref PW_STREAM_STATE_PAUSED state, the stream can be set to + * the \ref PW_STREAM_STATE_STREAMING state by the PipeWire server when + * data transport is started. + * + * Depending on how the stream was connected it will need to Produce or + * Consume data for/from PipeWire as explained in the following + * subsections. + * + * \subsection ssec_consume Consume data + * + * The process event is emitted for each new buffer that can be + * consumed. + * + * \ref pw_stream_dequeue_buffer() should be used to get the data and + * metadata of the buffer. + * + * The buffer is owned by the stream and stays alive until the + * remove_buffer callback has returned or the stream is destroyed. + * + * When the buffer has been processed, call \ref pw_stream_queue_buffer() + * to let PipeWire reuse the buffer. + * + * \subsection ssec_produce Produce data + * + * \ref pw_stream_dequeue_buffer() gives an empty buffer that can be filled. + * + * The buffer is owned by the stream and stays alive until the + * remove_buffer event is emitted or the stream is destroyed. + * + * Filled buffers should be queued with \ref pw_stream_queue_buffer(). + * + * The process event is emitted when PipeWire has emptied a buffer that + * can now be refilled. + * + * \section sec_stream_disconnect Disconnect + * + * Use \ref pw_stream_disconnect() to disconnect a stream after use. + * + * \section sec_stream_configuration Configuration + * + * \subsection ssec_config_properties Stream Properties + * + * \subsection ssec_config_rules Stream Rules + * + * \section sec_stream_environment Environment Variables + * + * The environment variable PIPEWIRE_AUTOCONNECT can be used to override the + * flag and force apps to autoconnect or not. + * + */ +/** \defgroup pw_stream Stream + * + * \brief PipeWire stream objects + * + * The stream object provides a convenient way to send and + * receive data streams from/to PipeWire. + * + * \see \ref page_streams, \ref api_pw_core + */ + +/** + * \addtogroup pw_stream + * \{ + */ +struct pw_stream; + +#include +#include +#include + +/** \enum pw_stream_state The state of a stream */ +enum pw_stream_state { + PW_STREAM_STATE_ERROR = -1, /**< the stream is in error */ + PW_STREAM_STATE_UNCONNECTED = 0, /**< unconnected */ + PW_STREAM_STATE_CONNECTING = 1, /**< connection is in progress */ + PW_STREAM_STATE_PAUSED = 2, /**< paused */ + PW_STREAM_STATE_STREAMING = 3 /**< streaming */ +}; + +/** a buffer structure obtained from pw_stream_dequeue_buffer(). The size of this + * structure can grow as more field are added in the future */ +struct pw_buffer { + struct spa_buffer *buffer; /**< the spa buffer */ + void *user_data; /**< user data attached to the buffer */ + uint64_t size; /**< This field is set by the user and the sum of + * all queued buffer is returned in the time info. + * For audio, it is advised to use the number of + * samples in the buffer for this field. */ + uint64_t requested; /**< For playback streams, this field contains the + * suggested amount of data to provide. For audio + * streams this will be the amount of samples + * required by the resampler. This field is 0 + * when no suggestion is provided. Since 0.3.49 */ +}; + +struct pw_stream_control { + const char *name; /**< name of the control */ + uint32_t flags; /**< extra flags (unused) */ + float def; /**< default value */ + float min; /**< min value */ + float max; /**< max value */ + float *values; /**< array of values */ + uint32_t n_values; /**< number of values in array */ + uint32_t max_values; /**< max values that can be set on this control */ +}; + +/** A time structure. + * + * Use pw_stream_get_time_n() to get an updated time snapshot of the stream. + * The time snapshot can give information about the time in the driver of the + * graph, the delay to the edge of the graph and the internal queuing in the + * stream. + * + * pw_time.ticks gives a monotonic increasing counter of the time in the graph + * driver. I can be used to generate a timetime to schedule samples as well + * as detect discontinuities in the timeline caused by xruns. + * + * pw_time.delay is expressed as pw_time.rate, the time domain of the graph. This + * value, and pw_time.ticks, were captured at pw_time.now and can be extrapolated + * to the current time like this: + * + *\code{.c} + * struct timespec ts; + * clock_gettime(CLOCK_MONOTONIC, &ts); + * int64_t diff = SPA_TIMESPEC_TO_NSEC(&ts) - pw_time.now; + * int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC); + *\endcode + * + * pw_time.delay contains the total delay that a signal will travel through the + * graph. This includes the delay caused by filters in the graph as well as delays + * caused by the hardware. The delay is usually quite stable and should only change when + * the topology, quantum or samplerate of the graph changes. + * + * pw_time.queued and pw_time.buffered is expressed in the time domain of the stream, + * or the format that is used for the buffers of this stream. + * + * pw_time.queued is the sum of all the pw_buffer.size fields of the buffers that are + * currently queued in the stream but not yet processed. The application can choose + * the units of this value, for example, time, samples or bytes (below expressed + * as app.rate). + * + * pw_time.buffered is format dependent, for audio/raw it contains the number of samples + * that are buffered inside the resampler/converter. + * + * The total delay of data in a stream is the sum of the queued and buffered data + * (not yet processed data) and the delay to the edge of the graph, usually a + * playback or capture device. + * + * For an audio playback stream, if you were to queue a buffer, the total delay + * in milliseconds for the first sample in the newly queued buffer to be played + * by the hardware can be calculated as: + * + *\code{.unparsed} + * (pw_time.buffered * 1000 / stream.samplerate) + + * (pw_time.queued * 1000 / app.rate) + + * ((pw_time.delay - elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom) + *\endcode + * + * The current extrapolated time (in ms) in the source or sink can be calculated as: + * + *\code{.unparsed} + * (pw_time.ticks + elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom + *\endcode + * + * Below is an overview of the different timing values: + * + *\code{.unparsed} + * stream time domain graph time domain + * /-----------------------\/-----------------------------\ + * + * queue +-+ +-+ +-----------+ +--------+ + * ----> | | | |->| converter | -> graph -> | kernel | -> speaker + * <---- +-+ +-+ +-----------+ +--------+ + * dequeue buffers \-------------------/\--------/ + * graph internal + * latency latency + * \--------/\-------------/\-----------------------------/ + * queued buffered delay + *\endcode + */ +struct pw_time { + int64_t now; /**< the monotonic time in nanoseconds. This is the time + * when this time report was updated. It is usually + * updated every graph cycle. You can use the current + * monotonic time to calculate the elapsed time between + * this report and the current state and calculate + * updated ticks and delay values. */ + struct spa_fraction rate; /**< the rate of \a ticks and delay. This is usually + * expressed in 1/. */ + uint64_t ticks; /**< the ticks at \a now. This is the current time that + * the remote end is reading/writing. This is monotonicaly + * increasing. */ + int64_t delay; /**< delay to device. This is the time it will take for + * the next output sample of the stream to be presented by + * the playback device or the time a sample traveled + * from the capture device. This delay includes the + * delay introduced by all filters on the path between + * the stream and the device. The delay is normally + * constant in a graph and can change when the topology + * of the graph or the quantum changes. This delay does + * not include the delay caused by queued buffers. */ + uint64_t queued; /**< data queued in the stream, this is the sum + * of the size fields in the pw_buffer that are + * currently queued */ + uint64_t buffered; /**< for audio/raw streams, this contains the extra + * number of samples buffered in the resampler. + * Since 0.3.50. */ + uint32_t queued_buffers; /**< The number of buffers that are queued. Since 0.3.50 */ + uint32_t avail_buffers; /**< The number of buffers that can be dequeued. Since 0.3.50 */ +}; + +#include + +/** Events for a stream. These events are always called from the mainloop + * unless explicitly documented otherwise. */ +struct pw_stream_events { +#define PW_VERSION_STREAM_EVENTS 2 + uint32_t version; + + void (*destroy) (void *data); + /** when the stream state changes */ + void (*state_changed) (void *data, enum pw_stream_state old, + enum pw_stream_state state, const char *error); + + /** Notify information about a control. */ + void (*control_info) (void *data, uint32_t id, const struct pw_stream_control *control); + + /** when io changed on the stream. */ + void (*io_changed) (void *data, uint32_t id, void *area, uint32_t size); + /** when a parameter changed */ + void (*param_changed) (void *data, uint32_t id, const struct spa_pod *param); + + /** when a new buffer was created for this stream */ + void (*add_buffer) (void *data, struct pw_buffer *buffer); + /** when a buffer was destroyed for this stream */ + void (*remove_buffer) (void *data, struct pw_buffer *buffer); + + /** when a buffer can be queued (for playback streams) or + * dequeued (for capture streams). This is normally called from the + * mainloop but can also be called directly from the realtime data + * thread if the user is prepared to deal with this. */ + void (*process) (void *data); + + /** The stream is drained */ + void (*drained) (void *data); + + /** A command notify, Since 0.3.39:1 */ + void (*command) (void *data, const struct spa_command *command); + + /** a trigger_process completed. Since version 0.3.40:2 */ + void (*trigger_done) (void *data); +}; + +/** Convert a stream state to a readable string */ +const char * pw_stream_state_as_string(enum pw_stream_state state); + +/** \enum pw_stream_flags Extra flags that can be used in \ref pw_stream_connect() */ +enum pw_stream_flags { + PW_STREAM_FLAG_NONE = 0, /**< no flags */ + PW_STREAM_FLAG_AUTOCONNECT = (1 << 0), /**< try to automatically connect + * this stream */ + PW_STREAM_FLAG_INACTIVE = (1 << 1), /**< start the stream inactive, + * pw_stream_set_active() needs to be + * called explicitly */ + PW_STREAM_FLAG_MAP_BUFFERS = (1 << 2), /**< mmap the buffers except DmaBuf */ + PW_STREAM_FLAG_DRIVER = (1 << 3), /**< be a driver */ + PW_STREAM_FLAG_RT_PROCESS = (1 << 4), /**< call process from the realtime + * thread. You MUST use RT safe functions + * in the process callback. */ + PW_STREAM_FLAG_NO_CONVERT = (1 << 5), /**< don't convert format */ + PW_STREAM_FLAG_EXCLUSIVE = (1 << 6), /**< require exclusive access to the + * device */ + PW_STREAM_FLAG_DONT_RECONNECT = (1 << 7), /**< don't try to reconnect this stream + * when the sink/source is removed */ + PW_STREAM_FLAG_ALLOC_BUFFERS = (1 << 8), /**< the application will allocate buffer + * memory. In the add_buffer event, the + * data of the buffer should be set */ + PW_STREAM_FLAG_TRIGGER = (1 << 9), /**< the output stream will not be scheduled + * automatically but _trigger_process() + * needs to be called. This can be used + * when the output of the stream depends + * on input from other streams. */ + PW_STREAM_FLAG_ASYNC = (1 << 10), /**< Buffers will not be dequeued/queued from + * the realtime process() function. This is + * assumed when RT_PROCESS is unset but can + * also be the case when the process() function + * does a trigger_process() that will then + * dequeue/queue a buffer from another process() + * function. since 0.3.73 */ + PW_STREAM_FLAG_EARLY_PROCESS = (1 << 11), /**< Call process as soon as there is a buffer + * to dequeue. This is only relevant for + * playback and when not using RT_PROCESS. It + * can be used to keep the maximum number of + * buffers queued. Since 0.3.81 */ +}; + +/** Create a new unconneced \ref pw_stream + * \return a newly allocated \ref pw_stream */ +struct pw_stream * +pw_stream_new(struct pw_core *core, /**< a \ref pw_core */ + const char *name, /**< a stream media name */ + struct pw_properties *props /**< stream properties, ownership is taken */); + +struct pw_stream * +pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use */ + const char *name, /**< a stream media name */ + struct pw_properties *props,/**< stream properties, ownership is taken */ + const struct pw_stream_events *events, /**< stream events */ + void *data /**< data passed to events */); + +/** Destroy a stream */ +void pw_stream_destroy(struct pw_stream *stream); + +void pw_stream_add_listener(struct pw_stream *stream, + struct spa_hook *listener, + const struct pw_stream_events *events, + void *data); + +enum pw_stream_state pw_stream_get_state(struct pw_stream *stream, const char **error); + +const char *pw_stream_get_name(struct pw_stream *stream); + +struct pw_core *pw_stream_get_core(struct pw_stream *stream); + +const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream); + +int pw_stream_update_properties(struct pw_stream *stream, const struct spa_dict *dict); + +/** Connect a stream for input or output on \a port_path. + * \return 0 on success < 0 on error. + * + * You should connect to the process event and use pw_stream_dequeue_buffer() + * to get the latest metadata and data. */ +int +pw_stream_connect(struct pw_stream *stream, /**< a \ref pw_stream */ + enum pw_direction direction, /**< the stream direction */ + uint32_t target_id, /**< should have the value PW_ID_ANY. + * To select a specific target + * node, specify the + * PW_KEY_OBJECT_SERIAL or the + * PW_KEY_NODE_NAME value of the target + * node in the PW_KEY_TARGET_OBJECT + * property of the stream. + * Specifying target nodes by + * their id is deprecated. + */ + enum pw_stream_flags flags, /**< stream flags */ + const struct spa_pod **params, /**< an array with params. The params + * should ideally contain supported + * formats. */ + uint32_t n_params /**< number of items in \a params */); + +/** Get the node ID of the stream. + * \return node ID. */ +uint32_t +pw_stream_get_node_id(struct pw_stream *stream); + +/** Disconnect \a stream */ +int pw_stream_disconnect(struct pw_stream *stream); + +/** Set the stream in error state */ +int pw_stream_set_error(struct pw_stream *stream, /**< a \ref pw_stream */ + int res, /**< a result code */ + const char *error, /**< an error message */ + ...) SPA_PRINTF_FUNC(3, 4); + +/** Update the param exposed on the stream. */ +int +pw_stream_update_params(struct pw_stream *stream, /**< a \ref pw_stream */ + const struct spa_pod **params, /**< an array of params. */ + uint32_t n_params /**< number of elements in \a params */); + +/** + * Set a parameter on the stream. This is like pw_stream_set_control() but with + * a complete spa_pod param. It can also be called from the param_changed event handler + * to intercept and modify the param for the adapter. Since 0.3.70 */ +int pw_stream_set_param(struct pw_stream *stream, /**< a \ref pw_stream */ + uint32_t id, /**< the id of the param */ + const struct spa_pod *param /**< the params to set */); + +/** Get control values */ +const struct pw_stream_control *pw_stream_get_control(struct pw_stream *stream, uint32_t id); + +/** Set control values */ +int pw_stream_set_control(struct pw_stream *stream, uint32_t id, uint32_t n_values, float *values, ...); + +/** Query the time on the stream */ +int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size); + +/** Query the time on the stream, deprecated since 0.3.50, + * use pw_stream_get_time_n() to get the fields added since 0.3.50. */ +SPA_DEPRECATED +int pw_stream_get_time(struct pw_stream *stream, struct pw_time *time); + +/** Get a buffer that can be filled for playback streams or consumed + * for capture streams. */ +struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream); + +/** Submit a buffer for playback or recycle a buffer for capture. */ +int pw_stream_queue_buffer(struct pw_stream *stream, struct pw_buffer *buffer); + +/** Activate or deactivate the stream */ +int pw_stream_set_active(struct pw_stream *stream, bool active); + +/** Flush a stream. When \a drain is true, the drained callback will + * be called when all data is played or recorded */ +int pw_stream_flush(struct pw_stream *stream, bool drain); + +/** Check if the stream is driving. The stream needs to have the + * PW_STREAM_FLAG_DRIVER set. When the stream is driving, + * pw_stream_trigger_process() needs to be called when data is + * available (output) or needed (input). Since 0.3.34 */ +bool pw_stream_is_driving(struct pw_stream *stream); + +/** Trigger a push/pull on the stream. One iteration of the graph will + * scheduled and process() will be called. Since 0.3.34 */ +int pw_stream_trigger_process(struct pw_stream *stream); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_STREAM_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/thread-loop.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/thread-loop.h new file mode 100644 index 000000000000..f1eb1910ea98 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/thread-loop.h @@ -0,0 +1,157 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_THREAD_LOOP_H +#define PIPEWIRE_THREAD_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \page page_thread_loop Thread Loop + * + * \see \ref pw_thread_loop + * + * \section sec_thread_loop_overview Overview + * + * The threaded loop implementation is a special wrapper around the + * regular \ref pw_loop implementation. + * + * The added feature in the threaded loop is that it spawns a new thread + * that runs the wrapped loop. This allows a synchronous application to use + * the asynchronous API without risking to stall the PipeWire library. + * + * \section sec_thread_loop_create Creation + * + * A \ref pw_thread_loop object is created using pw_thread_loop_new(). + * The \ref pw_loop to wrap must be given as an argument along with the name + * for the thread that will be spawned. + * + * After allocating the object, the thread must be started with + * pw_thread_loop_start() + * + * \section sec_thread_loop_destruction Destruction + * + * When the PipeWire connection has been terminated, the thread must be + * stopped and the resources freed. Stopping the thread is done using + * pw_thread_loop_stop(), which must be called without the lock (see + * below) held. When that function returns, the thread is stopped and the + * \ref pw_thread_loop object can be freed using pw_thread_loop_destroy(). + * + * \section sec_thread_loop_locking Locking + * + * Since the PipeWire API doesn't allow concurrent accesses to objects, + * a locking scheme must be used to guarantee safe usage. The threaded + * loop API provides such a scheme through the functions + * pw_thread_loop_lock() and pw_thread_loop_unlock(). + * + * The lock is recursive, so it's safe to use it multiple times from the same + * thread. Just make sure you call pw_thread_loop_unlock() the same + * number of times you called pw_thread_loop_lock(). + * + * The lock needs to be held whenever you call any PipeWire function that + * uses an object associated with this loop. Make sure you do not hold + * on to the lock more than necessary though, as the threaded loop stops + * while the lock is held. + * + * \section sec_thread_loop_events Events and Callbacks + * + * All events and callbacks are called with the thread lock held. + * + */ +/** \defgroup pw_thread_loop Thread Loop + * + * The threaded loop object runs a \ref pw_loop in a separate thread + * and ensures proper locking is done. + * + * All of the loop callbacks will be executed with the loop + * lock held. + * + * \see \ref page_thread_loop + */ + +/** + * \addtogroup pw_thread_loop + * \{ + */ +struct pw_thread_loop; + +/** Thread loop events */ +struct pw_thread_loop_events { +#define PW_VERSION_THREAD_LOOP_EVENTS 0 + uint32_t version; + + /** the loop is destroyed */ + void (*destroy) (void *data); +}; + +/** Make a new thread loop with the given name and optional properties. */ +struct pw_thread_loop * +pw_thread_loop_new(const char *name, const struct spa_dict *props); + +/** Make a new thread loop with the given loop, name and optional properties. + * When \a loop is NULL, a new loop will be created. */ +struct pw_thread_loop * +pw_thread_loop_new_full(struct pw_loop *loop, const char *name, const struct spa_dict *props); + +/** Destroy a thread loop */ +void pw_thread_loop_destroy(struct pw_thread_loop *loop); + +/** Add an event listener */ +void pw_thread_loop_add_listener(struct pw_thread_loop *loop, + struct spa_hook *listener, + const struct pw_thread_loop_events *events, + void *data); + +/** Get the loop implementation of the thread loop */ +struct pw_loop * pw_thread_loop_get_loop(struct pw_thread_loop *loop); + +/** Start the thread loop */ +int pw_thread_loop_start(struct pw_thread_loop *loop); + +/** Stop the thread loop */ +void pw_thread_loop_stop(struct pw_thread_loop *loop); + +/** Lock the loop. This ensures exclusive ownership of the loop */ +void pw_thread_loop_lock(struct pw_thread_loop *loop); + +/** Unlock the loop */ +void pw_thread_loop_unlock(struct pw_thread_loop *loop); + +/** Release the lock and wait until some thread calls \ref pw_thread_loop_signal */ +void pw_thread_loop_wait(struct pw_thread_loop *loop); + +/** Release the lock and wait a maximum of 'wait_max_sec' seconds + * until some thread calls \ref pw_thread_loop_signal or time out */ +int pw_thread_loop_timed_wait(struct pw_thread_loop *loop, int wait_max_sec); + +/** Get a struct timespec suitable for \ref pw_thread_loop_timed_wait_full. + * Since: 0.3.7 */ +int pw_thread_loop_get_time(struct pw_thread_loop *loop, struct timespec *abstime, int64_t timeout); + +/** Release the lock and wait up to \a abstime until some thread calls + * \ref pw_thread_loop_signal. Use \ref pw_thread_loop_get_time to make a timeout. + * Since: 0.3.7 */ +int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, const struct timespec *abstime); + +/** Signal all threads waiting with \ref pw_thread_loop_wait */ +void pw_thread_loop_signal(struct pw_thread_loop *loop, bool wait_for_accept); + +/** Signal all threads executing \ref pw_thread_loop_signal with wait_for_accept */ +void pw_thread_loop_accept(struct pw_thread_loop *loop); + +/** Check if inside the thread */ +bool pw_thread_loop_in_thread(struct pw_thread_loop *loop); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_THREAD_LOOP_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/type.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/type.h new file mode 100644 index 000000000000..a8f982c5903b --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/type.h @@ -0,0 +1,45 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_TYPE_H +#define PIPEWIRE_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \defgroup pw_type Type info + * Type information + */ + +/** + * \addtogroup pw_type + * \{ + */ + +enum { + PW_TYPE_FIRST = SPA_TYPE_VENDOR_PipeWire, +}; + +#define PW_TYPE_INFO_BASE "PipeWire:" + +#define PW_TYPE_INFO_Object PW_TYPE_INFO_BASE "Object" +#define PW_TYPE_INFO_OBJECT_BASE PW_TYPE_INFO_Object ":" + +#define PW_TYPE_INFO_Interface PW_TYPE_INFO_BASE "Interface" +#define PW_TYPE_INFO_INTERFACE_BASE PW_TYPE_INFO_Interface ":" + +const struct spa_type_info * pw_type_info(void); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_TYPE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/utils.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/utils.h new file mode 100644 index 000000000000..9889fd7f5b8f --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/utils.h @@ -0,0 +1,106 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_UTILS_H +#define PIPEWIRE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#ifndef _POSIX_C_SOURCE +# include +#endif +#include + +#ifndef ENODATA +#define ENODATA 9919 +#endif + +#include +#include + +/** \defgroup pw_utils Utilities + * + * Various utility functions + */ + +/** + * \addtogroup pw_utils + * \{ + */ + +/** a function to destroy an item */ +typedef void (*pw_destroy_t) (void *object); + +const char * +pw_split_walk(const char *str, const char *delimiter, size_t *len, const char **state); + +char ** +pw_split_strv(const char *str, const char *delimiter, int max_tokens, int *n_tokens); + +int +pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens[]); + +char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens); + +int pw_strv_find(char **a, const char *b); + +int pw_strv_find_common(char **a, char **b); + +void +pw_free_strv(char **str); + +char * +pw_strip(char *str, const char *whitespace); + +#if !defined(strndupa) +# define strndupa(s, n) \ + ({ \ + const char *__old = (s); \ + size_t __len = strnlen(__old, (n)); \ + char *__new = (char *) __builtin_alloca(__len + 1); \ + memcpy(__new, __old, __len); \ + __new[__len] = '\0'; \ + __new; \ + }) +#endif + +#if !defined(strdupa) +# define strdupa(s) \ + ({ \ + const char *__old = (s); \ + size_t __len = strlen(__old) + 1; \ + char *__new = (char *) alloca(__len); \ + (char *) memcpy(__new, __old, __len); \ + }) +#endif + +SPA_WARN_UNUSED_RESULT +ssize_t pw_getrandom(void *buf, size_t buflen, unsigned int flags); + +void pw_random(void *buf, size_t buflen); + +#define pw_rand32() ({ uint32_t val; pw_random(&val, sizeof(val)); val; }) + +void* pw_reallocarray(void *ptr, size_t nmemb, size_t size); + +#ifdef PW_ENABLE_DEPRECATED +#define PW_DEPRECATED(v) (v) +#else +#define PW_DEPRECATED(v) ({ __typeof__(v) _v SPA_DEPRECATED = (v); (void)_v; (v); }) +#endif /* PW_ENABLE_DEPRECATED */ + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_UTILS_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/pipewire/version.h b/thirdparty/linuxbsd_headers/pipewire/pipewire/version.h new file mode 100644 index 000000000000..033d9d333cbe --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/pipewire/version.h @@ -0,0 +1,54 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_VERSION_H +#define PIPEWIRE_VERSION_H + +/* WARNING: Make sure to edit the real source file version.h.in! */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Return the version of the header files. Keep in mind that this is +a macro and not a function, so it is impossible to get the pointer of +it. */ +#define pw_get_headers_version() ("1.0.0") + +/** Return the version of the library the current application is + * linked to. */ +const char* pw_get_library_version(void); + +/** Return TRUE if the currently linked PipeWire library version is equal + * or newer than the specified version. Since 0.3.75 */ +bool pw_check_library_version(int major, int minor, int micro); + +/** The current API version. Versions prior to 0.2.0 have + * PW_API_VERSION undefined. Please note that this is only ever + * increased on incompatible API changes! */ +#define PW_API_VERSION "0.3" + +/** The major version of PipeWire. \since 0.2.0 */ +#define PW_MAJOR 1 + +/** The minor version of PipeWire. \since 0.2.0 */ +#define PW_MINOR 0 + +/** The micro version of PipeWire. \since 0.2.0 */ +#define PW_MICRO 0 + +/** Evaluates to TRUE if the PipeWire library version is equal or + * newer than the specified. \since 0.2.0 */ +#define PW_CHECK_VERSION(major,minor,micro) \ + ((PW_MAJOR > (major)) || \ + (PW_MAJOR == (major) && PW_MINOR > (minor)) || \ + (PW_MAJOR == (major) && PW_MINOR == (minor) && PW_MICRO >= (micro))) + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_VERSION_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/buffer/buffer.h b/thirdparty/linuxbsd_headers/pipewire/spa/buffer/buffer.h new file mode 100644 index 000000000000..13ed8d17528c --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/buffer/buffer.h @@ -0,0 +1,112 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_BUFFER_H +#define SPA_BUFFER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** \defgroup spa_buffer Buffers + * + * Buffers describe the data and metadata that is exchanged between + * ports of a node. + */ + +/** + * \addtogroup spa_buffer + * \{ + */ + +enum spa_data_type { + SPA_DATA_Invalid, + SPA_DATA_MemPtr, /**< pointer to memory, the data field in + * struct spa_data is set. */ + SPA_DATA_MemFd, /**< generic fd, mmap to get to memory */ + SPA_DATA_DmaBuf, /**< fd to dmabuf memory */ + SPA_DATA_MemId, /**< memory is identified with an id */ + + _SPA_DATA_LAST, /**< not part of ABI */ +}; + +/** Chunk of memory, can change for each buffer */ +struct spa_chunk { + uint32_t offset; /**< offset of valid data. Should be taken + * modulo the data maxsize to get the offset + * in the data memory. */ + uint32_t size; /**< size of valid data. Should be clamped to + * maxsize. */ + int32_t stride; /**< stride of valid data */ +#define SPA_CHUNK_FLAG_NONE 0 +#define SPA_CHUNK_FLAG_CORRUPTED (1u<<0) /**< chunk data is corrupted in some way */ +#define SPA_CHUNK_FLAG_EMPTY (1u<<1) /**< chunk data is empty with media specific + * neutral data such as silence or black. This + * could be used to optimize processing. */ + int32_t flags; /**< chunk flags */ +}; + +/** Data for a buffer this stays constant for a buffer */ +struct spa_data { + uint32_t type; /**< memory type, one of enum spa_data_type, when + * allocating memory, the type contains a bitmask + * of allowed types. SPA_ID_INVALID is a special + * value for the allocator to indicate that the + * other side did not explicitly specify any + * supported data types. It should probably use + * a memory type that does not require special + * handling in addition to simple mmap/munmap. */ +#define SPA_DATA_FLAG_NONE 0 +#define SPA_DATA_FLAG_READABLE (1u<<0) /**< data is readable */ +#define SPA_DATA_FLAG_WRITABLE (1u<<1) /**< data is writable */ +#define SPA_DATA_FLAG_DYNAMIC (1u<<2) /**< data pointer can be changed */ +#define SPA_DATA_FLAG_READWRITE (SPA_DATA_FLAG_READABLE|SPA_DATA_FLAG_WRITABLE) + uint32_t flags; /**< data flags */ + int64_t fd; /**< optional fd for data */ + uint32_t mapoffset; /**< offset to map fd at */ + uint32_t maxsize; /**< max size of data */ + void *data; /**< optional data pointer */ + struct spa_chunk *chunk; /**< valid chunk of memory */ +}; + +/** A Buffer */ +struct spa_buffer { + uint32_t n_metas; /**< number of metadata */ + uint32_t n_datas; /**< number of data members */ + struct spa_meta *metas; /**< array of metadata */ + struct spa_data *datas; /**< array of data members */ +}; + +/** Find metadata in a buffer */ +static inline struct spa_meta *spa_buffer_find_meta(const struct spa_buffer *b, uint32_t type) +{ + uint32_t i; + + for (i = 0; i < b->n_metas; i++) + if (b->metas[i].type == type) + return &b->metas[i]; + + return NULL; +} + +static inline void *spa_buffer_find_meta_data(const struct spa_buffer *b, uint32_t type, size_t size) +{ + struct spa_meta *m; + if ((m = spa_buffer_find_meta(b, type)) && m->size >= size) + return m->data; + return NULL; +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_BUFFER_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/buffer/meta.h b/thirdparty/linuxbsd_headers/pipewire/spa/buffer/meta.h new file mode 100644 index 000000000000..42e6a3fb742a --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/buffer/meta.h @@ -0,0 +1,172 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_META_H +#define SPA_META_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \addtogroup spa_buffer + * \{ + */ + +enum spa_meta_type { + SPA_META_Invalid, + SPA_META_Header, /**< struct spa_meta_header */ + SPA_META_VideoCrop, /**< struct spa_meta_region with cropping data */ + SPA_META_VideoDamage, /**< array of struct spa_meta_region with damage, where an invalid entry or end-of-array marks the end. */ + SPA_META_Bitmap, /**< struct spa_meta_bitmap */ + SPA_META_Cursor, /**< struct spa_meta_cursor */ + SPA_META_Control, /**< metadata contains a spa_meta_control + * associated with the data */ + SPA_META_Busy, /**< don't write to buffer when count > 0 */ + SPA_META_VideoTransform, /**< struct spa_meta_transform */ + + _SPA_META_LAST, /**< not part of ABI/API */ +}; + +/** + * A metadata element. + * + * This structure is available on the buffer structure and contains + * the type of the metadata and a pointer/size to the actual metadata + * itself. + */ +struct spa_meta { + uint32_t type; /**< metadata type, one of enum spa_meta_type */ + uint32_t size; /**< size of metadata */ + void *data; /**< pointer to metadata */ +}; + +static inline void *spa_meta_first(const struct spa_meta *m) { + return m->data; +} +#define spa_meta_first spa_meta_first +static inline void *spa_meta_end(const struct spa_meta *m) { + return SPA_PTROFF(m->data,m->size,void); +} +#define spa_meta_end spa_meta_end +#define spa_meta_check(p,m) (SPA_PTROFF(p,sizeof(*(p)),void) <= spa_meta_end(m)) + +/** + * Describes essential buffer header metadata such as flags and + * timestamps. + */ +struct spa_meta_header { +#define SPA_META_HEADER_FLAG_DISCONT (1 << 0) /**< data is not continuous with previous buffer */ +#define SPA_META_HEADER_FLAG_CORRUPTED (1 << 1) /**< data might be corrupted */ +#define SPA_META_HEADER_FLAG_MARKER (1 << 2) /**< media specific marker */ +#define SPA_META_HEADER_FLAG_HEADER (1 << 3) /**< data contains a codec specific header */ +#define SPA_META_HEADER_FLAG_GAP (1 << 4) /**< data contains media neutral data */ +#define SPA_META_HEADER_FLAG_DELTA_UNIT (1 << 5) /**< cannot be decoded independently */ + uint32_t flags; /**< flags */ + uint32_t offset; /**< offset in current cycle */ + int64_t pts; /**< presentation timestamp in nanoseconds */ + int64_t dts_offset; /**< decoding timestamp as a difference with pts */ + uint64_t seq; /**< sequence number, increments with a + * media specific frequency */ +}; + +/** metadata structure for Region or an array of these for RegionArray */ +struct spa_meta_region { + struct spa_region region; +}; + +static inline bool spa_meta_region_is_valid(const struct spa_meta_region *m) { + return m->region.size.width != 0 && m->region.size.height != 0; +} +#define spa_meta_region_is_valid spa_meta_region_is_valid + +/** iterate all the items in a metadata */ +#define spa_meta_for_each(pos,meta) \ + for ((pos) = (__typeof(pos))spa_meta_first(meta); \ + spa_meta_check(pos, meta); \ + (pos)++) + +#define spa_meta_bitmap_is_valid(m) ((m)->format != 0) + +/** + * Bitmap information + * + * This metadata contains a bitmap image in the given format and size. + * It is typically used for cursor images or other small images that are + * better transferred inline. + */ +struct spa_meta_bitmap { + uint32_t format; /**< bitmap video format, one of enum spa_video_format. 0 is + * and invalid format and should be handled as if there is + * no new bitmap information. */ + struct spa_rectangle size; /**< width and height of bitmap */ + int32_t stride; /**< stride of bitmap data */ + uint32_t offset; /**< offset of bitmap data in this structure. An offset of + * 0 means no image data (invisible), an offset >= + * sizeof(struct spa_meta_bitmap) contains valid bitmap + * info. */ +}; + +#define spa_meta_cursor_is_valid(m) ((m)->id != 0) + +/** + * Cursor information + * + * Metadata to describe the position and appearance of a pointing device. + */ +struct spa_meta_cursor { + uint32_t id; /**< cursor id. an id of 0 is an invalid id and means that + * there is no new cursor data */ + uint32_t flags; /**< extra flags */ + struct spa_point position; /**< position on screen */ + struct spa_point hotspot; /**< offsets for hotspot in bitmap, this field has no meaning + * when there is no valid bitmap (see below) */ + uint32_t bitmap_offset; /**< offset of bitmap meta in this structure. When the offset + * is 0, there is no new bitmap information. When the offset is + * >= sizeof(struct spa_meta_cursor) there is a + * struct spa_meta_bitmap at the offset. */ +}; + +/** a timed set of events associated with the buffer */ +struct spa_meta_control { + struct spa_pod_sequence sequence; +}; + +/** a busy counter for the buffer */ +struct spa_meta_busy { + uint32_t flags; + uint32_t count; /**< number of users busy with the buffer */ +}; + +enum spa_meta_videotransform_value { + SPA_META_TRANSFORMATION_None = 0, /**< no transform */ + SPA_META_TRANSFORMATION_90, /**< 90 degree counter-clockwise */ + SPA_META_TRANSFORMATION_180, /**< 180 degree counter-clockwise */ + SPA_META_TRANSFORMATION_270, /**< 270 degree counter-clockwise */ + SPA_META_TRANSFORMATION_Flipped, /**< 180 degree flipped around the vertical axis. Equivalent + * to a reflexion through the vertical line splitting the + * bufffer in two equal sized parts */ + SPA_META_TRANSFORMATION_Flipped90, /**< flip then rotate around 90 degree counter-clockwise */ + SPA_META_TRANSFORMATION_Flipped180, /**< flip then rotate around 180 degree counter-clockwise */ + SPA_META_TRANSFORMATION_Flipped270, /**< flip then rotate around 270 degree counter-clockwise */ +}; + +/** a transformation of the buffer */ +struct spa_meta_videotransform { + uint32_t transform; /**< orientation transformation that was applied to the buffer, + * one of enum spa_meta_videotransform_value */ +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_META_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/node/command.h b/thirdparty/linuxbsd_headers/pipewire/spa/node/command.h new file mode 100644 index 000000000000..24c81a53ef02 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/node/command.h @@ -0,0 +1,53 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_COMMAND_NODE_H +#define SPA_COMMAND_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_node + * \{ + */ + +#include + +/* object id of SPA_TYPE_COMMAND_Node */ +enum spa_node_command { + SPA_NODE_COMMAND_Suspend, /**< suspend a node, this removes all configured + * formats and closes any devices */ + SPA_NODE_COMMAND_Pause, /**< pause a node. this makes it stop emitting + * scheduling events */ + SPA_NODE_COMMAND_Start, /**< start a node, this makes it start emitting + * scheduling events */ + SPA_NODE_COMMAND_Enable, + SPA_NODE_COMMAND_Disable, + SPA_NODE_COMMAND_Flush, + SPA_NODE_COMMAND_Drain, + SPA_NODE_COMMAND_Marker, + SPA_NODE_COMMAND_ParamBegin, /**< begin a set of parameter enumerations or + * configuration that require the device to + * remain opened, like query formats and then + * set a format */ + SPA_NODE_COMMAND_ParamEnd, /**< end a transaction */ + SPA_NODE_COMMAND_RequestProcess,/**< Sent to a driver when some other node emitted + * the RequestProcess event. */ +}; + +#define SPA_NODE_COMMAND_ID(cmd) SPA_COMMAND_ID(cmd, SPA_TYPE_COMMAND_Node) +#define SPA_NODE_COMMAND_INIT(id) SPA_COMMAND_INIT(SPA_TYPE_COMMAND_Node, id) + + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_COMMAND_NODE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/node/event.h b/thirdparty/linuxbsd_headers/pipewire/spa/node/event.h new file mode 100644 index 000000000000..b975a7bfc211 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/node/event.h @@ -0,0 +1,44 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_EVENT_NODE_H +#define SPA_EVENT_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_node + * \{ + */ + +#include + +/* object id of SPA_TYPE_EVENT_Node */ +enum spa_node_event { + SPA_NODE_EVENT_Error, + SPA_NODE_EVENT_Buffering, + SPA_NODE_EVENT_RequestRefresh, + SPA_NODE_EVENT_RequestProcess, /*< Ask the driver to start processing + * the graph */ +}; + +#define SPA_NODE_EVENT_ID(ev) SPA_EVENT_ID(ev, SPA_TYPE_EVENT_Node) +#define SPA_NODE_EVENT_INIT(id) SPA_EVENT_INIT(SPA_TYPE_EVENT_Node, id) + +/* properties for SPA_TYPE_EVENT_Node */ +enum spa_event_node { + SPA_EVENT_NODE_START, +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_EVENT_NODE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/node/io.h b/thirdparty/linuxbsd_headers/pipewire/spa/node/io.h new file mode 100644 index 000000000000..20934efd4c6f --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/node/io.h @@ -0,0 +1,290 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_IO_H +#define SPA_IO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_node + * \{ + */ + +#include +#include + +/** IO areas + * + * IO information for a port on a node. This is allocated + * by the host and configured on a node or all ports for which + * IO is requested. + * + * The plugin will communicate with the host through the IO + * areas. + */ + +/** Different IO area types */ +enum spa_io_type { + SPA_IO_Invalid, + SPA_IO_Buffers, /**< area to exchange buffers, struct spa_io_buffers */ + SPA_IO_Range, /**< expected byte range, struct spa_io_range */ + SPA_IO_Clock, /**< area to update clock information, struct spa_io_clock */ + SPA_IO_Latency, /**< latency reporting, struct spa_io_latency */ + SPA_IO_Control, /**< area for control messages, struct spa_io_sequence */ + SPA_IO_Notify, /**< area for notify messages, struct spa_io_sequence */ + SPA_IO_Position, /**< position information in the graph, struct spa_io_position */ + SPA_IO_RateMatch, /**< rate matching between nodes, struct spa_io_rate_match */ + SPA_IO_Memory, /**< memory pointer, struct spa_io_memory */ +}; + +/** + * IO area to exchange buffers. + * + * A set of buffers should first be configured on the node/port. + * Further references to those buffers will be made by using the + * id of the buffer. + * + * If status is SPA_STATUS_OK, the host should ignore + * the io area. + * + * If status is SPA_STATUS_NEED_DATA, the host should: + * 1) recycle the buffer in buffer_id, if possible + * 2) prepare a new buffer and place the id in buffer_id. + * + * If status is SPA_STATUS_HAVE_DATA, the host should consume + * the buffer in buffer_id and set the state to + * SPA_STATUS_NEED_DATA when new data is requested. + * + * If status is SPA_STATUS_STOPPED, some error occurred on the + * port. + * + * If status is SPA_STATUS_DRAINED, data from the io area was + * used to drain. + * + * Status can also be a negative errno value to indicate errors. + * such as: + * -EINVAL: buffer_id is invalid + * -EPIPE: no more buffers available + */ +struct spa_io_buffers { +#define SPA_STATUS_OK 0 +#define SPA_STATUS_NEED_DATA (1<<0) +#define SPA_STATUS_HAVE_DATA (1<<1) +#define SPA_STATUS_STOPPED (1<<2) +#define SPA_STATUS_DRAINED (1<<3) + int32_t status; /**< the status code */ + uint32_t buffer_id; /**< a buffer id */ +}; + +#define SPA_IO_BUFFERS_INIT ((struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, }) + +/** + * IO area to exchange a memory region + */ +struct spa_io_memory { + int32_t status; /**< the status code */ + uint32_t size; /**< the size of \a data */ + void *data; /**< a memory pointer */ +}; +#define SPA_IO_MEMORY_INIT ((struct spa_io_memory) { SPA_STATUS_OK, 0, NULL, }) + +/** A range, suitable for input ports that can suggest a range to output ports */ +struct spa_io_range { + uint64_t offset; /**< offset in range */ + uint32_t min_size; /**< minimum size of data */ + uint32_t max_size; /**< maximum size of data */ +}; + +/** + * Absolute time reporting. + * + * Nodes that can report clocking information will receive this io block. + * The application sets the id. This is usually set as part of the + * position information but can also be set separately. + * + * The clock counts the elapsed time according to the clock provider + * since the provider was last started. + */ +struct spa_io_clock { +#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) + uint32_t flags; /**< clock flags */ + uint32_t id; /**< unique clock id, set by application */ + char name[64]; /**< clock name prefixed with API, set by node. The clock name + * is unique per clock and can be used to check if nodes + * share the same clock. */ + uint64_t nsec; /**< time in nanoseconds against monotonic clock */ + struct spa_fraction rate; /**< rate for position/duration/delay/xrun */ + uint64_t position; /**< current position */ + uint64_t duration; /**< duration of current cycle */ + int64_t delay; /**< delay between position and hardware, + * positive for capture, negative for playback */ + double rate_diff; /**< rate difference between clock and monotonic time */ + uint64_t next_nsec; /**< estimated next wakeup time in nanoseconds */ + + struct spa_fraction target_rate; /**< target rate of next cycle */ + uint64_t target_duration; /**< target duration of next cycle */ + uint32_t target_seq; /**< seq counter. must be equal at start and + * end of read and lower bit must be 0 */ + uint32_t padding; + uint64_t xrun; /**< estimated accumulated xrun duration */ +}; + +/* the size of the video in this cycle */ +struct spa_io_video_size { +#define SPA_IO_VIDEO_SIZE_VALID (1<<0) + uint32_t flags; /**< optional flags */ + uint32_t stride; /**< video stride in bytes */ + struct spa_rectangle size; /**< the video size */ + struct spa_fraction framerate; /**< the minimum framerate, the cycle duration is + * always smaller to ensure there is only one + * video frame per cycle. */ + uint32_t padding[4]; +}; + +/** latency reporting */ +struct spa_io_latency { + struct spa_fraction rate; /**< rate for min/max */ + uint64_t min; /**< min latency */ + uint64_t max; /**< max latency */ +}; + +/** control stream, io area for SPA_IO_Control and SPA_IO_Notify */ +struct spa_io_sequence { + struct spa_pod_sequence sequence; /**< sequence of timed events */ +}; + +/** bar and beat segment */ +struct spa_io_segment_bar { +#define SPA_IO_SEGMENT_BAR_FLAG_VALID (1<<0) + uint32_t flags; /**< extra flags */ + uint32_t offset; /**< offset in segment of this beat */ + float signature_num; /**< time signature numerator */ + float signature_denom; /**< time signature denominator */ + double bpm; /**< beats per minute */ + double beat; /**< current beat in segment */ + uint32_t padding[8]; +}; + +/** video frame segment */ +struct spa_io_segment_video { +#define SPA_IO_SEGMENT_VIDEO_FLAG_VALID (1<<0) +#define SPA_IO_SEGMENT_VIDEO_FLAG_DROP_FRAME (1<<1) +#define SPA_IO_SEGMENT_VIDEO_FLAG_PULL_DOWN (1<<2) +#define SPA_IO_SEGMENT_VIDEO_FLAG_INTERLACED (1<<3) + uint32_t flags; /**< flags */ + uint32_t offset; /**< offset in segment */ + struct spa_fraction framerate; + uint32_t hours; + uint32_t minutes; + uint32_t seconds; + uint32_t frames; + uint32_t field_count; /**< 0 for progressive, 1 and 2 for interlaced */ + uint32_t padding[11]; +}; + +/** + * A segment converts a running time to a segment (stream) position. + * + * The segment position is valid when the current running time is between + * start and start + duration. The position is then + * calculated as: + * + * (running time - start) * rate + position; + * + * Support for looping is done by specifying the LOOPING flags with a + * non-zero duration. When the running time reaches start + duration, + * duration is added to start and the loop repeats. + * + * Care has to be taken when the running time + clock.duration extends + * past the start + duration from the segment; the user should correctly + * wrap around and partially repeat the loop in the current cycle. + * + * Extra information can be placed in the segment by setting the valid flags + * and filling up the corresponding structures. + */ +struct spa_io_segment { + uint32_t version; +#define SPA_IO_SEGMENT_FLAG_LOOPING (1<<0) /**< after the duration, the segment repeats */ +#define SPA_IO_SEGMENT_FLAG_NO_POSITION (1<<1) /**< position is invalid. The position can be invalid + * after a seek, for example, when the exact mapping + * of the extra segment info (bar, video, ...) to + * position has not been determined yet */ + uint32_t flags; /**< extra flags */ + uint64_t start; /**< value of running time when this + * info is active. Can be in the future for + * pending changes. It does not have to be in + * exact multiples of the clock duration. */ + uint64_t duration; /**< duration when this info becomes invalid expressed + * in running time. If the duration is 0, this + * segment extends to the next segment. If the + * segment becomes invalid and the looping flag is + * set, the segment repeats. */ + double rate; /**< overall rate of the segment, can be negative for + * backwards time reporting. */ + uint64_t position; /**< The position when the running time == start. + * can be invalid when the owner of the extra segment + * information has not yet made the mapping. */ + + struct spa_io_segment_bar bar; + struct spa_io_segment_video video; +}; + +enum spa_io_position_state { + SPA_IO_POSITION_STATE_STOPPED, + SPA_IO_POSITION_STATE_STARTING, + SPA_IO_POSITION_STATE_RUNNING, +}; + +/** the maximum number of segments visible in the future */ +#define SPA_IO_POSITION_MAX_SEGMENTS 8 + +/** + * The position information adds extra meaning to the raw clock times. + * + * It is set on all nodes and the clock id will contain the clock of the + * driving node in the graph. + * + * The position information contains 1 or more segments that convert the + * raw clock times to a stream time. They are sorted based on their + * start times, and thus the order in which they will activate in + * the future. This makes it possible to look ahead in the scheduled + * segments and anticipate the changes in the timeline. + */ +struct spa_io_position { + struct spa_io_clock clock; /**< clock position of driver, always valid and + * read only */ + struct spa_io_video_size video; /**< size of the video in the current cycle */ + int64_t offset; /**< an offset to subtract from the clock position + * to get a running time. This is the time that + * the state has been in the RUNNING state and the + * time that should be used to compare the segment + * start values against. */ + uint32_t state; /**< one of enum spa_io_position_state */ + + uint32_t n_segments; /**< number of segments */ + struct spa_io_segment segments[SPA_IO_POSITION_MAX_SEGMENTS]; /**< segments */ +}; + +/** rate matching */ +struct spa_io_rate_match { + uint32_t delay; /**< extra delay in samples for resampler */ + uint32_t size; /**< requested input size for resampler */ + double rate; /**< rate for resampler */ +#define SPA_IO_RATE_MATCH_FLAG_ACTIVE (1 << 0) + uint32_t flags; /**< extra flags */ + uint32_t padding[7]; +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_IO_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/node/node.h b/thirdparty/linuxbsd_headers/pipewire/spa/node/node.h new file mode 100644 index 000000000000..f3eb6c027177 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/node/node.h @@ -0,0 +1,680 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_NODE_H +#define SPA_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup spa_node Node + * + * A spa_node is a component that can consume and produce buffers. + */ + +/** + * \addtogroup spa_node + * \{ + */ + +#include +#include +#include +#include +#include +#include +#include + + +#define SPA_TYPE_INTERFACE_Node SPA_TYPE_INFO_INTERFACE_BASE "Node" + +#define SPA_VERSION_NODE 0 +struct spa_node { struct spa_interface iface; }; + +/** + * Node information structure + * + * Contains the basic node information. + */ +struct spa_node_info { + uint32_t max_input_ports; + uint32_t max_output_ports; +#define SPA_NODE_CHANGE_MASK_FLAGS (1u<<0) +#define SPA_NODE_CHANGE_MASK_PROPS (1u<<1) +#define SPA_NODE_CHANGE_MASK_PARAMS (1u<<2) + uint64_t change_mask; + +#define SPA_NODE_FLAG_RT (1u<<0) /**< node can do real-time processing */ +#define SPA_NODE_FLAG_IN_DYNAMIC_PORTS (1u<<1) /**< input ports can be added/removed */ +#define SPA_NODE_FLAG_OUT_DYNAMIC_PORTS (1u<<2) /**< output ports can be added/removed */ +#define SPA_NODE_FLAG_IN_PORT_CONFIG (1u<<3) /**< input ports can be reconfigured with + * PortConfig parameter */ +#define SPA_NODE_FLAG_OUT_PORT_CONFIG (1u<<4) /**< output ports can be reconfigured with + * PortConfig parameter */ +#define SPA_NODE_FLAG_NEED_CONFIGURE (1u<<5) /**< node needs configuration before it can + * be started. */ +#define SPA_NODE_FLAG_ASYNC (1u<<6) /**< the process function might not + * immediately produce or consume data + * but might offload the work to a worker + * thread. */ + uint64_t flags; + struct spa_dict *props; /**< extra node properties */ + struct spa_param_info *params; /**< parameter information */ + uint32_t n_params; /**< number of items in \a params */ +}; + +#define SPA_NODE_INFO_INIT() ((struct spa_node_info) { 0, }) + +/** + * Port information structure + * + * Contains the basic port information. + */ +struct spa_port_info { +#define SPA_PORT_CHANGE_MASK_FLAGS (1u<<0) +#define SPA_PORT_CHANGE_MASK_RATE (1u<<1) +#define SPA_PORT_CHANGE_MASK_PROPS (1u<<2) +#define SPA_PORT_CHANGE_MASK_PARAMS (1u<<3) + uint64_t change_mask; + +#define SPA_PORT_FLAG_REMOVABLE (1u<<0) /**< port can be removed */ +#define SPA_PORT_FLAG_OPTIONAL (1u<<1) /**< processing on port is optional */ +#define SPA_PORT_FLAG_CAN_ALLOC_BUFFERS (1u<<2) /**< the port can allocate buffer data */ +#define SPA_PORT_FLAG_IN_PLACE (1u<<3) /**< the port can process data in-place and + * will need a writable input buffer */ +#define SPA_PORT_FLAG_NO_REF (1u<<4) /**< the port does not keep a ref on the buffer. + * This means the node will always completely + * consume the input buffer and it will be + * recycled after process. */ +#define SPA_PORT_FLAG_LIVE (1u<<5) /**< output buffers from this port are + * timestamped against a live clock. */ +#define SPA_PORT_FLAG_PHYSICAL (1u<<6) /**< connects to some device */ +#define SPA_PORT_FLAG_TERMINAL (1u<<7) /**< data was not created from this port + * or will not be made available on another + * port */ +#define SPA_PORT_FLAG_DYNAMIC_DATA (1u<<8) /**< data pointer on buffers can be changed. + * Only the buffer data marked as DYNAMIC + * can be changed. */ + uint64_t flags; /**< port flags */ + struct spa_fraction rate; /**< rate of sequence numbers on port */ + const struct spa_dict *props; /**< extra port properties */ + struct spa_param_info *params; /**< parameter information */ + uint32_t n_params; /**< number of items in \a params */ +}; + +#define SPA_PORT_INFO_INIT() ((struct spa_port_info) { 0, }) + +#define SPA_RESULT_TYPE_NODE_ERROR 1 +#define SPA_RESULT_TYPE_NODE_PARAMS 2 + +/** an error result */ +struct spa_result_node_error { + const char *message; +}; + +/** the result of enum_params or port_enum_params. */ +struct spa_result_node_params { + uint32_t id; /**< id of parameter */ + uint32_t index; /**< index of parameter */ + uint32_t next; /**< next index of iteration */ + struct spa_pod *param; /**< the result param */ +}; + +#define SPA_NODE_EVENT_INFO 0 +#define SPA_NODE_EVENT_PORT_INFO 1 +#define SPA_NODE_EVENT_RESULT 2 +#define SPA_NODE_EVENT_EVENT 3 +#define SPA_NODE_EVENT_NUM 4 + +/** events from the spa_node. + * + * All event are called from the main thread and multiple + * listeners can be registered for the events with + * spa_node_add_listener(). + */ +struct spa_node_events { +#define SPA_VERSION_NODE_EVENTS 0 + uint32_t version; /**< version of this structure */ + + /** Emitted when info changes */ + void (*info) (void *data, const struct spa_node_info *info); + + /** Emitted when port info changes, NULL when port is removed */ + void (*port_info) (void *data, + enum spa_direction direction, uint32_t port, + const struct spa_port_info *info); + + /** notify a result. + * + * Some methods will trigger a result event with an optional + * result of the given type. Look at the documentation of the + * method to know when to expect a result event. + * + * The result event can be called synchronously, as an event + * called from inside the method itself, in which case the seq + * number passed to the method will be passed unchanged. + * + * The result event will be called asynchronously when the + * method returned an async return value. In this case, the seq + * number in the result will match the async return value of + * the method call. Users should match the seq number from + * request to the reply. + */ + void (*result) (void *data, int seq, int res, + uint32_t type, const void *result); + + /** + * \param node a spa_node + * \param event the event that was emitted + * + * This will be called when an out-of-bound event is notified + * on \a node. + */ + void (*event) (void *data, const struct spa_event *event); +}; + +#define SPA_NODE_CALLBACK_READY 0 +#define SPA_NODE_CALLBACK_REUSE_BUFFER 1 +#define SPA_NODE_CALLBACK_XRUN 2 +#define SPA_NODE_CALLBACK_NUM 3 + +/** Node callbacks + * + * Callbacks are called from the real-time data thread. Only + * one callback structure can be set on an spa_node. + */ +struct spa_node_callbacks { +#define SPA_VERSION_NODE_CALLBACKS 0 + uint32_t version; + /** + * \param node a spa_node + * + * The node is ready for processing. + * + * When this function is NULL, synchronous operation is requested + * on the ports. + */ + int (*ready) (void *data, int state); + + /** + * \param node a spa_node + * \param port_id an input port_id + * \param buffer_id the buffer id to be reused + * + * The node has a buffer that can be reused. + * + * When this function is NULL, the buffers to reuse will be set in + * the io area of the input ports. + */ + int (*reuse_buffer) (void *data, + uint32_t port_id, + uint32_t buffer_id); + + /** + * \param data user data + * \param trigger the timestamp in microseconds when the xrun happened + * \param delay the amount of microseconds of xrun. + * \param info an object with extra info (NULL for now) + * + * The node has encountered an over or underrun + * + * The info contains an object with more information + */ + int (*xrun) (void *data, uint64_t trigger, uint64_t delay, + struct spa_pod *info); +}; + + +/** flags that can be passed to set_param and port_set_param functions */ +#define SPA_NODE_PARAM_FLAG_TEST_ONLY (1 << 0) /**< Just check if the param is accepted */ +#define SPA_NODE_PARAM_FLAG_FIXATE (1 << 1) /**< Fixate the non-optional unset fields */ +#define SPA_NODE_PARAM_FLAG_NEAREST (1 << 2) /**< Allow set fields to be rounded to the + * nearest allowed field value. */ + +/** flags to pass to the use_buffers functions */ +#define SPA_NODE_BUFFERS_FLAG_ALLOC (1 << 0) /**< Allocate memory for the buffers. This flag + * is ignored when the port does not have the + * SPA_PORT_FLAG_CAN_ALLOC_BUFFERS set. */ + + +#define SPA_NODE_METHOD_ADD_LISTENER 0 +#define SPA_NODE_METHOD_SET_CALLBACKS 1 +#define SPA_NODE_METHOD_SYNC 2 +#define SPA_NODE_METHOD_ENUM_PARAMS 3 +#define SPA_NODE_METHOD_SET_PARAM 4 +#define SPA_NODE_METHOD_SET_IO 5 +#define SPA_NODE_METHOD_SEND_COMMAND 6 +#define SPA_NODE_METHOD_ADD_PORT 7 +#define SPA_NODE_METHOD_REMOVE_PORT 8 +#define SPA_NODE_METHOD_PORT_ENUM_PARAMS 9 +#define SPA_NODE_METHOD_PORT_SET_PARAM 10 +#define SPA_NODE_METHOD_PORT_USE_BUFFERS 11 +#define SPA_NODE_METHOD_PORT_SET_IO 12 +#define SPA_NODE_METHOD_PORT_REUSE_BUFFER 13 +#define SPA_NODE_METHOD_PROCESS 14 +#define SPA_NODE_METHOD_NUM 15 + +/** + * Node methods + */ +struct spa_node_methods { + /* the version of the node methods. This can be used to expand this + * structure in the future */ +#define SPA_VERSION_NODE_METHODS 0 + uint32_t version; + + /** + * Adds an event listener on \a node. + * + * Setting the events will trigger the info event and a + * port_info event for each managed port on the new + * listener. + * + * \param node a #spa_node + * \param listener a listener + * \param events a struct \ref spa_node_events + * \param data data passed as first argument in functions of \a events + * \return 0 on success + * < 0 errno on error + */ + int (*add_listener) (void *object, + struct spa_hook *listener, + const struct spa_node_events *events, + void *data); + /** + * Set callbacks to on \a node. + * if \a callbacks is NULL, the current callbacks are removed. + * + * This function must be called from the main thread. + * + * All callbacks are called from the data thread. + * + * \param node a spa_node + * \param callbacks callbacks to set + * \return 0 on success + * -EINVAL when node is NULL + */ + int (*set_callbacks) (void *object, + const struct spa_node_callbacks *callbacks, + void *data); + /** + * Perform a sync operation. + * + * This method will emit the result event with the given sequence + * number synchronously or with the returned async return value + * asynchronously. + * + * Because all methods are serialized in the node, this can be used + * to wait for completion of all previous method calls. + * + * \param seq a sequence number + * \return 0 on success + * -EINVAL when node is NULL + * an async result + */ + int (*sync) (void *object, int seq); + + /** + * Enumerate the parameters of a node. + * + * Parameters are identified with an \a id. Some parameters can have + * multiple values, see the documentation of the parameter id. + * + * Parameters can be filtered by passing a non-NULL \a filter. + * + * The function will emit the result event up to \a max times with + * the result value. The seq in the result will either be the \a seq + * number when executed synchronously or the async return value of + * this function when executed asynchronously. + * + * This function must be called from the main thread. + * + * \param node a \ref spa_node + * \param seq a sequence number to pass to the result event when + * this method is executed synchronously. + * \param id the param id to enumerate + * \param start the index of enumeration, pass 0 for the first item + * \param max the maximum number of parameters to enumerate + * \param filter and optional filter to use + * + * \return 0 when no more items can be iterated. + * -EINVAL when invalid arguments are given + * -ENOENT the parameter \a id is unknown + * -ENOTSUP when there are no parameters + * implemented on \a node + * an async return value when the result event will be + * emitted later. + */ + int (*enum_params) (void *object, int seq, + uint32_t id, uint32_t start, uint32_t max, + const struct spa_pod *filter); + + /** + * Set the configurable parameter in \a node. + * + * Usually, \a param will be obtained from enum_params and then + * modified but it is also possible to set another spa_pod + * as long as its keys and types match a supported object. + * + * Objects with property keys that are not known are ignored. + * + * This function must be called from the main thread. + * + * \param node a \ref spa_node + * \param id the parameter id to configure + * \param flags additional flags + * \param param the parameter to configure + * + * \return 0 on success + * -EINVAL when node is NULL + * -ENOTSUP when there are no parameters implemented on \a node + * -ENOENT the parameter is unknown + */ + int (*set_param) (void *object, + uint32_t id, uint32_t flags, + const struct spa_pod *param); + + /** + * Configure the given memory area with \a id on \a node. This + * structure is allocated by the host and is used to exchange + * data and parameters with the node. + * + * Setting an \a io of NULL will disable the node io. + * + * This function must be called from the main thread. + * + * \param id the id of the io area, the available ids can be + * enumerated with the node parameters. + * \param data a io area memory + * \param size the size of \a data + * \return 0 on success + * -EINVAL when invalid input is given + * -ENOENT when \a id is unknown + * -ENOSPC when \a size is too small + */ + int (*set_io) (void *object, + uint32_t id, void *data, size_t size); + + /** + * Send a command to a node. + * + * Upon completion, a command might change the state of a node. + * + * This function must be called from the main thread. + * + * \param node a spa_node + * \param command a spa_command + * \return 0 on success + * -EINVAL when node or command is NULL + * -ENOTSUP when this node can't process commands + * -EINVAL \a command is an invalid command + */ + int (*send_command) (void *object, const struct spa_command *command); + + /** + * Make a new port with \a port_id. The caller should use the lowest unused + * port id for the given \a direction. + * + * Port ids should be between 0 and max_ports as obtained from the info + * event. + * + * This function must be called from the main thread. + * + * \param node a spa_node + * \param direction a enum \ref spa_direction + * \param port_id an unused port id + * \param props extra properties + * \return 0 on success + * -EINVAL when node is NULL + */ + int (*add_port) (void *object, + enum spa_direction direction, uint32_t port_id, + const struct spa_dict *props); + + /** + * Remove a port with \a port_id. + * + * \param node a spa_node + * \param direction a enum \ref spa_direction + * \param port_id a port id + * \return 0 on success + * -EINVAL when node is NULL or when port_id is unknown or + * when the port can't be removed. + */ + int (*remove_port) (void *object, + enum spa_direction direction, uint32_t port_id); + + /** + * Enumerate all possible parameters of \a id on \a port_id of \a node + * that are compatible with \a filter. + * + * The result parameters can be queried and modified and ultimately be used + * to call port_set_param. + * + * The function will emit the result event up to \a max times with + * the result value. The seq in the result event will either be the + * \a seq number when executed synchronously or the async return + * value of this function when executed asynchronously. + * + * This function must be called from the main thread. + * + * \param node a spa_node + * \param seq a sequence number to pass to the result event when + * this method is executed synchronously. + * \param direction an spa_direction + * \param port_id the port to query + * \param id the parameter id to query + * \param start the first index to query, 0 to get the first item + * \param max the maximum number of params to query + * \param filter a parameter filter or NULL for no filter + * + * \return 0 when no more items can be iterated. + * -EINVAL when invalid parameters are given + * -ENOENT when \a id is unknown + * an async return value when the result event will be + * emitted later. + */ + int (*port_enum_params) (void *object, int seq, + enum spa_direction direction, uint32_t port_id, + uint32_t id, uint32_t start, uint32_t max, + const struct spa_pod *filter); + /** + * Set a parameter on \a port_id of \a node. + * + * When \a param is NULL, the parameter will be unset. + * + * This function must be called from the main thread. The node muse be paused + * or the port SPA_IO_Buffers area is NULL when this function is called with + * a param that changes the processing state (like a format change). + * + * \param node a struct \ref spa_node + * \param direction a enum \ref spa_direction + * \param port_id the port to configure + * \param id the parameter id to set + * \param flags optional flags + * \param param a struct \ref spa_pod with the parameter to set + * \return 0 on success + * 1 on success, the value of \a param might have been + * changed depending on \a flags and the final value can be found by + * doing port_enum_params. + * -EINVAL when node is NULL or invalid arguments are given + * -ESRCH when one of the mandatory param + * properties is not specified and SPA_NODE_PARAM_FLAG_FIXATE was + * not set in \a flags. + * -ESRCH when the type or size of a property is not correct. + * -ENOENT when the param id is not found + */ + int (*port_set_param) (void *object, + enum spa_direction direction, + uint32_t port_id, + uint32_t id, uint32_t flags, + const struct spa_pod *param); + + /** + * Tell the port to use the given buffers + * + * When \a flags contains SPA_NODE_BUFFERS_FLAG_ALLOC, the data + * in the buffers should point to an array of at least 1 data entry + * with the desired supported type that will be filled by this function. + * + * The port should also have a spa_io_buffers io area configured to exchange + * the buffers with the port. + * + * For an input port, all the buffers will remain dequeued. + * Once a buffer has been queued on a port in the spa_io_buffers, + * it should not be reused until the reuse_buffer callback is notified + * or when the buffer has been returned in the spa_io_buffers of + * the port. + * + * For output ports, all buffers will be queued in the port. When process + * returns SPA_STATUS_HAVE_DATA, buffers are available in one or more + * of the spa_io_buffers areas. + * + * When a buffer can be reused, port_reuse_buffer() should be called or the + * buffer_id should be placed in the spa_io_buffers area before calling + * process. + * + * Passing NULL as \a buffers will remove the reference that the port has + * on the buffers. + * + * When this function returns async, use the spa_node_sync operation to + * wait for completion. + * + * This function must be called from the main thread. The node muse be paused + * or the port SPA_IO_Buffers area is NULL when this function is called. + * + * \param object an object implementing the interface + * \param direction a port direction + * \param port_id a port id + * \param flags extra flags + * \param buffers an array of buffer pointers + * \param n_buffers number of elements in \a buffers + * \return 0 on success + */ + int (*port_use_buffers) (void *object, + enum spa_direction direction, + uint32_t port_id, + uint32_t flags, + struct spa_buffer **buffers, + uint32_t n_buffers); + + /** + * Configure the given memory area with \a id on \a port_id. This + * structure is allocated by the host and is used to exchange + * data and parameters with the port. + * + * Setting an \a io of NULL will disable the port io. + * + * This function must be called from the main thread. + * + * This function can be called when the node is running and the node + * must be prepared to handle changes in io areas while running. This + * is normally done by synchronizing the port io updates with the + * data processing loop. + * + * \param direction a spa_direction + * \param port_id a port id + * \param id the id of the io area, the available ids can be + * enumerated with the port parameters. + * \param data a io area memory + * \param size the size of \a data + * \return 0 on success + * -EINVAL when invalid input is given + * -ENOENT when \a id is unknown + * -ENOSPC when \a size is too small + */ + int (*port_set_io) (void *object, + enum spa_direction direction, + uint32_t port_id, + uint32_t id, + void *data, size_t size); + + /** + * Tell an output port to reuse a buffer. + * + * This function must be called from the data thread. + * + * \param node a spa_node + * \param port_id a port id + * \param buffer_id a buffer id to reuse + * \return 0 on success + * -EINVAL when node is NULL + */ + int (*port_reuse_buffer) (void *object, uint32_t port_id, uint32_t buffer_id); + + /** + * Process the node + * + * This function must be called from the data thread. + * + * Output io areas with SPA_STATUS_NEED_DATA will recycle the + * buffers if any. + * + * Input areas with SPA_STATUS_HAVE_DATA are consumed if possible + * and the status is set to SPA_STATUS_NEED_DATA or SPA_STATUS_OK. + * + * When the node has new output buffers, the SPA_STATUS_HAVE_DATA + * bit will be set. + * + * When the node can accept new input in the next cycle, the + * SPA_STATUS_NEED_DATA bit will be set. + * + * Note that the node might return SPA_STATUS_NEED_DATA even when + * no input ports have this status. This means that the amount of + * data still available on the input ports is likely not going to + * be enough for the next cycle and the host might need to prefetch + * data for the next cycle. + */ + int (*process) (void *object); +}; + +#define spa_node_method(o,method,version,...) \ +({ \ + int _res = -ENOTSUP; \ + struct spa_node *_n = o; \ + spa_interface_call_res(&_n->iface, \ + struct spa_node_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define spa_node_method_fast(o,method,version,...) \ +({ \ + int _res; \ + struct spa_node *_n = o; \ + spa_interface_call_fast_res(&_n->iface, \ + struct spa_node_methods, _res, \ + method, version, ##__VA_ARGS__); \ + _res; \ +}) + +#define spa_node_add_listener(n,...) spa_node_method(n, add_listener, 0, __VA_ARGS__) +#define spa_node_set_callbacks(n,...) spa_node_method(n, set_callbacks, 0, __VA_ARGS__) +#define spa_node_sync(n,...) spa_node_method(n, sync, 0, __VA_ARGS__) +#define spa_node_enum_params(n,...) spa_node_method(n, enum_params, 0, __VA_ARGS__) +#define spa_node_set_param(n,...) spa_node_method(n, set_param, 0, __VA_ARGS__) +#define spa_node_set_io(n,...) spa_node_method(n, set_io, 0, __VA_ARGS__) +#define spa_node_send_command(n,...) spa_node_method(n, send_command, 0, __VA_ARGS__) +#define spa_node_add_port(n,...) spa_node_method(n, add_port, 0, __VA_ARGS__) +#define spa_node_remove_port(n,...) spa_node_method(n, remove_port, 0, __VA_ARGS__) +#define spa_node_port_enum_params(n,...) spa_node_method(n, port_enum_params, 0, __VA_ARGS__) +#define spa_node_port_set_param(n,...) spa_node_method(n, port_set_param, 0, __VA_ARGS__) +#define spa_node_port_use_buffers(n,...) spa_node_method(n, port_use_buffers, 0, __VA_ARGS__) +#define spa_node_port_set_io(n,...) spa_node_method(n, port_set_io, 0, __VA_ARGS__) + +#define spa_node_port_reuse_buffer(n,...) spa_node_method(n, port_reuse_buffer, 0, __VA_ARGS__) +#define spa_node_port_reuse_buffer_fast(n,...) spa_node_method_fast(n, port_reuse_buffer, 0, __VA_ARGS__) +#define spa_node_process(n) spa_node_method(n, process, 0) +#define spa_node_process_fast(n) spa_node_method_fast(n, process, 0) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_NODE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/audio/raw.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/audio/raw.h new file mode 100644 index 000000000000..a357d55970b3 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/audio/raw.h @@ -0,0 +1,303 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_RAW_H +#define SPA_AUDIO_RAW_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if !defined(__FreeBSD__) && !defined(__MidnightBSD__) +#include +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#define SPA_AUDIO_MAX_CHANNELS 64u + +enum spa_audio_format { + SPA_AUDIO_FORMAT_UNKNOWN, + SPA_AUDIO_FORMAT_ENCODED, + + /* interleaved formats */ + SPA_AUDIO_FORMAT_START_Interleaved = 0x100, + SPA_AUDIO_FORMAT_S8, + SPA_AUDIO_FORMAT_U8, + SPA_AUDIO_FORMAT_S16_LE, + SPA_AUDIO_FORMAT_S16_BE, + SPA_AUDIO_FORMAT_U16_LE, + SPA_AUDIO_FORMAT_U16_BE, + SPA_AUDIO_FORMAT_S24_32_LE, + SPA_AUDIO_FORMAT_S24_32_BE, + SPA_AUDIO_FORMAT_U24_32_LE, + SPA_AUDIO_FORMAT_U24_32_BE, + SPA_AUDIO_FORMAT_S32_LE, + SPA_AUDIO_FORMAT_S32_BE, + SPA_AUDIO_FORMAT_U32_LE, + SPA_AUDIO_FORMAT_U32_BE, + SPA_AUDIO_FORMAT_S24_LE, + SPA_AUDIO_FORMAT_S24_BE, + SPA_AUDIO_FORMAT_U24_LE, + SPA_AUDIO_FORMAT_U24_BE, + SPA_AUDIO_FORMAT_S20_LE, + SPA_AUDIO_FORMAT_S20_BE, + SPA_AUDIO_FORMAT_U20_LE, + SPA_AUDIO_FORMAT_U20_BE, + SPA_AUDIO_FORMAT_S18_LE, + SPA_AUDIO_FORMAT_S18_BE, + SPA_AUDIO_FORMAT_U18_LE, + SPA_AUDIO_FORMAT_U18_BE, + SPA_AUDIO_FORMAT_F32_LE, + SPA_AUDIO_FORMAT_F32_BE, + SPA_AUDIO_FORMAT_F64_LE, + SPA_AUDIO_FORMAT_F64_BE, + + SPA_AUDIO_FORMAT_ULAW, + SPA_AUDIO_FORMAT_ALAW, + + /* planar formats */ + SPA_AUDIO_FORMAT_START_Planar = 0x200, + SPA_AUDIO_FORMAT_U8P, + SPA_AUDIO_FORMAT_S16P, + SPA_AUDIO_FORMAT_S24_32P, + SPA_AUDIO_FORMAT_S32P, + SPA_AUDIO_FORMAT_S24P, + SPA_AUDIO_FORMAT_F32P, + SPA_AUDIO_FORMAT_F64P, + SPA_AUDIO_FORMAT_S8P, + + /* other formats start here */ + SPA_AUDIO_FORMAT_START_Other = 0x400, + + /* Aliases */ + + /* DSP formats */ + SPA_AUDIO_FORMAT_DSP_S32 = SPA_AUDIO_FORMAT_S24_32P, + SPA_AUDIO_FORMAT_DSP_F32 = SPA_AUDIO_FORMAT_F32P, + SPA_AUDIO_FORMAT_DSP_F64 = SPA_AUDIO_FORMAT_F64P, + + /* native endian */ +#if __BYTE_ORDER == __BIG_ENDIAN + SPA_AUDIO_FORMAT_S16 = SPA_AUDIO_FORMAT_S16_BE, + SPA_AUDIO_FORMAT_U16 = SPA_AUDIO_FORMAT_U16_BE, + SPA_AUDIO_FORMAT_S24_32 = SPA_AUDIO_FORMAT_S24_32_BE, + SPA_AUDIO_FORMAT_U24_32 = SPA_AUDIO_FORMAT_U24_32_BE, + SPA_AUDIO_FORMAT_S32 = SPA_AUDIO_FORMAT_S32_BE, + SPA_AUDIO_FORMAT_U32 = SPA_AUDIO_FORMAT_U32_BE, + SPA_AUDIO_FORMAT_S24 = SPA_AUDIO_FORMAT_S24_BE, + SPA_AUDIO_FORMAT_U24 = SPA_AUDIO_FORMAT_U24_BE, + SPA_AUDIO_FORMAT_S20 = SPA_AUDIO_FORMAT_S20_BE, + SPA_AUDIO_FORMAT_U20 = SPA_AUDIO_FORMAT_U20_BE, + SPA_AUDIO_FORMAT_S18 = SPA_AUDIO_FORMAT_S18_BE, + SPA_AUDIO_FORMAT_U18 = SPA_AUDIO_FORMAT_U18_BE, + SPA_AUDIO_FORMAT_F32 = SPA_AUDIO_FORMAT_F32_BE, + SPA_AUDIO_FORMAT_F64 = SPA_AUDIO_FORMAT_F64_BE, + SPA_AUDIO_FORMAT_S16_OE = SPA_AUDIO_FORMAT_S16_LE, + SPA_AUDIO_FORMAT_U16_OE = SPA_AUDIO_FORMAT_U16_LE, + SPA_AUDIO_FORMAT_S24_32_OE = SPA_AUDIO_FORMAT_S24_32_LE, + SPA_AUDIO_FORMAT_U24_32_OE = SPA_AUDIO_FORMAT_U24_32_LE, + SPA_AUDIO_FORMAT_S32_OE = SPA_AUDIO_FORMAT_S32_LE, + SPA_AUDIO_FORMAT_U32_OE = SPA_AUDIO_FORMAT_U32_LE, + SPA_AUDIO_FORMAT_S24_OE = SPA_AUDIO_FORMAT_S24_LE, + SPA_AUDIO_FORMAT_U24_OE = SPA_AUDIO_FORMAT_U24_LE, + SPA_AUDIO_FORMAT_S20_OE = SPA_AUDIO_FORMAT_S20_LE, + SPA_AUDIO_FORMAT_U20_OE = SPA_AUDIO_FORMAT_U20_LE, + SPA_AUDIO_FORMAT_S18_OE = SPA_AUDIO_FORMAT_S18_LE, + SPA_AUDIO_FORMAT_U18_OE = SPA_AUDIO_FORMAT_U18_LE, + SPA_AUDIO_FORMAT_F32_OE = SPA_AUDIO_FORMAT_F32_LE, + SPA_AUDIO_FORMAT_F64_OE = SPA_AUDIO_FORMAT_F64_LE, +#elif __BYTE_ORDER == __LITTLE_ENDIAN + SPA_AUDIO_FORMAT_S16 = SPA_AUDIO_FORMAT_S16_LE, + SPA_AUDIO_FORMAT_U16 = SPA_AUDIO_FORMAT_U16_LE, + SPA_AUDIO_FORMAT_S24_32 = SPA_AUDIO_FORMAT_S24_32_LE, + SPA_AUDIO_FORMAT_U24_32 = SPA_AUDIO_FORMAT_U24_32_LE, + SPA_AUDIO_FORMAT_S32 = SPA_AUDIO_FORMAT_S32_LE, + SPA_AUDIO_FORMAT_U32 = SPA_AUDIO_FORMAT_U32_LE, + SPA_AUDIO_FORMAT_S24 = SPA_AUDIO_FORMAT_S24_LE, + SPA_AUDIO_FORMAT_U24 = SPA_AUDIO_FORMAT_U24_LE, + SPA_AUDIO_FORMAT_S20 = SPA_AUDIO_FORMAT_S20_LE, + SPA_AUDIO_FORMAT_U20 = SPA_AUDIO_FORMAT_U20_LE, + SPA_AUDIO_FORMAT_S18 = SPA_AUDIO_FORMAT_S18_LE, + SPA_AUDIO_FORMAT_U18 = SPA_AUDIO_FORMAT_U18_LE, + SPA_AUDIO_FORMAT_F32 = SPA_AUDIO_FORMAT_F32_LE, + SPA_AUDIO_FORMAT_F64 = SPA_AUDIO_FORMAT_F64_LE, + SPA_AUDIO_FORMAT_S16_OE = SPA_AUDIO_FORMAT_S16_BE, + SPA_AUDIO_FORMAT_U16_OE = SPA_AUDIO_FORMAT_U16_BE, + SPA_AUDIO_FORMAT_S24_32_OE = SPA_AUDIO_FORMAT_S24_32_BE, + SPA_AUDIO_FORMAT_U24_32_OE = SPA_AUDIO_FORMAT_U24_32_BE, + SPA_AUDIO_FORMAT_S32_OE = SPA_AUDIO_FORMAT_S32_BE, + SPA_AUDIO_FORMAT_U32_OE = SPA_AUDIO_FORMAT_U32_BE, + SPA_AUDIO_FORMAT_S24_OE = SPA_AUDIO_FORMAT_S24_BE, + SPA_AUDIO_FORMAT_U24_OE = SPA_AUDIO_FORMAT_U24_BE, + SPA_AUDIO_FORMAT_S20_OE = SPA_AUDIO_FORMAT_S20_BE, + SPA_AUDIO_FORMAT_U20_OE = SPA_AUDIO_FORMAT_U20_BE, + SPA_AUDIO_FORMAT_S18_OE = SPA_AUDIO_FORMAT_S18_BE, + SPA_AUDIO_FORMAT_U18_OE = SPA_AUDIO_FORMAT_U18_BE, + SPA_AUDIO_FORMAT_F32_OE = SPA_AUDIO_FORMAT_F32_BE, + SPA_AUDIO_FORMAT_F64_OE = SPA_AUDIO_FORMAT_F64_BE, +#endif +}; + +#define SPA_AUDIO_FORMAT_IS_INTERLEAVED(fmt) ((fmt) > SPA_AUDIO_FORMAT_START_Interleaved && (fmt) < SPA_AUDIO_FORMAT_START_Planar) +#define SPA_AUDIO_FORMAT_IS_PLANAR(fmt) ((fmt) > SPA_AUDIO_FORMAT_START_Planar && (fmt) < SPA_AUDIO_FORMAT_START_Other) + +enum spa_audio_channel { + SPA_AUDIO_CHANNEL_UNKNOWN, /**< unspecified */ + SPA_AUDIO_CHANNEL_NA, /**< N/A, silent */ + + SPA_AUDIO_CHANNEL_MONO, /**< mono stream */ + + SPA_AUDIO_CHANNEL_FL, /**< front left */ + SPA_AUDIO_CHANNEL_FR, /**< front right */ + SPA_AUDIO_CHANNEL_FC, /**< front center */ + SPA_AUDIO_CHANNEL_LFE, /**< LFE */ + SPA_AUDIO_CHANNEL_SL, /**< side left */ + SPA_AUDIO_CHANNEL_SR, /**< side right */ + SPA_AUDIO_CHANNEL_FLC, /**< front left center */ + SPA_AUDIO_CHANNEL_FRC, /**< front right center */ + SPA_AUDIO_CHANNEL_RC, /**< rear center */ + SPA_AUDIO_CHANNEL_RL, /**< rear left */ + SPA_AUDIO_CHANNEL_RR, /**< rear right */ + SPA_AUDIO_CHANNEL_TC, /**< top center */ + SPA_AUDIO_CHANNEL_TFL, /**< top front left */ + SPA_AUDIO_CHANNEL_TFC, /**< top front center */ + SPA_AUDIO_CHANNEL_TFR, /**< top front right */ + SPA_AUDIO_CHANNEL_TRL, /**< top rear left */ + SPA_AUDIO_CHANNEL_TRC, /**< top rear center */ + SPA_AUDIO_CHANNEL_TRR, /**< top rear right */ + SPA_AUDIO_CHANNEL_RLC, /**< rear left center */ + SPA_AUDIO_CHANNEL_RRC, /**< rear right center */ + SPA_AUDIO_CHANNEL_FLW, /**< front left wide */ + SPA_AUDIO_CHANNEL_FRW, /**< front right wide */ + SPA_AUDIO_CHANNEL_LFE2, /**< LFE 2 */ + SPA_AUDIO_CHANNEL_FLH, /**< front left high */ + SPA_AUDIO_CHANNEL_FCH, /**< front center high */ + SPA_AUDIO_CHANNEL_FRH, /**< front right high */ + SPA_AUDIO_CHANNEL_TFLC, /**< top front left center */ + SPA_AUDIO_CHANNEL_TFRC, /**< top front right center */ + SPA_AUDIO_CHANNEL_TSL, /**< top side left */ + SPA_AUDIO_CHANNEL_TSR, /**< top side right */ + SPA_AUDIO_CHANNEL_LLFE, /**< left LFE */ + SPA_AUDIO_CHANNEL_RLFE, /**< right LFE */ + SPA_AUDIO_CHANNEL_BC, /**< bottom center */ + SPA_AUDIO_CHANNEL_BLC, /**< bottom left center */ + SPA_AUDIO_CHANNEL_BRC, /**< bottom right center */ + + SPA_AUDIO_CHANNEL_START_Aux = 0x1000, /**< aux channels */ + SPA_AUDIO_CHANNEL_AUX0 = SPA_AUDIO_CHANNEL_START_Aux, + SPA_AUDIO_CHANNEL_AUX1, + SPA_AUDIO_CHANNEL_AUX2, + SPA_AUDIO_CHANNEL_AUX3, + SPA_AUDIO_CHANNEL_AUX4, + SPA_AUDIO_CHANNEL_AUX5, + SPA_AUDIO_CHANNEL_AUX6, + SPA_AUDIO_CHANNEL_AUX7, + SPA_AUDIO_CHANNEL_AUX8, + SPA_AUDIO_CHANNEL_AUX9, + SPA_AUDIO_CHANNEL_AUX10, + SPA_AUDIO_CHANNEL_AUX11, + SPA_AUDIO_CHANNEL_AUX12, + SPA_AUDIO_CHANNEL_AUX13, + SPA_AUDIO_CHANNEL_AUX14, + SPA_AUDIO_CHANNEL_AUX15, + SPA_AUDIO_CHANNEL_AUX16, + SPA_AUDIO_CHANNEL_AUX17, + SPA_AUDIO_CHANNEL_AUX18, + SPA_AUDIO_CHANNEL_AUX19, + SPA_AUDIO_CHANNEL_AUX20, + SPA_AUDIO_CHANNEL_AUX21, + SPA_AUDIO_CHANNEL_AUX22, + SPA_AUDIO_CHANNEL_AUX23, + SPA_AUDIO_CHANNEL_AUX24, + SPA_AUDIO_CHANNEL_AUX25, + SPA_AUDIO_CHANNEL_AUX26, + SPA_AUDIO_CHANNEL_AUX27, + SPA_AUDIO_CHANNEL_AUX28, + SPA_AUDIO_CHANNEL_AUX29, + SPA_AUDIO_CHANNEL_AUX30, + SPA_AUDIO_CHANNEL_AUX31, + SPA_AUDIO_CHANNEL_AUX32, + SPA_AUDIO_CHANNEL_AUX33, + SPA_AUDIO_CHANNEL_AUX34, + SPA_AUDIO_CHANNEL_AUX35, + SPA_AUDIO_CHANNEL_AUX36, + SPA_AUDIO_CHANNEL_AUX37, + SPA_AUDIO_CHANNEL_AUX38, + SPA_AUDIO_CHANNEL_AUX39, + SPA_AUDIO_CHANNEL_AUX40, + SPA_AUDIO_CHANNEL_AUX41, + SPA_AUDIO_CHANNEL_AUX42, + SPA_AUDIO_CHANNEL_AUX43, + SPA_AUDIO_CHANNEL_AUX44, + SPA_AUDIO_CHANNEL_AUX45, + SPA_AUDIO_CHANNEL_AUX46, + SPA_AUDIO_CHANNEL_AUX47, + SPA_AUDIO_CHANNEL_AUX48, + SPA_AUDIO_CHANNEL_AUX49, + SPA_AUDIO_CHANNEL_AUX50, + SPA_AUDIO_CHANNEL_AUX51, + SPA_AUDIO_CHANNEL_AUX52, + SPA_AUDIO_CHANNEL_AUX53, + SPA_AUDIO_CHANNEL_AUX54, + SPA_AUDIO_CHANNEL_AUX55, + SPA_AUDIO_CHANNEL_AUX56, + SPA_AUDIO_CHANNEL_AUX57, + SPA_AUDIO_CHANNEL_AUX58, + SPA_AUDIO_CHANNEL_AUX59, + SPA_AUDIO_CHANNEL_AUX60, + SPA_AUDIO_CHANNEL_AUX61, + SPA_AUDIO_CHANNEL_AUX62, + SPA_AUDIO_CHANNEL_AUX63, + + SPA_AUDIO_CHANNEL_LAST_Aux = 0x1fff, /**< aux channels */ + + SPA_AUDIO_CHANNEL_START_Custom = 0x10000, +}; + +enum spa_audio_volume_ramp_scale { + SPA_AUDIO_VOLUME_RAMP_INVALID, + SPA_AUDIO_VOLUME_RAMP_LINEAR, + SPA_AUDIO_VOLUME_RAMP_CUBIC, +}; + +/** Extra audio flags */ +#define SPA_AUDIO_FLAG_NONE (0) /*< no valid flag */ +#define SPA_AUDIO_FLAG_UNPOSITIONED (1 << 0) /*< the position array explicitly + * contains unpositioned channels. */ +/** Audio information description */ +struct spa_audio_info_raw { + enum spa_audio_format format; /*< format, one of enum spa_audio_format */ + uint32_t flags; /*< extra flags */ + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ + uint32_t position[SPA_AUDIO_MAX_CHANNELS]; /*< channel position from enum spa_audio_channel */ +}; + +#define SPA_AUDIO_INFO_RAW_INIT(...) ((struct spa_audio_info_raw) { __VA_ARGS__ }) + +#define SPA_KEY_AUDIO_FORMAT "audio.format" /**< an audio format as string, + * Ex. "S16LE" */ +#define SPA_KEY_AUDIO_CHANNEL "audio.channel" /**< an audio channel as string, + * Ex. "FL" */ +#define SPA_KEY_AUDIO_CHANNELS "audio.channels" /**< an audio channel count as int */ +#define SPA_KEY_AUDIO_RATE "audio.rate" /**< an audio sample rate as int */ +#define SPA_KEY_AUDIO_POSITION "audio.position" /**< channel positions as comma separated list + * of channels ex. "FL,FR" */ +#define SPA_KEY_AUDIO_ALLOWED_RATES "audio.allowed-rates" /**< a list of allowed samplerates + * ex. "[ 44100 48000 ]" */ +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_RAW_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/buffers.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/buffers.h new file mode 100644 index 000000000000..399d3a5f0942 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/buffers.h @@ -0,0 +1,52 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_BUFFERS_H +#define SPA_PARAM_BUFFERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +/** properties for SPA_TYPE_OBJECT_ParamBuffers */ +enum spa_param_buffers { + SPA_PARAM_BUFFERS_START, + SPA_PARAM_BUFFERS_buffers, /**< number of buffers (Int) */ + SPA_PARAM_BUFFERS_blocks, /**< number of data blocks per buffer (Int) */ + SPA_PARAM_BUFFERS_size, /**< size of a data block memory (Int)*/ + SPA_PARAM_BUFFERS_stride, /**< stride of data block memory (Int) */ + SPA_PARAM_BUFFERS_align, /**< alignment of data block memory (Int) */ + SPA_PARAM_BUFFERS_dataType, /**< possible memory types (Int, mask of enum spa_data_type) */ +}; + +/** properties for SPA_TYPE_OBJECT_ParamMeta */ +enum spa_param_meta { + SPA_PARAM_META_START, + SPA_PARAM_META_type, /**< the metadata, one of enum spa_meta_type (Id enum spa_meta_type) */ + SPA_PARAM_META_size, /**< the expected maximum size the meta (Int) */ +}; + +/** properties for SPA_TYPE_OBJECT_ParamIO */ +enum spa_param_io { + SPA_PARAM_IO_START, + SPA_PARAM_IO_id, /**< type ID, uniquely identifies the io area (Id enum spa_io_type) */ + SPA_PARAM_IO_size, /**< size of the io area (Int) */ +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_BUFFERS_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/format.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/format.h new file mode 100644 index 000000000000..3f075fd36e31 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/format.h @@ -0,0 +1,157 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_FORMAT_H +#define SPA_PARAM_FORMAT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +/** media type for SPA_TYPE_OBJECT_Format */ +enum spa_media_type { + SPA_MEDIA_TYPE_unknown, + SPA_MEDIA_TYPE_audio, + SPA_MEDIA_TYPE_video, + SPA_MEDIA_TYPE_image, + SPA_MEDIA_TYPE_binary, + SPA_MEDIA_TYPE_stream, + SPA_MEDIA_TYPE_application, +}; + +/** media subtype for SPA_TYPE_OBJECT_Format */ +enum spa_media_subtype { + SPA_MEDIA_SUBTYPE_unknown, + SPA_MEDIA_SUBTYPE_raw, + SPA_MEDIA_SUBTYPE_dsp, + SPA_MEDIA_SUBTYPE_iec958, /** S/PDIF */ + SPA_MEDIA_SUBTYPE_dsd, + + SPA_MEDIA_SUBTYPE_START_Audio = 0x10000, + SPA_MEDIA_SUBTYPE_mp3, + SPA_MEDIA_SUBTYPE_aac, + SPA_MEDIA_SUBTYPE_vorbis, + SPA_MEDIA_SUBTYPE_wma, + SPA_MEDIA_SUBTYPE_ra, + SPA_MEDIA_SUBTYPE_sbc, + SPA_MEDIA_SUBTYPE_adpcm, + SPA_MEDIA_SUBTYPE_g723, + SPA_MEDIA_SUBTYPE_g726, + SPA_MEDIA_SUBTYPE_g729, + SPA_MEDIA_SUBTYPE_amr, + SPA_MEDIA_SUBTYPE_gsm, + SPA_MEDIA_SUBTYPE_alac, /** since 0.3.65 */ + SPA_MEDIA_SUBTYPE_flac, /** since 0.3.65 */ + SPA_MEDIA_SUBTYPE_ape, /** since 0.3.65 */ + SPA_MEDIA_SUBTYPE_opus, /** since 0.3.68 */ + + SPA_MEDIA_SUBTYPE_START_Video = 0x20000, + SPA_MEDIA_SUBTYPE_h264, + SPA_MEDIA_SUBTYPE_mjpg, + SPA_MEDIA_SUBTYPE_dv, + SPA_MEDIA_SUBTYPE_mpegts, + SPA_MEDIA_SUBTYPE_h263, + SPA_MEDIA_SUBTYPE_mpeg1, + SPA_MEDIA_SUBTYPE_mpeg2, + SPA_MEDIA_SUBTYPE_mpeg4, + SPA_MEDIA_SUBTYPE_xvid, + SPA_MEDIA_SUBTYPE_vc1, + SPA_MEDIA_SUBTYPE_vp8, + SPA_MEDIA_SUBTYPE_vp9, + SPA_MEDIA_SUBTYPE_bayer, + + SPA_MEDIA_SUBTYPE_START_Image = 0x30000, + SPA_MEDIA_SUBTYPE_jpeg, + + SPA_MEDIA_SUBTYPE_START_Binary = 0x40000, + + SPA_MEDIA_SUBTYPE_START_Stream = 0x50000, + SPA_MEDIA_SUBTYPE_midi, + + SPA_MEDIA_SUBTYPE_START_Application = 0x60000, + SPA_MEDIA_SUBTYPE_control, /**< control stream, data contains + * spa_pod_sequence with control info. */ +}; + +/** properties for audio SPA_TYPE_OBJECT_Format */ +enum spa_format { + SPA_FORMAT_START, + + SPA_FORMAT_mediaType, /**< media type (Id enum spa_media_type) */ + SPA_FORMAT_mediaSubtype, /**< media subtype (Id enum spa_media_subtype) */ + + /* Audio format keys */ + SPA_FORMAT_START_Audio = 0x10000, + SPA_FORMAT_AUDIO_format, /**< audio format, (Id enum spa_audio_format) */ + SPA_FORMAT_AUDIO_flags, /**< optional flags (Int) */ + SPA_FORMAT_AUDIO_rate, /**< sample rate (Int) */ + SPA_FORMAT_AUDIO_channels, /**< number of audio channels (Int) */ + SPA_FORMAT_AUDIO_position, /**< channel positions (Id enum spa_audio_position) */ + + SPA_FORMAT_AUDIO_iec958Codec, /**< codec used (IEC958) (Id enum spa_audio_iec958_codec) */ + + SPA_FORMAT_AUDIO_bitorder, /**< bit order (Id enum spa_param_bitorder) */ + SPA_FORMAT_AUDIO_interleave, /**< Interleave bytes (Int) */ + SPA_FORMAT_AUDIO_bitrate, /**< bit rate (Int) */ + SPA_FORMAT_AUDIO_blockAlign, /**< audio data block alignment (Int) */ + + SPA_FORMAT_AUDIO_AAC_streamFormat, /**< AAC stream format, (Id enum spa_audio_aac_stream_format) */ + + SPA_FORMAT_AUDIO_WMA_profile, /**< WMA profile (Id enum spa_audio_wma_profile) */ + + SPA_FORMAT_AUDIO_AMR_bandMode, /**< AMR band mode (Id enum spa_audio_amr_band_mode) */ + + + /* Video Format keys */ + SPA_FORMAT_START_Video = 0x20000, + SPA_FORMAT_VIDEO_format, /**< video format (Id enum spa_video_format) */ + SPA_FORMAT_VIDEO_modifier, /**< format modifier (Long) + * use only with DMA-BUF and omit for other buffer types */ + SPA_FORMAT_VIDEO_size, /**< size (Rectangle) */ + SPA_FORMAT_VIDEO_framerate, /**< frame rate (Fraction) */ + SPA_FORMAT_VIDEO_maxFramerate, /**< maximum frame rate (Fraction) */ + SPA_FORMAT_VIDEO_views, /**< number of views (Int) */ + SPA_FORMAT_VIDEO_interlaceMode, /**< (Id enum spa_video_interlace_mode) */ + SPA_FORMAT_VIDEO_pixelAspectRatio, /**< (Rectangle) */ + SPA_FORMAT_VIDEO_multiviewMode, /**< (Id enum spa_video_multiview_mode) */ + SPA_FORMAT_VIDEO_multiviewFlags, /**< (Id enum spa_video_multiview_flags) */ + SPA_FORMAT_VIDEO_chromaSite, /**< /Id enum spa_video_chroma_site) */ + SPA_FORMAT_VIDEO_colorRange, /**< /Id enum spa_video_color_range) */ + SPA_FORMAT_VIDEO_colorMatrix, /**< /Id enum spa_video_color_matrix) */ + SPA_FORMAT_VIDEO_transferFunction, /**< /Id enum spa_video_transfer_function) */ + SPA_FORMAT_VIDEO_colorPrimaries, /**< /Id enum spa_video_color_primaries) */ + SPA_FORMAT_VIDEO_profile, /**< (Int) */ + SPA_FORMAT_VIDEO_level, /**< (Int) */ + SPA_FORMAT_VIDEO_H264_streamFormat, /**< (Id enum spa_h264_stream_format) */ + SPA_FORMAT_VIDEO_H264_alignment, /**< (Id enum spa_h264_alignment) */ + + /* Image Format keys */ + SPA_FORMAT_START_Image = 0x30000, + /* Binary Format keys */ + SPA_FORMAT_START_Binary = 0x40000, + /* Stream Format keys */ + SPA_FORMAT_START_Stream = 0x50000, + /* Application Format keys */ + SPA_FORMAT_START_Application = 0x60000, +}; + +#define SPA_KEY_FORMAT_DSP "format.dsp" /**< a predefined DSP format, + * Ex. "32 bit float mono audio" */ + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_FORMAT_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/param.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/param.h new file mode 100644 index 000000000000..51c442c353e8 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/param.h @@ -0,0 +1,88 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_H +#define SPA_PARAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup spa_param Parameters + * Parameter value enumerations and type information + */ + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +/** different parameter types that can be queried */ +enum spa_param_type { + SPA_PARAM_Invalid, /**< invalid */ + SPA_PARAM_PropInfo, /**< property information as SPA_TYPE_OBJECT_PropInfo */ + SPA_PARAM_Props, /**< properties as SPA_TYPE_OBJECT_Props */ + SPA_PARAM_EnumFormat, /**< available formats as SPA_TYPE_OBJECT_Format */ + SPA_PARAM_Format, /**< configured format as SPA_TYPE_OBJECT_Format */ + SPA_PARAM_Buffers, /**< buffer configurations as SPA_TYPE_OBJECT_ParamBuffers*/ + SPA_PARAM_Meta, /**< allowed metadata for buffers as SPA_TYPE_OBJECT_ParamMeta*/ + SPA_PARAM_IO, /**< configurable IO areas as SPA_TYPE_OBJECT_ParamIO */ + SPA_PARAM_EnumProfile, /**< profile enumeration as SPA_TYPE_OBJECT_ParamProfile */ + SPA_PARAM_Profile, /**< profile configuration as SPA_TYPE_OBJECT_ParamProfile */ + SPA_PARAM_EnumPortConfig, /**< port configuration enumeration as SPA_TYPE_OBJECT_ParamPortConfig */ + SPA_PARAM_PortConfig, /**< port configuration as SPA_TYPE_OBJECT_ParamPortConfig */ + SPA_PARAM_EnumRoute, /**< routing enumeration as SPA_TYPE_OBJECT_ParamRoute */ + SPA_PARAM_Route, /**< routing configuration as SPA_TYPE_OBJECT_ParamRoute */ + SPA_PARAM_Control, /**< Control parameter, a SPA_TYPE_Sequence */ + SPA_PARAM_Latency, /**< latency reporting, a SPA_TYPE_OBJECT_ParamLatency */ + SPA_PARAM_ProcessLatency, /**< processing latency, a SPA_TYPE_OBJECT_ParamProcessLatency */ + SPA_PARAM_Tag, /**< tag reporting, a SPA_TYPE_OBJECT_ParamTag. Since 0.3.79 */ +}; + +/** information about a parameter */ +struct spa_param_info { + uint32_t id; /**< enum spa_param_type */ +#define SPA_PARAM_INFO_SERIAL (1<<0) /**< bit to signal update even when the + * read/write flags don't change */ +#define SPA_PARAM_INFO_READ (1<<1) +#define SPA_PARAM_INFO_WRITE (1<<2) +#define SPA_PARAM_INFO_READWRITE (SPA_PARAM_INFO_WRITE|SPA_PARAM_INFO_READ) + uint32_t flags; + uint32_t user; /**< private user field. You can use this to keep + * state. */ + int32_t seq; /**< private seq field. You can use this to keep + * state of a pending update. */ + uint32_t padding[4]; +}; + +#define SPA_PARAM_INFO(id,flags) ((struct spa_param_info){ (id), (flags) }) + +enum spa_param_bitorder { + SPA_PARAM_BITORDER_unknown, /**< unknown bitorder */ + SPA_PARAM_BITORDER_msb, /**< most significant bit */ + SPA_PARAM_BITORDER_lsb, /**< least significant bit */ +}; + +enum spa_param_availability { + SPA_PARAM_AVAILABILITY_unknown, /**< unknown availability */ + SPA_PARAM_AVAILABILITY_no, /**< not available */ + SPA_PARAM_AVAILABILITY_yes, /**< available */ +}; + +#include +#include +#include +#include + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/port-config.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/port-config.h new file mode 100644 index 000000000000..7e05eda27617 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/port-config.h @@ -0,0 +1,46 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_PORT_CONFIG_H +#define SPA_PARAM_PORT_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +enum spa_param_port_config_mode { + SPA_PARAM_PORT_CONFIG_MODE_none, /**< no configuration */ + SPA_PARAM_PORT_CONFIG_MODE_passthrough, /**< passthrough configuration */ + SPA_PARAM_PORT_CONFIG_MODE_convert, /**< convert configuration */ + SPA_PARAM_PORT_CONFIG_MODE_dsp, /**< dsp configuration, depending on the external + * format. For audio, ports will be configured for + * the given number of channels with F32 format. */ +}; + +/** properties for SPA_TYPE_OBJECT_ParamPortConfig */ +enum spa_param_port_config { + SPA_PARAM_PORT_CONFIG_START, + SPA_PARAM_PORT_CONFIG_direction, /**< (Id enum spa_direction) direction */ + SPA_PARAM_PORT_CONFIG_mode, /**< (Id enum spa_param_port_config_mode) mode */ + SPA_PARAM_PORT_CONFIG_monitor, /**< (Bool) enable monitor output ports on input ports */ + SPA_PARAM_PORT_CONFIG_control, /**< (Bool) enable control ports */ + SPA_PARAM_PORT_CONFIG_format, /**< (Object) format filter */ +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_PORT_CONFIG_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/profile.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/profile.h new file mode 100644 index 000000000000..00468f36d50b --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/profile.h @@ -0,0 +1,52 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_PROFILE_H +#define SPA_PARAM_PROFILE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +/** properties for SPA_TYPE_OBJECT_ParamProfile */ +enum spa_param_profile { + SPA_PARAM_PROFILE_START, + SPA_PARAM_PROFILE_index, /**< profile index (Int) */ + SPA_PARAM_PROFILE_name, /**< profile name (String) */ + SPA_PARAM_PROFILE_description, /**< profile description (String) */ + SPA_PARAM_PROFILE_priority, /**< profile priority (Int) */ + SPA_PARAM_PROFILE_available, /**< availability of the profile + * (Id enum spa_param_availability) */ + SPA_PARAM_PROFILE_info, /**< info (Struct( + * Int : n_items, + * (String : key, + * String : value)*)) */ + SPA_PARAM_PROFILE_classes, /**< node classes provided by this profile + * (Struct( + * Int : number of items following + * Struct( + * String : class name (eg. "Audio/Source"), + * Int : number of nodes + * String : property (eg. "card.profile.devices"), + * Array of Int: device indexes + * )*)) */ + SPA_PARAM_PROFILE_save, /**< If profile should be saved (Bool) */ +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_PROFILE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/param/route.h b/thirdparty/linuxbsd_headers/pipewire/spa/param/route.h new file mode 100644 index 000000000000..d73880c5ac94 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/param/route.h @@ -0,0 +1,49 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_ROUTE_H +#define SPA_PARAM_ROUTE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +/** properties for SPA_TYPE_OBJECT_ParamRoute */ +enum spa_param_route { + SPA_PARAM_ROUTE_START, + SPA_PARAM_ROUTE_index, /**< index of the routing destination (Int) */ + SPA_PARAM_ROUTE_direction, /**< direction, input/output (Id enum spa_direction) */ + SPA_PARAM_ROUTE_device, /**< device id (Int) */ + SPA_PARAM_ROUTE_name, /**< name of the routing destination (String) */ + SPA_PARAM_ROUTE_description, /**< description of the destination (String) */ + SPA_PARAM_ROUTE_priority, /**< priority of the destination (Int) */ + SPA_PARAM_ROUTE_available, /**< availability of the destination + * (Id enum spa_param_availability) */ + SPA_PARAM_ROUTE_info, /**< info (Struct( + * Int : n_items, + * (String : key, + * String : value)*)) */ + SPA_PARAM_ROUTE_profiles, /**< associated profile indexes (Array of Int) */ + SPA_PARAM_ROUTE_props, /**< properties SPA_TYPE_OBJECT_Props */ + SPA_PARAM_ROUTE_devices, /**< associated device indexes (Array of Int) */ + SPA_PARAM_ROUTE_profile, /**< profile id (Int) */ + SPA_PARAM_ROUTE_save, /**< If route should be saved (Bool) */ +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_ROUTE_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/pod/builder.h b/thirdparty/linuxbsd_headers/pipewire/spa/pod/builder.h new file mode 100644 index 000000000000..fdf9e93685bb --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/pod/builder.h @@ -0,0 +1,681 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_POD_BUILDER_H +#define SPA_POD_BUILDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup spa_pod POD + * Binary data serialization format + */ + +/** + * \addtogroup spa_pod + * \{ + */ + +#include + +#include +#include +#include + +struct spa_pod_builder_state { + uint32_t offset; +#define SPA_POD_BUILDER_FLAG_BODY (1<<0) +#define SPA_POD_BUILDER_FLAG_FIRST (1<<1) + uint32_t flags; + struct spa_pod_frame *frame; +}; + +struct spa_pod_builder; + +struct spa_pod_builder_callbacks { +#define SPA_VERSION_POD_BUILDER_CALLBACKS 0 + uint32_t version; + + int (*overflow) (void *data, uint32_t size); +}; + +struct spa_pod_builder { + void *data; + uint32_t size; + uint32_t _padding; + struct spa_pod_builder_state state; + struct spa_callbacks callbacks; +}; + +#define SPA_POD_BUILDER_INIT(buffer,size) ((struct spa_pod_builder){ (buffer), (size), 0, {}, {} }) + +static inline void +spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builder_state *state) +{ + *state = builder->state; +} + +static inline void +spa_pod_builder_set_callbacks(struct spa_pod_builder *builder, + const struct spa_pod_builder_callbacks *callbacks, void *data) +{ + builder->callbacks = SPA_CALLBACKS_INIT(callbacks, data); +} + +static inline void +spa_pod_builder_reset(struct spa_pod_builder *builder, struct spa_pod_builder_state *state) +{ + struct spa_pod_frame *f; + uint32_t size = builder->state.offset - state->offset; + builder->state = *state; + for (f = builder->state.frame; f ; f = f->parent) + f->pod.size -= size; +} + +static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size) +{ + *builder = SPA_POD_BUILDER_INIT(data, size); +} + +static inline struct spa_pod * +spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset) +{ + uint32_t size = builder->size; + if (offset + 8 <= size) { + struct spa_pod *pod = SPA_PTROFF(builder->data, offset, struct spa_pod); + if (offset + SPA_POD_SIZE(pod) <= size) + return pod; + } + return NULL; +} + +static inline struct spa_pod * +spa_pod_builder_frame(struct spa_pod_builder *builder, struct spa_pod_frame *frame) +{ + if (frame->offset + SPA_POD_SIZE(&frame->pod) <= builder->size) + return SPA_PTROFF(builder->data, frame->offset, struct spa_pod); + return NULL; +} + +static inline void +spa_pod_builder_push(struct spa_pod_builder *builder, + struct spa_pod_frame *frame, + const struct spa_pod *pod, + uint32_t offset) +{ + frame->pod = *pod; + frame->offset = offset; + frame->parent = builder->state.frame; + frame->flags = builder->state.flags; + builder->state.frame = frame; + + if (frame->pod.type == SPA_TYPE_Array || frame->pod.type == SPA_TYPE_Choice) + builder->state.flags = SPA_POD_BUILDER_FLAG_FIRST | SPA_POD_BUILDER_FLAG_BODY; +} + +static inline int spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t size) +{ + int res = 0; + struct spa_pod_frame *f; + uint32_t offset = builder->state.offset; + + if (offset + size > builder->size) { + res = -ENOSPC; + if (offset <= builder->size) + spa_callbacks_call_res(&builder->callbacks, + struct spa_pod_builder_callbacks, res, + overflow, 0, offset + size); + } + if (res == 0 && data) + memcpy(SPA_PTROFF(builder->data, offset, void), data, size); + + builder->state.offset += size; + + for (f = builder->state.frame; f ; f = f->parent) + f->pod.size += size; + + return res; +} + +static inline int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size) +{ + uint64_t zeroes = 0; + size = SPA_ROUND_UP_N(size, 8) - size; + return size ? spa_pod_builder_raw(builder, &zeroes, size) : 0; +} + +static inline int +spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, uint32_t size) +{ + int r, res = spa_pod_builder_raw(builder, data, size); + if ((r = spa_pod_builder_pad(builder, size)) < 0) + res = r; + return res; +} + +static inline void *spa_pod_builder_pop(struct spa_pod_builder *builder, struct spa_pod_frame *frame) +{ + struct spa_pod *pod; + + if (SPA_FLAG_IS_SET(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST)) { + const struct spa_pod p = { 0, SPA_TYPE_None }; + spa_pod_builder_raw(builder, &p, sizeof(p)); + } + if ((pod = (struct spa_pod*)spa_pod_builder_frame(builder, frame)) != NULL) + *pod = frame->pod; + + builder->state.frame = frame->parent; + builder->state.flags = frame->flags; + spa_pod_builder_pad(builder, builder->state.offset); + return pod; +} + +static inline int +spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod *p) +{ + const void *data; + uint32_t size; + int r, res; + + if (builder->state.flags == SPA_POD_BUILDER_FLAG_BODY) { + data = SPA_POD_BODY_CONST(p); + size = SPA_POD_BODY_SIZE(p); + } else { + data = p; + size = SPA_POD_SIZE(p); + SPA_FLAG_CLEAR(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST); + } + res = spa_pod_builder_raw(builder, data, size); + if (builder->state.flags != SPA_POD_BUILDER_FLAG_BODY) + if ((r = spa_pod_builder_pad(builder, size)) < 0) + res = r; + return res; +} + +#define SPA_POD_INIT(size,type) ((struct spa_pod) { (size), (type) }) + +#define SPA_POD_INIT_None() SPA_POD_INIT(0, SPA_TYPE_None) + +static inline int spa_pod_builder_none(struct spa_pod_builder *builder) +{ + const struct spa_pod p = SPA_POD_INIT_None(); + return spa_pod_builder_primitive(builder, &p); +} + +static inline int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_t size, uint32_t type) +{ + const struct spa_pod p = SPA_POD_INIT(size,type); + SPA_FLAG_CLEAR(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST); + return spa_pod_builder_raw(builder, &p, sizeof(p)); +} + +#define SPA_POD_INIT_Bool(val) ((struct spa_pod_bool){ { sizeof(uint32_t), SPA_TYPE_Bool }, (val) ? 1 : 0, 0 }) + +static inline int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val) +{ + const struct spa_pod_bool p = SPA_POD_INIT_Bool(val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Id(val) ((struct spa_pod_id){ { sizeof(uint32_t), SPA_TYPE_Id }, (val), 0 }) + +static inline int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t val) +{ + const struct spa_pod_id p = SPA_POD_INIT_Id(val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Int(val) ((struct spa_pod_int){ { sizeof(int32_t), SPA_TYPE_Int }, (val), 0 }) + +static inline int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val) +{ + const struct spa_pod_int p = SPA_POD_INIT_Int(val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Long(val) ((struct spa_pod_long){ { sizeof(int64_t), SPA_TYPE_Long }, (val) }) + +static inline int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val) +{ + const struct spa_pod_long p = SPA_POD_INIT_Long(val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Float(val) ((struct spa_pod_float){ { sizeof(float), SPA_TYPE_Float }, (val), 0 }) + +static inline int spa_pod_builder_float(struct spa_pod_builder *builder, float val) +{ + const struct spa_pod_float p = SPA_POD_INIT_Float(val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Double(val) ((struct spa_pod_double){ { sizeof(double), SPA_TYPE_Double }, (val) }) + +static inline int spa_pod_builder_double(struct spa_pod_builder *builder, double val) +{ + const struct spa_pod_double p = SPA_POD_INIT_Double(val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_String(len) ((struct spa_pod_string){ { (len), SPA_TYPE_String } }) + +static inline int +spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, uint32_t len) +{ + int r, res; + res = spa_pod_builder_raw(builder, str, len); + if ((r = spa_pod_builder_raw(builder, "", 1)) < 0) + res = r; + if ((r = spa_pod_builder_pad(builder, builder->state.offset)) < 0) + res = r; + return res; +} + +static inline int +spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uint32_t len) +{ + const struct spa_pod_string p = SPA_POD_INIT_String(len+1); + int r, res = spa_pod_builder_raw(builder, &p, sizeof(p)); + if ((r = spa_pod_builder_write_string(builder, str, len)) < 0) + res = r; + return res; +} + +static inline int spa_pod_builder_string(struct spa_pod_builder *builder, const char *str) +{ + uint32_t len = str ? strlen(str) : 0; + return spa_pod_builder_string_len(builder, str ? str : "", len); +} + +#define SPA_POD_INIT_Bytes(len) ((struct spa_pod_bytes){ { (len), SPA_TYPE_Bytes } }) + +static inline int +spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32_t len) +{ + const struct spa_pod_bytes p = SPA_POD_INIT_Bytes(len); + int r, res = spa_pod_builder_raw(builder, &p, sizeof(p)); + if ((r = spa_pod_builder_raw_padded(builder, bytes, len)) < 0) + res = r; + return res; +} +static inline void * +spa_pod_builder_reserve_bytes(struct spa_pod_builder *builder, uint32_t len) +{ + uint32_t offset = builder->state.offset; + if (spa_pod_builder_bytes(builder, NULL, len) < 0) + return NULL; + return SPA_POD_BODY(spa_pod_builder_deref(builder, offset)); +} + +#define SPA_POD_INIT_Pointer(type,value) ((struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { (type), 0, (value) } }) + +static inline int +spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const void *val) +{ + const struct spa_pod_pointer p = SPA_POD_INIT_Pointer(type, val); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Fd(fd) ((struct spa_pod_fd){ { sizeof(int64_t), SPA_TYPE_Fd }, (fd) }) + +static inline int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd) +{ + const struct spa_pod_fd p = SPA_POD_INIT_Fd(fd); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Rectangle(val) ((struct spa_pod_rectangle){ { sizeof(struct spa_rectangle), SPA_TYPE_Rectangle }, (val) }) + +static inline int +spa_pod_builder_rectangle(struct spa_pod_builder *builder, uint32_t width, uint32_t height) +{ + const struct spa_pod_rectangle p = SPA_POD_INIT_Rectangle(SPA_RECTANGLE(width, height)); + return spa_pod_builder_primitive(builder, &p.pod); +} + +#define SPA_POD_INIT_Fraction(val) ((struct spa_pod_fraction){ { sizeof(struct spa_fraction), SPA_TYPE_Fraction }, (val) }) + +static inline int +spa_pod_builder_fraction(struct spa_pod_builder *builder, uint32_t num, uint32_t denom) +{ + const struct spa_pod_fraction p = SPA_POD_INIT_Fraction(SPA_FRACTION(num, denom)); + return spa_pod_builder_primitive(builder, &p.pod); +} + +static inline int +spa_pod_builder_push_array(struct spa_pod_builder *builder, struct spa_pod_frame *frame) +{ + const struct spa_pod_array p = + { {sizeof(struct spa_pod_array_body) - sizeof(struct spa_pod), SPA_TYPE_Array}, + {{0, 0}} }; + uint32_t offset = builder->state.offset; + int res = spa_pod_builder_raw(builder, &p, sizeof(p) - sizeof(struct spa_pod)); + spa_pod_builder_push(builder, frame, &p.pod, offset); + return res; +} + +static inline int +spa_pod_builder_array(struct spa_pod_builder *builder, + uint32_t child_size, uint32_t child_type, uint32_t n_elems, const void *elems) +{ + const struct spa_pod_array p = { + {(uint32_t)(sizeof(struct spa_pod_array_body) + n_elems * child_size), SPA_TYPE_Array}, + {{child_size, child_type}} + }; + int r, res = spa_pod_builder_raw(builder, &p, sizeof(p)); + if ((r = spa_pod_builder_raw_padded(builder, elems, child_size * n_elems)) < 0) + res = r; + return res; +} + +#define SPA_POD_INIT_CHOICE_BODY(type, flags, child_size, child_type) \ + ((struct spa_pod_choice_body) { (type), (flags), { (child_size), (child_type) }}) + +#define SPA_POD_INIT_Choice(type, ctype, child_type, n_vals, ...) \ + ((struct { struct spa_pod_choice choice; ctype vals[(n_vals)];}) \ + { { { (n_vals) * sizeof(ctype) + sizeof(struct spa_pod_choice_body), SPA_TYPE_Choice }, \ + { (type), 0, { sizeof(ctype), (child_type) } } }, { __VA_ARGS__ } }) + +static inline int +spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_frame *frame, + uint32_t type, uint32_t flags) +{ + const struct spa_pod_choice p = + { {sizeof(struct spa_pod_choice_body) - sizeof(struct spa_pod), SPA_TYPE_Choice}, + { type, flags, {0, 0}} }; + uint32_t offset = builder->state.offset; + int res = spa_pod_builder_raw(builder, &p, sizeof(p) - sizeof(struct spa_pod)); + spa_pod_builder_push(builder, frame, &p.pod, offset); + return res; +} + +#define SPA_POD_INIT_Struct(size) ((struct spa_pod_struct){ { (size), SPA_TYPE_Struct } }) + +static inline int +spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_frame *frame) +{ + const struct spa_pod_struct p = SPA_POD_INIT_Struct(0); + uint32_t offset = builder->state.offset; + int res = spa_pod_builder_raw(builder, &p, sizeof(p)); + spa_pod_builder_push(builder, frame, &p.pod, offset); + return res; +} + +#define SPA_POD_INIT_Object(size,type,id,...) ((struct spa_pod_object){ { (size), SPA_TYPE_Object }, { (type), (id) }, ##__VA_ARGS__ }) + +static inline int +spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_frame *frame, + uint32_t type, uint32_t id) +{ + const struct spa_pod_object p = + SPA_POD_INIT_Object(sizeof(struct spa_pod_object_body), type, id); + uint32_t offset = builder->state.offset; + int res = spa_pod_builder_raw(builder, &p, sizeof(p)); + spa_pod_builder_push(builder, frame, &p.pod, offset); + return res; +} + +#define SPA_POD_INIT_Prop(key,flags,size,type) \ + ((struct spa_pod_prop){ (key), (flags), { (size), (type) } }) + +static inline int +spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t flags) +{ + const struct { uint32_t key; uint32_t flags; } p = { key, flags }; + return spa_pod_builder_raw(builder, &p, sizeof(p)); +} + +#define SPA_POD_INIT_Sequence(size,unit) \ + ((struct spa_pod_sequence){ { (size), SPA_TYPE_Sequence}, {(unit), 0 } }) + +static inline int +spa_pod_builder_push_sequence(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t unit) +{ + const struct spa_pod_sequence p = + SPA_POD_INIT_Sequence(sizeof(struct spa_pod_sequence_body), unit); + uint32_t offset = builder->state.offset; + int res = spa_pod_builder_raw(builder, &p, sizeof(p)); + spa_pod_builder_push(builder, frame, &p.pod, offset); + return res; +} + +static inline int +spa_pod_builder_control(struct spa_pod_builder *builder, uint32_t offset, uint32_t type) +{ + const struct { uint32_t offset; uint32_t type; } p = { offset, type }; + return spa_pod_builder_raw(builder, &p, sizeof(p)); +} + +static inline uint32_t spa_choice_from_id(char id) +{ + switch (id) { + case 'r': + return SPA_CHOICE_Range; + case 's': + return SPA_CHOICE_Step; + case 'e': + return SPA_CHOICE_Enum; + case 'f': + return SPA_CHOICE_Flags; + case 'n': + default: + return SPA_CHOICE_None; + } +} + +#define SPA_POD_BUILDER_COLLECT(builder,type,args) \ +do { \ + switch (type) { \ + case 'b': \ + spa_pod_builder_bool(builder, !!va_arg(args, int)); \ + break; \ + case 'I': \ + spa_pod_builder_id(builder, va_arg(args, uint32_t)); \ + break; \ + case 'i': \ + spa_pod_builder_int(builder, va_arg(args, int)); \ + break; \ + case 'l': \ + spa_pod_builder_long(builder, va_arg(args, int64_t)); \ + break; \ + case 'f': \ + spa_pod_builder_float(builder, va_arg(args, double)); \ + break; \ + case 'd': \ + spa_pod_builder_double(builder, va_arg(args, double)); \ + break; \ + case 's': \ + { \ + char *strval = va_arg(args, char *); \ + if (strval != NULL) { \ + size_t len = strlen(strval); \ + spa_pod_builder_string_len(builder, strval, len); \ + } \ + else \ + spa_pod_builder_none(builder); \ + break; \ + } \ + case 'S': \ + { \ + char *strval = va_arg(args, char *); \ + size_t len = va_arg(args, int); \ + spa_pod_builder_string_len(builder, strval, len); \ + break; \ + } \ + case 'y': \ + { \ + void *ptr = va_arg(args, void *); \ + int len = va_arg(args, int); \ + spa_pod_builder_bytes(builder, ptr, len); \ + break; \ + } \ + case 'R': \ + { \ + struct spa_rectangle *rectval = \ + va_arg(args, struct spa_rectangle *); \ + spa_pod_builder_rectangle(builder, \ + rectval->width, rectval->height); \ + break; \ + } \ + case 'F': \ + { \ + struct spa_fraction *fracval = \ + va_arg(args, struct spa_fraction *); \ + spa_pod_builder_fraction(builder, fracval->num, fracval->denom);\ + break; \ + } \ + case 'a': \ + { \ + int child_size = va_arg(args, int); \ + int child_type = va_arg(args, int); \ + int n_elems = va_arg(args, int); \ + void *elems = va_arg(args, void *); \ + spa_pod_builder_array(builder, child_size, \ + child_type, n_elems, elems); \ + break; \ + } \ + case 'p': \ + { \ + int t = va_arg(args, uint32_t); \ + spa_pod_builder_pointer(builder, t, va_arg(args, void *)); \ + break; \ + } \ + case 'h': \ + spa_pod_builder_fd(builder, va_arg(args, int)); \ + break; \ + case 'P': \ + case 'O': \ + case 'T': \ + case 'V': \ + { \ + struct spa_pod *pod = va_arg(args, struct spa_pod *); \ + if (pod == NULL) \ + spa_pod_builder_none(builder); \ + else \ + spa_pod_builder_primitive(builder, pod); \ + break; \ + } \ + } \ +} while(false) + +static inline int +spa_pod_builder_addv(struct spa_pod_builder *builder, va_list args) +{ + int res = 0; + struct spa_pod_frame *frame = builder->state.frame; + uint32_t ftype = frame ? frame->pod.type : (uint32_t)SPA_TYPE_None; + + do { + const char *format; + int n_values = 1; + struct spa_pod_frame f; + bool choice; + + switch (ftype) { + case SPA_TYPE_Object: + { + uint32_t key = va_arg(args, uint32_t); + if (key == 0) + goto exit; + spa_pod_builder_prop(builder, key, 0); + break; + } + case SPA_TYPE_Sequence: + { + uint32_t offset = va_arg(args, uint32_t); + uint32_t type = va_arg(args, uint32_t); + if (type == 0) + goto exit; + spa_pod_builder_control(builder, offset, type); + SPA_FALLTHROUGH + } + default: + break; + } + if ((format = va_arg(args, const char *)) == NULL) + break; + + choice = *format == '?'; + if (choice) { + uint32_t type = spa_choice_from_id(*++format); + if (*format != '\0') + format++; + + spa_pod_builder_push_choice(builder, &f, type, 0); + + n_values = va_arg(args, int); + } + while (n_values-- > 0) + SPA_POD_BUILDER_COLLECT(builder, *format, args); + + if (choice) + spa_pod_builder_pop(builder, &f); + } while (true); + + exit: + return res; +} + +static inline int spa_pod_builder_add(struct spa_pod_builder *builder, ...) +{ + int res; + va_list args; + + va_start(args, builder); + res = spa_pod_builder_addv(builder, args); + va_end(args); + + return res; +} + +#define spa_pod_builder_add_object(b,type,id,...) \ +({ \ + struct spa_pod_builder *_b = (b); \ + struct spa_pod_frame _f; \ + spa_pod_builder_push_object(_b, &_f, type, id); \ + spa_pod_builder_add(_b, ##__VA_ARGS__, 0); \ + spa_pod_builder_pop(_b, &_f); \ +}) + +#define spa_pod_builder_add_struct(b,...) \ +({ \ + struct spa_pod_builder *_b = (b); \ + struct spa_pod_frame _f; \ + spa_pod_builder_push_struct(_b, &_f); \ + spa_pod_builder_add(_b, ##__VA_ARGS__, NULL); \ + spa_pod_builder_pop(_b, &_f); \ +}) + +#define spa_pod_builder_add_sequence(b,unit,...) \ +({ \ + struct spa_pod_builder *_b = (b); \ + struct spa_pod_frame _f; \ + spa_pod_builder_push_sequence(_b, &_f, unit); \ + spa_pod_builder_add(_b, ##__VA_ARGS__, 0, 0); \ + spa_pod_builder_pop(_b, &_f); \ +}) + +/** Copy a pod structure */ +static inline struct spa_pod * +spa_pod_copy(const struct spa_pod *pod) +{ + size_t size; + struct spa_pod *c; + + size = SPA_POD_SIZE(pod); + if ((c = (struct spa_pod *) malloc(size)) == NULL) + return NULL; + return (struct spa_pod *) memcpy(c, pod, size); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_POD_BUILDER_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/pod/command.h b/thirdparty/linuxbsd_headers/pipewire/spa/pod/command.h new file mode 100644 index 000000000000..330f56edc149 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/pod/command.h @@ -0,0 +1,49 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_COMMAND_H +#define SPA_COMMAND_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \addtogroup spa_pod + * \{ + */ + +struct spa_command_body { + struct spa_pod_object_body body; +}; + +struct spa_command { + struct spa_pod pod; + struct spa_command_body body; +}; + +#define SPA_COMMAND_TYPE(cmd) ((cmd)->body.body.type) +#define SPA_COMMAND_ID(cmd,type) (SPA_COMMAND_TYPE(cmd) == (type) ? \ + (cmd)->body.body.id : SPA_ID_INVALID) + +#define SPA_COMMAND_INIT_FULL(t,size,type,id,...) ((t) \ + { { (size), SPA_TYPE_Object }, \ + { { (type), (id) }, ##__VA_ARGS__ } }) + +#define SPA_COMMAND_INIT(type,id) \ + SPA_COMMAND_INIT_FULL(struct spa_command, \ + sizeof(struct spa_command_body), type, id) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_COMMAND_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/pod/event.h b/thirdparty/linuxbsd_headers/pipewire/spa/pod/event.h new file mode 100644 index 000000000000..b221bc73d5fa --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/pod/event.h @@ -0,0 +1,48 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_EVENT_H +#define SPA_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \addtogroup spa_pod + * \{ + */ + +struct spa_event_body { + struct spa_pod_object_body body; +}; + +struct spa_event { + struct spa_pod pod; + struct spa_event_body body; +}; + +#define SPA_EVENT_TYPE(ev) ((ev)->body.body.type) +#define SPA_EVENT_ID(ev,type) (SPA_EVENT_TYPE(ev) == (type) ? \ + (ev)->body.body.id : SPA_ID_INVALID) + +#define SPA_EVENT_INIT_FULL(t,size,type,id,...) ((t) \ + { { (size), SPA_TYPE_OBJECT }, \ + { { (type), (id) }, ##__VA_ARGS__ } }) \ + +#define SPA_EVENT_INIT(type,id) \ + SPA_EVENT_INIT_FULL(struct spa_event, \ + sizeof(struct spa_event_body), type, id) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_EVENT_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/pod/iter.h b/thirdparty/linuxbsd_headers/pipewire/spa/pod/iter.h new file mode 100644 index 000000000000..05abfc1c970d --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/pod/iter.h @@ -0,0 +1,455 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_POD_ITER_H +#define SPA_POD_ITER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +/** + * \addtogroup spa_pod + * \{ + */ + +struct spa_pod_frame { + struct spa_pod pod; + struct spa_pod_frame *parent; + uint32_t offset; + uint32_t flags; +}; + +static inline bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter) +{ + return SPA_POD_BODY(iter) <= SPA_PTROFF(pod, size, void) && + SPA_PTROFF(iter, SPA_POD_SIZE(iter), void) <= SPA_PTROFF(pod, size, void); +} + +static inline void *spa_pod_next(const void *iter) +{ + return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_SIZE(iter), 8), void); +} + +static inline struct spa_pod_prop *spa_pod_prop_first(const struct spa_pod_object_body *body) +{ + return SPA_PTROFF(body, sizeof(struct spa_pod_object_body), struct spa_pod_prop); +} + +static inline bool spa_pod_prop_is_inside(const struct spa_pod_object_body *body, + uint32_t size, const struct spa_pod_prop *iter) +{ + return SPA_POD_CONTENTS(struct spa_pod_prop, iter) <= SPA_PTROFF(body, size, void) && + SPA_PTROFF(iter, SPA_POD_PROP_SIZE(iter), void) <= SPA_PTROFF(body, size, void); +} + +static inline struct spa_pod_prop *spa_pod_prop_next(const struct spa_pod_prop *iter) +{ + return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_PROP_SIZE(iter), 8), struct spa_pod_prop); +} + +static inline struct spa_pod_control *spa_pod_control_first(const struct spa_pod_sequence_body *body) +{ + return SPA_PTROFF(body, sizeof(struct spa_pod_sequence_body), struct spa_pod_control); +} + +static inline bool spa_pod_control_is_inside(const struct spa_pod_sequence_body *body, + uint32_t size, const struct spa_pod_control *iter) +{ + return SPA_POD_CONTENTS(struct spa_pod_control, iter) <= SPA_PTROFF(body, size, void) && + SPA_PTROFF(iter, SPA_POD_CONTROL_SIZE(iter), void) <= SPA_PTROFF(body, size, void); +} + +static inline struct spa_pod_control *spa_pod_control_next(const struct spa_pod_control *iter) +{ + return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_CONTROL_SIZE(iter), 8), struct spa_pod_control); +} + +#define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \ + for ((iter) = (__typeof__(iter))SPA_PTROFF((body), sizeof(struct spa_pod_array_body), void); \ + (iter) < (__typeof__(iter))SPA_PTROFF((body), (_size), void); \ + (iter) = (__typeof__(iter))SPA_PTROFF((iter), (body)->child.size, void)) + +#define SPA_POD_ARRAY_FOREACH(obj, iter) \ + SPA_POD_ARRAY_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter) + +#define SPA_POD_CHOICE_BODY_FOREACH(body, _size, iter) \ + for ((iter) = (__typeof__(iter))SPA_PTROFF((body), sizeof(struct spa_pod_choice_body), void); \ + (iter) < (__typeof__(iter))SPA_PTROFF((body), (_size), void); \ + (iter) = (__typeof__(iter))SPA_PTROFF((iter), (body)->child.size, void)) + +#define SPA_POD_CHOICE_FOREACH(obj, iter) \ + SPA_POD_CHOICE_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter) + +#define SPA_POD_FOREACH(pod, size, iter) \ + for ((iter) = (pod); \ + spa_pod_is_inside(pod, size, iter); \ + (iter) = (__typeof__(iter))spa_pod_next(iter)) + +#define SPA_POD_STRUCT_FOREACH(obj, iter) \ + SPA_POD_FOREACH(SPA_POD_BODY(obj), SPA_POD_BODY_SIZE(obj), iter) + +#define SPA_POD_OBJECT_BODY_FOREACH(body, size, iter) \ + for ((iter) = spa_pod_prop_first(body); \ + spa_pod_prop_is_inside(body, size, iter); \ + (iter) = spa_pod_prop_next(iter)) + +#define SPA_POD_OBJECT_FOREACH(obj, iter) \ + SPA_POD_OBJECT_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter) + +#define SPA_POD_SEQUENCE_BODY_FOREACH(body, size, iter) \ + for ((iter) = spa_pod_control_first(body); \ + spa_pod_control_is_inside(body, size, iter); \ + (iter) = spa_pod_control_next(iter)) + +#define SPA_POD_SEQUENCE_FOREACH(seq, iter) \ + SPA_POD_SEQUENCE_BODY_FOREACH(&(seq)->body, SPA_POD_BODY_SIZE(seq), iter) + + +static inline void *spa_pod_from_data(void *data, size_t maxsize, off_t offset, size_t size) +{ + void *pod; + if (size < sizeof(struct spa_pod) || offset + size > maxsize) + return NULL; + pod = SPA_PTROFF(data, offset, void); + if (SPA_POD_SIZE(pod) > size) + return NULL; + return pod; +} + +static inline int spa_pod_is_none(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_None); +} + +static inline int spa_pod_is_bool(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Bool && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t)); +} + +static inline int spa_pod_get_bool(const struct spa_pod *pod, bool *value) +{ + if (!spa_pod_is_bool(pod)) + return -EINVAL; + *value = !!SPA_POD_VALUE(struct spa_pod_bool, pod); + return 0; +} + +static inline int spa_pod_is_id(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Id && SPA_POD_BODY_SIZE(pod) >= sizeof(uint32_t)); +} + +static inline int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) +{ + if (!spa_pod_is_id(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_id, pod); + return 0; +} + +static inline int spa_pod_is_int(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Int && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t)); +} + +static inline int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) +{ + if (!spa_pod_is_int(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_int, pod); + return 0; +} + +static inline int spa_pod_is_long(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Long && SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t)); +} + +static inline int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) +{ + if (!spa_pod_is_long(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_long, pod); + return 0; +} + +static inline int spa_pod_is_float(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Float && SPA_POD_BODY_SIZE(pod) >= sizeof(float)); +} + +static inline int spa_pod_get_float(const struct spa_pod *pod, float *value) +{ + if (!spa_pod_is_float(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_float, pod); + return 0; +} + +static inline int spa_pod_is_double(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Double && SPA_POD_BODY_SIZE(pod) >= sizeof(double)); +} + +static inline int spa_pod_get_double(const struct spa_pod *pod, double *value) +{ + if (!spa_pod_is_double(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_double, pod); + return 0; +} + +static inline int spa_pod_is_string(const struct spa_pod *pod) +{ + const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod); + return (SPA_POD_TYPE(pod) == SPA_TYPE_String && + SPA_POD_BODY_SIZE(pod) > 0 && + s[SPA_POD_BODY_SIZE(pod)-1] == '\0'); +} + +static inline int spa_pod_get_string(const struct spa_pod *pod, const char **value) +{ + if (!spa_pod_is_string(pod)) + return -EINVAL; + *value = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod); + return 0; +} + +static inline int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest) +{ + const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod); + if (!spa_pod_is_string(pod) || maxlen < 1) + return -EINVAL; + strncpy(dest, s, maxlen-1); + dest[maxlen-1]= '\0'; + return 0; +} + +static inline int spa_pod_is_bytes(const struct spa_pod *pod) +{ + return SPA_POD_TYPE(pod) == SPA_TYPE_Bytes; +} + +static inline int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len) +{ + if (!spa_pod_is_bytes(pod)) + return -EINVAL; + *value = (const void *)SPA_POD_CONTENTS(struct spa_pod_bytes, pod); + *len = SPA_POD_BODY_SIZE(pod); + return 0; +} + +static inline int spa_pod_is_pointer(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Pointer && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_pointer_body)); +} + +static inline int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value) +{ + if (!spa_pod_is_pointer(pod)) + return -EINVAL; + *type = ((struct spa_pod_pointer*)pod)->body.type; + *value = ((struct spa_pod_pointer*)pod)->body.value; + return 0; +} + +static inline int spa_pod_is_fd(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Fd && + SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t)); +} + +static inline int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) +{ + if (!spa_pod_is_fd(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_fd, pod); + return 0; +} + +static inline int spa_pod_is_rectangle(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Rectangle && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_rectangle)); +} + +static inline int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value) +{ + if (!spa_pod_is_rectangle(pod)) + return -EINVAL; + *value = SPA_POD_VALUE(struct spa_pod_rectangle, pod); + return 0; +} + +static inline int spa_pod_is_fraction(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Fraction && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_fraction)); +} + +static inline int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value) +{ + spa_return_val_if_fail(spa_pod_is_fraction(pod), -EINVAL); + *value = SPA_POD_VALUE(struct spa_pod_fraction, pod); + return 0; +} + +static inline int spa_pod_is_bitmap(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Bitmap && + SPA_POD_BODY_SIZE(pod) >= sizeof(uint8_t)); +} + +static inline int spa_pod_is_array(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Array && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_array_body)); +} + +static inline void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values) +{ + spa_return_val_if_fail(spa_pod_is_array(pod), NULL); + *n_values = SPA_POD_ARRAY_N_VALUES(pod); + return SPA_POD_ARRAY_VALUES(pod); +} + +static inline uint32_t spa_pod_copy_array(const struct spa_pod *pod, uint32_t type, + void *values, uint32_t max_values) +{ + uint32_t n_values; + void *v = spa_pod_get_array(pod, &n_values); + if (v == NULL || max_values == 0 || SPA_POD_ARRAY_VALUE_TYPE(pod) != type) + return 0; + n_values = SPA_MIN(n_values, max_values); + memcpy(values, v, SPA_POD_ARRAY_VALUE_SIZE(pod) * n_values); + return n_values; +} + +static inline int spa_pod_is_choice(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Choice && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_choice_body)); +} + +static inline struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice) +{ + if (pod->type == SPA_TYPE_Choice) { + *n_vals = SPA_POD_CHOICE_N_VALUES(pod); + if ((*choice = SPA_POD_CHOICE_TYPE(pod)) == SPA_CHOICE_None) + *n_vals = SPA_MIN(1u, SPA_POD_CHOICE_N_VALUES(pod)); + return (struct spa_pod*)SPA_POD_CHOICE_CHILD(pod); + } else { + *n_vals = 1; + *choice = SPA_CHOICE_None; + return (struct spa_pod*)pod; + } +} + +static inline int spa_pod_is_struct(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Struct); +} + +static inline int spa_pod_is_object(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Object && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_object_body)); +} + +static inline bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type) +{ + return (pod && spa_pod_is_object(pod) && SPA_POD_OBJECT_TYPE(pod) == type); +} + +static inline bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id) +{ + return (pod && spa_pod_is_object(pod) && SPA_POD_OBJECT_ID(pod) == id); +} + +static inline int spa_pod_is_sequence(const struct spa_pod *pod) +{ + return (SPA_POD_TYPE(pod) == SPA_TYPE_Sequence && + SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_sequence_body)); +} + +static inline const struct spa_pod_prop *spa_pod_object_find_prop(const struct spa_pod_object *pod, + const struct spa_pod_prop *start, uint32_t key) +{ + const struct spa_pod_prop *first, *res; + + first = spa_pod_prop_first(&pod->body); + start = start ? spa_pod_prop_next(start) : first; + + for (res = start; spa_pod_prop_is_inside(&pod->body, pod->pod.size, res); + res = spa_pod_prop_next(res)) { + if (res->key == key) + return res; + } + for (res = first; res != start; res = spa_pod_prop_next(res)) { + if (res->key == key) + return res; + } + return NULL; +} + +static inline const struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod *pod, + const struct spa_pod_prop *start, uint32_t key) +{ + if (!spa_pod_is_object(pod)) + return NULL; + return spa_pod_object_find_prop((const struct spa_pod_object *)pod, start, key); +} + +static inline int spa_pod_object_fixate(struct spa_pod_object *pod) +{ + struct spa_pod_prop *res; + SPA_POD_OBJECT_FOREACH(pod, res) { + if (res->value.type == SPA_TYPE_Choice && + !SPA_FLAG_IS_SET(res->flags, SPA_POD_PROP_FLAG_DONT_FIXATE)) + ((struct spa_pod_choice*)&res->value)->body.type = SPA_CHOICE_None; + } + return 0; +} + +static inline int spa_pod_fixate(struct spa_pod *pod) +{ + if (!spa_pod_is_object(pod)) + return -EINVAL; + return spa_pod_object_fixate((struct spa_pod_object *)pod); +} + +static inline int spa_pod_object_is_fixated(const struct spa_pod_object *pod) +{ + struct spa_pod_prop *res; + SPA_POD_OBJECT_FOREACH(pod, res) { + if (res->value.type == SPA_TYPE_Choice && + ((struct spa_pod_choice*)&res->value)->body.type != SPA_CHOICE_None) + return 0; + } + return 1; +} + +static inline int spa_pod_is_fixated(const struct spa_pod *pod) +{ + if (!spa_pod_is_object(pod)) + return -EINVAL; + return spa_pod_object_is_fixated((const struct spa_pod_object *)pod); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_POD_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/pod/pod.h b/thirdparty/linuxbsd_headers/pipewire/spa/pod/pod.h new file mode 100644 index 000000000000..f7627f48ea64 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/pod/pod.h @@ -0,0 +1,226 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_POD_H +#define SPA_POD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \addtogroup spa_pod + * \{ + */ + +#define SPA_POD_BODY_SIZE(pod) (((struct spa_pod*)(pod))->size) +#define SPA_POD_TYPE(pod) (((struct spa_pod*)(pod))->type) +#define SPA_POD_SIZE(pod) ((uint64_t)sizeof(struct spa_pod) + SPA_POD_BODY_SIZE(pod)) +#define SPA_POD_CONTENTS_SIZE(type,pod) (SPA_POD_SIZE(pod)-sizeof(type)) + +#define SPA_POD_CONTENTS(type,pod) SPA_PTROFF((pod),sizeof(type),void) +#define SPA_POD_CONTENTS_CONST(type,pod) SPA_PTROFF((pod),sizeof(type),const void) +#define SPA_POD_BODY(pod) SPA_PTROFF((pod),sizeof(struct spa_pod),void) +#define SPA_POD_BODY_CONST(pod) SPA_PTROFF((pod),sizeof(struct spa_pod),const void) + +struct spa_pod { + uint32_t size; /* size of the body */ + uint32_t type; /* a basic id of enum spa_type */ +}; + +#define SPA_POD_VALUE(type,pod) (((type*)(pod))->value) + +struct spa_pod_bool { + struct spa_pod pod; + int32_t value; + int32_t _padding; +}; + +struct spa_pod_id { + struct spa_pod pod; + uint32_t value; + int32_t _padding; +}; + +struct spa_pod_int { + struct spa_pod pod; + int32_t value; + int32_t _padding; +}; + +struct spa_pod_long { + struct spa_pod pod; + int64_t value; +}; + +struct spa_pod_float { + struct spa_pod pod; + float value; + int32_t _padding; +}; + +struct spa_pod_double { + struct spa_pod pod; + double value; +}; + +struct spa_pod_string { + struct spa_pod pod; + /* value here */ +}; + +struct spa_pod_bytes { + struct spa_pod pod; + /* value here */ +}; + +struct spa_pod_rectangle { + struct spa_pod pod; + struct spa_rectangle value; +}; + +struct spa_pod_fraction { + struct spa_pod pod; + struct spa_fraction value; +}; + +struct spa_pod_bitmap { + struct spa_pod pod; + /* array of uint8_t follows with the bitmap */ +}; + +#define SPA_POD_ARRAY_CHILD(arr) (&((struct spa_pod_array*)(arr))->body.child) +#define SPA_POD_ARRAY_VALUE_TYPE(arr) (SPA_POD_TYPE(SPA_POD_ARRAY_CHILD(arr))) +#define SPA_POD_ARRAY_VALUE_SIZE(arr) (SPA_POD_BODY_SIZE(SPA_POD_ARRAY_CHILD(arr))) +#define SPA_POD_ARRAY_N_VALUES(arr) (SPA_POD_ARRAY_VALUE_SIZE(arr) ? ((SPA_POD_BODY_SIZE(arr) - sizeof(struct spa_pod_array_body)) / SPA_POD_ARRAY_VALUE_SIZE(arr)) : 0) +#define SPA_POD_ARRAY_VALUES(arr) SPA_POD_CONTENTS(struct spa_pod_array, arr) + +struct spa_pod_array_body { + struct spa_pod child; + /* array with elements of child.size follows */ +}; + +struct spa_pod_array { + struct spa_pod pod; + struct spa_pod_array_body body; +}; + +#define SPA_POD_CHOICE_CHILD(choice) (&((struct spa_pod_choice*)(choice))->body.child) +#define SPA_POD_CHOICE_TYPE(choice) (((struct spa_pod_choice*)(choice))->body.type) +#define SPA_POD_CHOICE_FLAGS(choice) (((struct spa_pod_choice*)(choice))->body.flags) +#define SPA_POD_CHOICE_VALUE_TYPE(choice) (SPA_POD_TYPE(SPA_POD_CHOICE_CHILD(choice))) +#define SPA_POD_CHOICE_VALUE_SIZE(choice) (SPA_POD_BODY_SIZE(SPA_POD_CHOICE_CHILD(choice))) +#define SPA_POD_CHOICE_N_VALUES(choice) (SPA_POD_CHOICE_VALUE_SIZE(choice) ? ((SPA_POD_BODY_SIZE(choice) - sizeof(struct spa_pod_choice_body)) / SPA_POD_CHOICE_VALUE_SIZE(choice)) : 0) +#define SPA_POD_CHOICE_VALUES(choice) (SPA_POD_CONTENTS(struct spa_pod_choice, choice)) + +enum spa_choice_type { + SPA_CHOICE_None, /**< no choice, first value is current */ + SPA_CHOICE_Range, /**< range: default, min, max */ + SPA_CHOICE_Step, /**< range with step: default, min, max, step */ + SPA_CHOICE_Enum, /**< list: default, alternative,... */ + SPA_CHOICE_Flags, /**< flags: default, possible flags,... */ +}; + +struct spa_pod_choice_body { + uint32_t type; /**< type of choice, one of enum spa_choice_type */ + uint32_t flags; /**< extra flags */ + struct spa_pod child; + /* array with elements of child.size follows. Note that there might be more + * elements than required by \a type, which should be ignored. */ +}; + +struct spa_pod_choice { + struct spa_pod pod; + struct spa_pod_choice_body body; +}; + +struct spa_pod_struct { + struct spa_pod pod; + /* one or more spa_pod follow */ +}; + +#define SPA_POD_OBJECT_TYPE(obj) (((struct spa_pod_object*)(obj))->body.type) +#define SPA_POD_OBJECT_ID(obj) (((struct spa_pod_object*)(obj))->body.id) + +struct spa_pod_object_body { + uint32_t type; /**< one of enum spa_type */ + uint32_t id; /**< id of the object, depends on the object type */ + /* contents follow, series of spa_pod_prop */ +}; + +struct spa_pod_object { + struct spa_pod pod; + struct spa_pod_object_body body; +}; + +struct spa_pod_pointer_body { + uint32_t type; /**< pointer id, one of enum spa_type */ + uint32_t _padding; + const void *value; +}; + +struct spa_pod_pointer { + struct spa_pod pod; + struct spa_pod_pointer_body body; +}; + +struct spa_pod_fd { + struct spa_pod pod; + int64_t value; +}; + +#define SPA_POD_PROP_SIZE(prop) (sizeof(struct spa_pod_prop) + (prop)->value.size) + +/* props can be inside an object */ +struct spa_pod_prop { + uint32_t key; /**< key of property, list of valid keys depends on the + * object type */ +#define SPA_POD_PROP_FLAG_READONLY (1u<<0) /**< is read-only */ +#define SPA_POD_PROP_FLAG_HARDWARE (1u<<1) /**< some sort of hardware parameter */ +#define SPA_POD_PROP_FLAG_HINT_DICT (1u<<2) /**< contains a dictionary struct as + * (Struct( + * Int : n_items, + * (String : key, + * String : value)*)) */ +#define SPA_POD_PROP_FLAG_MANDATORY (1u<<3) /**< is mandatory */ +#define SPA_POD_PROP_FLAG_DONT_FIXATE (1u<<4) /**< choices need no fixation */ + uint32_t flags; /**< flags for property */ + struct spa_pod value; + /* value follows */ +}; + +#define SPA_POD_CONTROL_SIZE(ev) (sizeof(struct spa_pod_control) + (ev)->value.size) + +/* controls can be inside a sequence and mark timed values */ +struct spa_pod_control { + uint32_t offset; /**< media offset */ + uint32_t type; /**< type of control, enum spa_control_type */ + struct spa_pod value; /**< control value, depends on type */ + /* value contents follow */ +}; + +struct spa_pod_sequence_body { + uint32_t unit; + uint32_t pad; + /* series of struct spa_pod_control follows */ +}; + +/** a sequence of timed controls */ +struct spa_pod_sequence { + struct spa_pod pod; + struct spa_pod_sequence_body body; +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_POD_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/pod/vararg.h b/thirdparty/linuxbsd_headers/pipewire/spa/pod/vararg.h new file mode 100644 index 000000000000..a30e11479bc1 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/pod/vararg.h @@ -0,0 +1,93 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_POD_VARARG_H +#define SPA_POD_VARARG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +/** + * \addtogroup spa_pod + * \{ + */ + +#define SPA_POD_Prop(key,...) \ + key, ##__VA_ARGS__ + +#define SPA_POD_Control(offset,type,...) \ + offset, type, ##__VA_ARGS__ + +#define SPA_CHOICE_RANGE(def,min,max) 3,(def),(min),(max) +#define SPA_CHOICE_STEP(def,min,max,step) 4,(def),(min),(max),(step) +#define SPA_CHOICE_ENUM(n_vals,...) (n_vals),##__VA_ARGS__ +#define SPA_CHOICE_FLAGS(flags) 1, (flags) +#define SPA_CHOICE_BOOL(def) 3,(def),(def),!(def) + +#define SPA_POD_Bool(val) "b", val +#define SPA_POD_CHOICE_Bool(def) "?eb", SPA_CHOICE_BOOL(def) + +#define SPA_POD_Id(val) "I", val +#define SPA_POD_CHOICE_ENUM_Id(n_vals,...) "?eI", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) + +#define SPA_POD_Int(val) "i", val +#define SPA_POD_CHOICE_ENUM_Int(n_vals,...) "?ei", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) +#define SPA_POD_CHOICE_RANGE_Int(def,min,max) "?ri", SPA_CHOICE_RANGE(def, min, max) +#define SPA_POD_CHOICE_STEP_Int(def,min,max,step) "?si", SPA_CHOICE_STEP(def, min, max, step) +#define SPA_POD_CHOICE_FLAGS_Int(flags) "?fi", SPA_CHOICE_FLAGS(flags) + +#define SPA_POD_Long(val) "l", val +#define SPA_POD_CHOICE_ENUM_Long(n_vals,...) "?el", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) +#define SPA_POD_CHOICE_RANGE_Long(def,min,max) "?rl", SPA_CHOICE_RANGE(def, min, max) +#define SPA_POD_CHOICE_STEP_Long(def,min,max,step) "?sl", SPA_CHOICE_STEP(def, min, max, step) +#define SPA_POD_CHOICE_FLAGS_Long(flags) "?fl", SPA_CHOICE_FLAGS(flags) + +#define SPA_POD_Float(val) "f", val +#define SPA_POD_CHOICE_ENUM_Float(n_vals,...) "?ef", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) +#define SPA_POD_CHOICE_RANGE_Float(def,min,max) "?rf", SPA_CHOICE_RANGE(def, min, max) +#define SPA_POD_CHOICE_STEP_Float(def,min,max,step) "?sf", SPA_CHOICE_STEP(def, min, max, step) + +#define SPA_POD_Double(val) "d", val +#define SPA_POD_CHOICE_ENUM_Double(n_vals,...) "?ed", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) +#define SPA_POD_CHOICE_RANGE_Double(def,min,max) "?rd", SPA_CHOICE_RANGE(def, min, max) +#define SPA_POD_CHOICE_STEP_Double(def,min,max,step) "?sd", SPA_CHOICE_STEP(def, min, max, step) + +#define SPA_POD_String(val) "s",val +#define SPA_POD_Stringn(val,len) "S",val,len + +#define SPA_POD_Bytes(val,len) "y",val,len + +#define SPA_POD_Rectangle(val) "R",val +#define SPA_POD_CHOICE_ENUM_Rectangle(n_vals,...) "?eR", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) +#define SPA_POD_CHOICE_RANGE_Rectangle(def,min,max) "?rR", SPA_CHOICE_RANGE((def),(min),(max)) +#define SPA_POD_CHOICE_STEP_Rectangle(def,min,max,step) "?sR", SPA_CHOICE_STEP((def),(min),(max),(step)) + +#define SPA_POD_Fraction(val) "F",val +#define SPA_POD_CHOICE_ENUM_Fraction(n_vals,...) "?eF", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) +#define SPA_POD_CHOICE_RANGE_Fraction(def,min,max) "?rF", SPA_CHOICE_RANGE((def),(min),(max)) +#define SPA_POD_CHOICE_STEP_Fraction(def,min,max,step) "?sF", SPA_CHOICE_STEP(def, min, max, step) + +#define SPA_POD_Array(csize,ctype,n_vals,vals) "a", csize,ctype,n_vals,vals +#define SPA_POD_Pointer(type,val) "p", type,val +#define SPA_POD_Fd(val) "h", val +#define SPA_POD_None() "P", NULL +#define SPA_POD_Pod(val) "P", val +#define SPA_POD_PodObject(val) "O", val +#define SPA_POD_PodStruct(val) "T", val +#define SPA_POD_PodChoice(val) "V", val + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_POD_VARARG_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/support/log.h b/thirdparty/linuxbsd_headers/pipewire/spa/support/log.h new file mode 100644 index 000000000000..450ff2624a8c --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/support/log.h @@ -0,0 +1,304 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_LOG_H +#define SPA_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include + +/** \defgroup spa_log Log + * Logging interface + */ + +/** + * \addtogroup spa_log + * \{ + */ + +/** The default log topic. Redefine this in your code to + * allow for the spa_log_* macros to work correctly, e.g: + * + * \code{.c} + * struct spa_log_topic *mylogger; + * #undef SPA_LOG_TOPIC_DEFAULT + * #define SPA_LOG_TOPIC_DEFAULT mylogger + * \endcode + */ +#define SPA_LOG_TOPIC_DEFAULT NULL + +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" + + +struct spa_log { + /** the version of this log. This can be used to expand this + * structure in the future */ +#define SPA_VERSION_LOG 0 + struct spa_interface iface; + /** + * Logging level, everything above this level is not logged + */ + enum spa_log_level level; +}; + +/** + * \struct spa_log_topic + * + * Identifier for a topic. Topics are string-based filters that logically + * group messages together. An implementation may decide to filter different + * topics on different levels, for example the "protocol" topic may require + * debug level TRACE while the "core" topic defaults to debug level INFO. + * + * spa_log_topics require a spa_log_methods version of 1 or higher. + */ +struct spa_log_topic { +#define SPA_VERSION_LOG_TOPIC 0 + /** the version of this topic. This can be used to expand this + * structure in the future */ + uint32_t version; + /** The string identifier for the topic */ + const char *topic; + /** Logging level set for this topic */ + enum spa_log_level level; + /** False if this topic follows the \ref spa_log level */ + bool has_custom_level; +}; + +struct spa_log_methods { +#define SPA_VERSION_LOG_METHODS 1 + uint32_t version; + /** + * Log a message with the given log level. + * + * \note If compiled with this header, this function is only called + * for implementations of version 0. For versions 1 and above, see + * logt() instead. + * + * \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. + * + * \note If compiled with this header, this function is only called + * for implementations of version 0. For versions 1 and above, see + * logtv() instead. + * + * \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); + /** + * Log a message with the given log level for the given topic. + * + * \note Callers that do not use topic-based logging (version 0), the \a + * topic is NULL + * + * \param log a spa_log + * \param level a spa_log_level + * \param topic the topic for this message, may be NULL + * \param file the file name + * \param line the line number + * \param func the function name + * \param fmt printf style format + * \param ... format arguments + * + * \since 1 + */ + void (*logt) (void *object, + enum spa_log_level level, + const struct spa_log_topic *topic, + const char *file, + int line, + const char *func, + const char *fmt, ...) SPA_PRINTF_FUNC(7, 8); + + /** + * Log a message with the given log level for the given topic. + * + * \note For callers that do not use topic-based logging (version 0), + * the \a topic is NULL + * + * \param log a spa_log + * \param level a spa_log_level + * \param topic the topic for this message, may be NULL + * \param file the file name + * \param line the line number + * \param func the function name + * \param fmt printf style format + * \param args format arguments + * + * \since 1 + */ + void (*logtv) (void *object, + enum spa_log_level level, + const struct spa_log_topic *topic, + const char *file, + int line, + const char *func, + const char *fmt, + va_list args) SPA_PRINTF_FUNC(7, 0); + + /** + * Initializes a \ref spa_log_topic to the correct logging level. + * + * \since 1 + */ + void (*topic_init) (void *object, struct spa_log_topic *topic); +}; + + +#define SPA_LOG_TOPIC(v, t) \ + (struct spa_log_topic){ .version = (v), .topic = (t)} + +static inline void spa_log_topic_init(struct spa_log *log, struct spa_log_topic *topic) +{ + if (SPA_UNLIKELY(!log)) + return; + + spa_interface_call(&log->iface, struct spa_log_methods, topic_init, 1, topic); +} + +static inline bool spa_log_level_topic_enabled(const struct spa_log *log, + const struct spa_log_topic *topic, + enum spa_log_level level) +{ + enum spa_log_level max_level; + + if (SPA_UNLIKELY(!log)) + return false; + + if (topic && topic->has_custom_level) + max_level = topic->level; + else + max_level = log->level; + + return level <= max_level; +} + +/* Transparently calls to version 0 log if v1 is not supported */ +#define spa_log_logt(l,lev,topic,...) \ +({ \ + struct spa_log *_l = l; \ + if (SPA_UNLIKELY(spa_log_level_topic_enabled(_l, topic, lev))) { \ + struct spa_interface *_if = &_l->iface; \ + if (!spa_interface_call(_if, \ + struct spa_log_methods, logt, 1, \ + lev, topic, \ + __VA_ARGS__)) \ + spa_interface_call(_if, \ + struct spa_log_methods, log, 0, \ + lev, __VA_ARGS__); \ + } \ +}) + +/* Transparently calls to version 0 logv if v1 is not supported */ +#define spa_log_logtv(l,lev,topic,...) \ +({ \ + struct spa_log *_l = l; \ + if (SPA_UNLIKELY(spa_log_level_topic_enabled(_l, topic, lev))) { \ + struct spa_interface *_if = &_l->iface; \ + if (!spa_interface_call(_if, \ + struct spa_log_methods, logtv, 1, \ + lev, topic, \ + __VA_ARGS__)) \ + spa_interface_call(_if, \ + struct spa_log_methods, logv, 0, \ + lev, __VA_ARGS__); \ + } \ +}) + +#define spa_logt_lev(l,lev,t,...) \ + spa_log_logt(l,lev,t,__FILE__,__LINE__,__func__,__VA_ARGS__) + +#define spa_log_lev(l,lev,...) \ + spa_logt_lev(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__) + +#define spa_log_log(l,lev,...) \ + spa_log_logt(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__) + +#define spa_log_logv(l,lev,...) \ + spa_log_logtv(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__) + +#define spa_log_error(l,...) spa_log_lev(l,SPA_LOG_LEVEL_ERROR,__VA_ARGS__) +#define spa_log_warn(l,...) spa_log_lev(l,SPA_LOG_LEVEL_WARN,__VA_ARGS__) +#define spa_log_info(l,...) spa_log_lev(l,SPA_LOG_LEVEL_INFO,__VA_ARGS__) +#define spa_log_debug(l,...) spa_log_lev(l,SPA_LOG_LEVEL_DEBUG,__VA_ARGS__) +#define spa_log_trace(l,...) spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__) + +#define spa_logt_error(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_ERROR,t,__VA_ARGS__) +#define spa_logt_warn(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_WARN,t,__VA_ARGS__) +#define spa_logt_info(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_INFO,t,__VA_ARGS__) +#define spa_logt_debug(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_DEBUG,t,__VA_ARGS__) +#define spa_logt_trace(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_TRACE,t,__VA_ARGS__) + +#ifndef FASTPATH +#define spa_log_trace_fp(l,...) spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__) +#else +#define spa_log_trace_fp(l,...) +#endif + + +/** \fn spa_log_error */ + +/** 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, set to "force" to enable + * colors even when not logging to a terminal */ +#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 */ +#define SPA_KEY_LOG_PATTERNS "log.patterns" /**< Spa:String:JSON array of [ {"pattern" : level}, ... ] */ + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* SPA_LOG_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/support/loop.h b/thirdparty/linuxbsd_headers/pipewire/spa/support/loop.h new file mode 100644 index 000000000000..01b9abc5b2ef --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/support/loop.h @@ -0,0 +1,330 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_LOOP_H +#define SPA_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** \defgroup spa_loop Loop + * Event loop interface + */ + +/** + * \addtogroup spa_loop + * \{ + */ + +#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 1 +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; + /* private data for the loop implementer */ + void *priv; +}; + +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_fast(&_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_fast(&_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 1 + 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); + + /** Check context of the loop + * \param ctrl the control + * + * This function will check if the current thread is currently the + * one that did the enter call. Since version 1:1. + * + * returns 1 on success, 0 or negative errno value on error. + */ + int (*check) (void *object); +}; + +#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_method_fast_r(o,method,version,...) \ +({ \ + int _res; \ + struct spa_loop_control *_o = o; \ + spa_interface_call_fast_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__) +#define spa_loop_control_check(l) spa_loop_control_method_r(l,check,1) + +#define spa_loop_control_iterate_fast(l,...) spa_loop_control_method_fast_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/thirdparty/linuxbsd_headers/pipewire/spa/support/plugin.h b/thirdparty/linuxbsd_headers/pipewire/spa/support/plugin.h new file mode 100644 index 000000000000..e2e6d469c077 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/support/plugin.h @@ -0,0 +1,209 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PLUGIN_H +#define SPA_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup spa_handle Plugin Handle + * SPA plugin handle and factory interfaces + */ + +/** + * \addtogroup spa_handle + * \{ + */ + +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/thirdparty/linuxbsd_headers/pipewire/spa/support/system.h b/thirdparty/linuxbsd_headers/pipewire/spa/support/system.h new file mode 100644 index 000000000000..9ea41bce8436 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/support/system.h @@ -0,0 +1,144 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_SYSTEM_H +#define SPA_SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct itimerspec; + +#include +#include + +#include +#include + +/** \defgroup spa_system System + * I/O, clock, polling, timer, and signal interfaces + */ + +/** + * \addtogroup spa_system + * \{ + */ + +/** + * 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,...) \ +({ \ + volatile int _res = -ENOTSUP; \ + struct spa_system *_o = o; \ + spa_interface_call_fast_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 */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/support/thread.h b/thirdparty/linuxbsd_headers/pipewire/spa/support/thread.h new file mode 100644 index 000000000000..1e5f837b829b --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/support/thread.h @@ -0,0 +1,129 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_THREAD_H +#define SPA_THREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include +#include + +/** \defgroup spa_thread Thread + * Threading utility interfaces + */ + +/** + * \addtogroup spa_thread + * \{ + */ + +/** a thread object. + * This can be cast to a platform native thread, like pthread on posix systems + */ +#define SPA_TYPE_INFO_Thread SPA_TYPE_INFO_POINTER_BASE "Thread" +struct spa_thread; + +#define SPA_TYPE_INTERFACE_ThreadUtils SPA_TYPE_INFO_INTERFACE_BASE "ThreadUtils" +#define SPA_VERSION_THREAD_UTILS 0 +struct spa_thread_utils { struct spa_interface iface; }; + +/** thread utils */ +struct spa_thread_utils_methods { +#define SPA_VERSION_THREAD_UTILS_METHODS 0 + uint32_t version; + + /** create a new thread that runs \a start with \a arg */ + struct spa_thread * (*create) (void *object, const struct spa_dict *props, + void *(*start)(void*), void *arg); + /** stop and join a thread */ + int (*join)(void *object, struct spa_thread *thread, void **retval); + + /** get realtime priority range for threads created with \a props */ + int (*get_rt_range) (void *object, const struct spa_dict *props, int *min, int *max); + /** acquire realtime priority, a priority of -1 refers to the priority + * configured in the realtime module + */ + int (*acquire_rt) (void *object, struct spa_thread *thread, int priority); + /** drop realtime priority */ + int (*drop_rt) (void *object, struct spa_thread *thread); +}; + +/** \copydoc spa_thread_utils_methods.create + * \sa spa_thread_utils_methods.create */ +static inline struct spa_thread *spa_thread_utils_create(struct spa_thread_utils *o, + const struct spa_dict *props, void *(*start_routine)(void*), void *arg) +{ + struct spa_thread *res = NULL; + spa_interface_call_res(&o->iface, + struct spa_thread_utils_methods, res, create, 0, + props, start_routine, arg); + return res; +} + +/** \copydoc spa_thread_utils_methods.join + * \sa spa_thread_utils_methods.join */ +static inline int spa_thread_utils_join(struct spa_thread_utils *o, + struct spa_thread *thread, void **retval) +{ + int res = -ENOTSUP; + spa_interface_call_res(&o->iface, + struct spa_thread_utils_methods, res, join, 0, + thread, retval); + return res; +} + +/** \copydoc spa_thread_utils_methods.get_rt_range + * \sa spa_thread_utils_methods.get_rt_range */ +static inline int spa_thread_utils_get_rt_range(struct spa_thread_utils *o, + const struct spa_dict *props, int *min, int *max) +{ + int res = -ENOTSUP; + spa_interface_call_res(&o->iface, + struct spa_thread_utils_methods, res, get_rt_range, 0, + props, min, max); + return res; +} + +/** \copydoc spa_thread_utils_methods.acquire_rt + * \sa spa_thread_utils_methods.acquire_rt */ +static inline int spa_thread_utils_acquire_rt(struct spa_thread_utils *o, + struct spa_thread *thread, int priority) +{ + int res = -ENOTSUP; + spa_interface_call_res(&o->iface, + struct spa_thread_utils_methods, res, acquire_rt, 0, + thread, priority); + return res; +} + +/** \copydoc spa_thread_utils_methods.drop_rt + * \sa spa_thread_utils_methods.drop_rt */ +static inline int spa_thread_utils_drop_rt(struct spa_thread_utils *o, + struct spa_thread *thread) +{ + int res = -ENOTSUP; + spa_interface_call_res(&o->iface, + struct spa_thread_utils_methods, res, drop_rt, 0, thread); + return res; +} + +#define SPA_KEY_THREAD_NAME "thread.name" /* the thread name */ +#define SPA_KEY_THREAD_STACK_SIZE "thread.stack-size" /* the stack size of the thread */ + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_THREAD_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/defs.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/defs.h new file mode 100644 index 000000000000..8940b52df772 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/defs.h @@ -0,0 +1,382 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_UTILS_DEFS_H +#define SPA_UTILS_DEFS_H + +#ifdef __cplusplus +extern "C" { +# if __cplusplus >= 201103L +# define SPA_STATIC_ASSERT_IMPL(expr, msg, ...) static_assert(expr, msg) +# endif +#else +# include +# if __STDC_VERSION__ >= 201112L +# define SPA_STATIC_ASSERT_IMPL(expr, msg, ...) _Static_assert(expr, msg) +# endif +#endif +#ifndef SPA_STATIC_ASSERT_IMPL +#define SPA_STATIC_ASSERT_IMPL(expr, ...) \ + ((void)sizeof(struct { int spa_static_assertion_failed : 2 * !!(expr) - 1; })) +#endif + +#define SPA_STATIC_ASSERT(expr, ...) SPA_STATIC_ASSERT_IMPL(expr, ## __VA_ARGS__, "`" #expr "` evaluated to false") + +#include +#include +#include +#include +#include +#include + +/** + * \defgroup spa_utils_defs Miscellaneous + * Helper macros and functions + */ + +/** + * \addtogroup spa_utils_defs + * \{ + */ + +/** + * SPA_FALLTHROUGH is an annotation to suppress compiler warnings about switch + * cases that fall through without a break or return statement. SPA_FALLTHROUGH + * is only needed on cases that have code: + * + * switch (foo) { + * case 1: // These cases have no code. No fallthrough annotations are needed. + * case 2: + * case 3: + * foo = 4; // This case has code, so a fallthrough annotation is needed: + * SPA_FALLTHROUGH; + * default: + * return foo; + * } + */ +#if defined(__clang__) && defined(__cplusplus) && __cplusplus >= 201103L + /* clang's fallthrough annotations are only available starting in C++11. */ +# define SPA_FALLTHROUGH [[clang::fallthrough]]; +#elif __GNUC__ >= 7 || __clang_major__ >= 10 +# define SPA_FALLTHROUGH __attribute__ ((fallthrough)); +#else +# define SPA_FALLTHROUGH /* FALLTHROUGH */ +#endif + +#define SPA_FLAG_MASK(field,mask,flag) (((field) & (mask)) == (flag)) +#define SPA_FLAG_IS_SET(field,flag) SPA_FLAG_MASK(field, flag, flag) + +#define SPA_FLAG_SET(field,flag) ((field) |= (flag)) +#define SPA_FLAG_CLEAR(field, flag) \ +({ \ + SPA_STATIC_ASSERT(__builtin_constant_p(flag) ? \ + (__typeof__(flag))(__typeof__(field))(__typeof__(flag))(flag) == (flag) : \ + sizeof(field) >= sizeof(flag), \ + "truncation problem when masking " #field \ + " with ~" #flag); \ + ((field) &= ~(__typeof__(field))(flag)); \ +}) +#define SPA_FLAG_UPDATE(field,flag,val) ((val) ? SPA_FLAG_SET((field),(flag)) : SPA_FLAG_CLEAR((field),(flag))) + +enum spa_direction { + SPA_DIRECTION_INPUT = 0, + SPA_DIRECTION_OUTPUT = 1, +}; + +#define SPA_DIRECTION_REVERSE(d) ((d) ^ 1) + +#define SPA_RECTANGLE(width,height) ((struct spa_rectangle){ (width), (height) }) +struct spa_rectangle { + uint32_t width; + uint32_t height; +}; + +#define SPA_POINT(x,y) ((struct spa_point){ (x), (y) }) +struct spa_point { + int32_t x; + int32_t y; +}; + +#define SPA_REGION(x,y,width,height) ((struct spa_region){ SPA_POINT(x,y), SPA_RECTANGLE(width,height) }) +struct spa_region { + struct spa_point position; + struct spa_rectangle size; +}; + +#define SPA_FRACTION(num,denom) ((struct spa_fraction){ (num), (denom) }) +struct spa_fraction { + uint32_t num; + uint32_t denom; +}; + +#define SPA_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) +/** + * Array iterator macro. Usage: + * ```c + * struct foo array[16]; + * struct foo *f; + * SPA_FOR_EACH_ELEMENT(array, f) { + * f->bar = baz; + * } + * ``` + */ +#define SPA_FOR_EACH_ELEMENT(arr, ptr) \ + for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++) + +#define SPA_FOR_EACH_ELEMENT_VAR(arr, var) \ + for (__typeof__((arr)[0])* var = arr; (void*)(var) < SPA_PTROFF(arr, sizeof(arr), void); (var)++) + +#define SPA_ABS(a) \ +({ \ + __typeof__(a) _a = (a); \ + SPA_LIKELY(_a >= 0) ? _a : -_a; \ +}) +#define SPA_MIN(a,b) \ +({ \ + __typeof__(a) _min_a = (a); \ + __typeof__(b) _min_b = (b); \ + SPA_LIKELY(_min_a <= _min_b) ? _min_a : _min_b; \ +}) +#define SPA_MAX(a,b) \ +({ \ + __typeof__(a) _max_a = (a); \ + __typeof__(b) _max_b = (b); \ + SPA_LIKELY(_max_a >= _max_b) ? _max_a : _max_b; \ +}) +#define SPA_CLAMP(v,low,high) \ +({ \ + __typeof__(v) _v = (v); \ + __typeof__(low) _low = (low); \ + __typeof__(high) _high = (high); \ + SPA_MIN(SPA_MAX(_v, _low), _high); \ +}) + +#define SPA_CLAMPF(v,low,high) \ +({ \ + fminf(fmaxf(v, low), high); \ +}) + + +#define SPA_SWAP(a,b) \ +({ \ + __typeof__(a) _t = (a); \ + (a) = b; (b) = _t; \ +}) + +#define SPA_TYPECHECK(type,x) \ +({ type _dummy; \ + typeof(x) _dummy2; \ + (void)(&_dummy == &_dummy2); \ + x; \ +}) + +/** + * Return the address (buffer + offset) as pointer of \a type + */ +#define SPA_PTROFF(ptr_,offset_,type_) ((type_*)((uintptr_t)(ptr_) + (ptrdiff_t)(offset_))) +#define SPA_PTROFF_ALIGN(ptr_,offset_,alignment_,type_) \ + SPA_PTR_ALIGN(SPA_PTROFF(ptr_,offset_,type_),alignment_,type_) + + +/** + * Deprecated, use SPA_PTROFF and SPA_PTROFF_ALIGN instead + */ +#define SPA_MEMBER(b,o,t) SPA_PTROFF(b,o,t) +#define SPA_MEMBER_ALIGN(b,o,a,t) SPA_PTROFF_ALIGN(b,o,a,t) + +#define SPA_CONTAINER_OF(p,t,m) ((t*)((uintptr_t)(p) - offsetof(t,m))) + +#define SPA_PTRDIFF(p1,p2) ((intptr_t)(p1) - (intptr_t)(p2)) + +#define SPA_PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define SPA_INT_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define SPA_PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define SPA_UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define SPA_TIME_INVALID ((int64_t)INT64_MIN) +#define SPA_IDX_INVALID ((unsigned int)-1) +#define SPA_ID_INVALID ((uint32_t)0xffffffff) + +#define SPA_NSEC_PER_SEC (1000000000LL) +#define SPA_NSEC_PER_MSEC (1000000ll) +#define SPA_NSEC_PER_USEC (1000ll) +#define SPA_USEC_PER_SEC (1000000ll) +#define SPA_USEC_PER_MSEC (1000ll) +#define SPA_MSEC_PER_SEC (1000ll) + +#define SPA_TIMESPEC_TO_NSEC(ts) ((ts)->tv_sec * SPA_NSEC_PER_SEC + (ts)->tv_nsec) +#define SPA_TIMESPEC_TO_USEC(ts) ((ts)->tv_sec * SPA_USEC_PER_SEC + (ts)->tv_nsec / SPA_NSEC_PER_USEC) +#define SPA_TIMEVAL_TO_NSEC(tv) ((tv)->tv_sec * SPA_NSEC_PER_SEC + (tv)->tv_usec * SPA_NSEC_PER_USEC) +#define SPA_TIMEVAL_TO_USEC(tv) ((tv)->tv_sec * SPA_USEC_PER_SEC + (tv)->tv_usec) + +#ifdef __GNUC__ +#define SPA_PRINTF_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1))) +#define SPA_FORMAT_ARG_FUNC(arg1) __attribute__((format_arg(arg1))) +#define SPA_ALIGNED(align) __attribute__((aligned(align))) +#define SPA_DEPRECATED __attribute__ ((deprecated)) +#define SPA_EXPORT __attribute__((visibility("default"))) +#define SPA_SENTINEL __attribute__((__sentinel__)) +#define SPA_UNUSED __attribute__ ((unused)) +#define SPA_NORETURN __attribute__ ((noreturn)) +#define SPA_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +#else +#define SPA_PRINTF_FUNC(fmt, arg1) +#define SPA_FORMAT_ARG_FUNC(arg1) +#define SPA_ALIGNED(align) +#define SPA_DEPRECATED +#define SPA_EXPORT +#define SPA_SENTINEL +#define SPA_UNUSED +#define SPA_NORETURN +#define SPA_WARN_UNUSED_RESULT +#endif + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define SPA_RESTRICT restrict +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define SPA_RESTRICT __restrict__ +#else +#define SPA_RESTRICT +#endif + +#define SPA_ROUND_DOWN(num,value) \ +({ \ + __typeof__(num) _num = (num); \ + ((_num) - ((_num) % (value))); \ +}) +#define SPA_ROUND_UP(num,value) \ +({ \ + __typeof__(value) _v = (value); \ + ((((num) + (_v) - 1) / (_v)) * (_v)); \ +}) + +#define SPA_ROUND_MASK(num,mask) ((__typeof__(num))((mask)-1)) + +#define SPA_ROUND_DOWN_N(num,align) ((num) & ~SPA_ROUND_MASK(num, align)) +#define SPA_ROUND_UP_N(num,align) ((((num)-1) | SPA_ROUND_MASK(num, align))+1) + +#define SPA_SCALE32_UP(val,num,denom) \ +({ \ + uint64_t _val = (val); \ + uint64_t _denom = (denom); \ + (uint32_t)(((_val) * (num) + (_denom)-1) / (_denom)); \ +}) + + +#define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1)) +#define SPA_IS_ALIGNED(p,align) (SPA_PTR_ALIGNMENT(p,align) == 0) +#define SPA_PTR_ALIGN(p,align,type) ((type*)SPA_ROUND_UP_N((intptr_t)(p), (intptr_t)(align))) + +#ifndef SPA_LIKELY +#ifdef __GNUC__ +#define SPA_LIKELY(x) (__builtin_expect(!!(x),1)) +#define SPA_UNLIKELY(x) (__builtin_expect(!!(x),0)) +#else +#define SPA_LIKELY(x) (x) +#define SPA_UNLIKELY(x) (x) +#endif +#endif + +#define SPA_STRINGIFY_1(...) #__VA_ARGS__ +#define SPA_STRINGIFY(...) SPA_STRINGIFY_1(__VA_ARGS__) + +#define spa_return_if_fail(expr) \ + do { \ + if (SPA_UNLIKELY(!(expr))) { \ + fprintf(stderr, "'%s' failed at %s:%u %s()\n", \ + #expr , __FILE__, __LINE__, __func__); \ + return; \ + } \ + } while(false) + +#define spa_return_val_if_fail(expr, val) \ + do { \ + if (SPA_UNLIKELY(!(expr))) { \ + fprintf(stderr, "'%s' failed at %s:%u %s()\n", \ + #expr , __FILE__, __LINE__, __func__); \ + return (val); \ + } \ + } while(false) + +/* spa_assert_se() is an assert which guarantees side effects of x, + * i.e. is never optimized away, regardless of NDEBUG or FASTPATH. */ +#ifndef __COVERITY__ +#define spa_assert_se(expr) \ + do { \ + if (SPA_UNLIKELY(!(expr))) { \ + fprintf(stderr, "'%s' failed at %s:%u %s()\n", \ + #expr , __FILE__, __LINE__, __func__); \ + abort(); \ + } \ + } while (false) +#else +#define spa_assert_se(expr) \ + do { \ + int _unique_var = (expr); \ + if (!_unique_var) \ + abort(); \ + } while (false) +#endif + +/* Does exactly nothing */ +#define spa_nop() do {} while (false) + +#ifdef NDEBUG +#define spa_assert(expr) spa_nop() +#elif defined (FASTPATH) +#define spa_assert(expr) spa_assert_se(expr) +#else +#define spa_assert(expr) spa_assert_se(expr) +#endif + +#ifdef NDEBUG +#define spa_assert_not_reached() abort() +#else +#define spa_assert_not_reached() \ + do { \ + fprintf(stderr, "Code should not be reached at %s:%u %s()\n", \ + __FILE__, __LINE__, __func__); \ + abort(); \ + } while (false) +#endif + +#define spa_memzero(x,l) (memset((x), 0, (l))) +#define spa_zero(x) (spa_memzero(&(x), sizeof(x))) + +#ifdef SPA_DEBUG_MEMCPY +#define spa_memcpy(d,s,n) \ +({ \ + fprintf(stderr, "%s:%u %s() memcpy(%p, %p, %zd)\n", \ + __FILE__, __LINE__, __func__, (d), (s), (size_t)(n)); \ + memcpy(d,s,n); \ +}) +#define spa_memmove(d,s,n) \ +({ \ + fprintf(stderr, "%s:%u %s() memmove(%p, %p, %zd)\n", \ + __FILE__, __LINE__, __func__, (d), (s), (size_t)(n)); \ + memmove(d,s,n); \ +}) +#else +#define spa_memcpy(d,s,n) memcpy(d,s,n) +#define spa_memmove(d,s,n) memmove(d,s,n) +#endif + +#define spa_aprintf(_fmt, ...) \ +({ \ + char *_strp; \ + if (asprintf(&(_strp), (_fmt), ## __VA_ARGS__ ) == -1) \ + _strp = NULL; \ + _strp; \ +}) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_UTILS_DEFS_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/dict.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/dict.h new file mode 100644 index 000000000000..126f469ec27a --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/dict.h @@ -0,0 +1,100 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_DICT_H +#define SPA_DICT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +/** + * \defgroup spa_dict Dictionary + * Dictionary data structure + */ + +/** + * \addtogroup spa_dict + * \{ + */ + +struct spa_dict_item { + const char *key; + const char *value; +}; + +#define SPA_DICT_ITEM_INIT(key,value) ((struct spa_dict_item) { (key), (value) }) + +struct spa_dict { +#define SPA_DICT_FLAG_SORTED (1<<0) /**< items are sorted */ + uint32_t flags; + uint32_t n_items; + const struct spa_dict_item *items; +}; + +#define SPA_DICT_INIT(items,n_items) ((struct spa_dict) { 0, (n_items), (items) }) +#define SPA_DICT_INIT_ARRAY(items) ((struct spa_dict) { 0, SPA_N_ELEMENTS(items), (items) }) + +#define spa_dict_for_each(item, dict) \ + for ((item) = (dict)->items; \ + (item) < &(dict)->items[(dict)->n_items]; \ + (item)++) + +static inline int spa_dict_item_compare(const void *i1, const void *i2) +{ + const struct spa_dict_item *it1 = (const struct spa_dict_item *)i1, + *it2 = (const struct spa_dict_item *)i2; + return strcmp(it1->key, it2->key); +} + +static inline void spa_dict_qsort(struct spa_dict *dict) +{ + if (dict->n_items > 0) + qsort((void*)dict->items, dict->n_items, sizeof(struct spa_dict_item), + spa_dict_item_compare); + SPA_FLAG_SET(dict->flags, SPA_DICT_FLAG_SORTED); +} + +static inline const struct spa_dict_item *spa_dict_lookup_item(const struct spa_dict *dict, + const char *key) +{ + const struct spa_dict_item *item; + + if (SPA_FLAG_IS_SET(dict->flags, SPA_DICT_FLAG_SORTED) && + dict->n_items > 0) { + struct spa_dict_item k = SPA_DICT_ITEM_INIT(key, NULL); + item = (const struct spa_dict_item *)bsearch(&k, + (const void *) dict->items, dict->n_items, + sizeof(struct spa_dict_item), + spa_dict_item_compare); + if (item != NULL) + return item; + } else { + spa_dict_for_each(item, dict) { + if (!strcmp(item->key, key)) + return item; + } + } + return NULL; +} + +static inline const char *spa_dict_lookup(const struct spa_dict *dict, const char *key) +{ + const struct spa_dict_item *item = spa_dict_lookup_item(dict, key); + return item ? item->value : NULL; +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_DICT_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/hook.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/hook.h new file mode 100644 index 000000000000..aea18d28e0a6 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/hook.h @@ -0,0 +1,471 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_HOOK_H +#define SPA_HOOK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** \defgroup spa_interfaces Interfaces + * + * \brief Generic implementation of implementation-independent interfaces + * + * A SPA Interface is a generic struct that, together with a few macros, + * provides a generic way of invoking methods on objects without knowing the + * details of the implementation. + * + * The primary interaction with interfaces is through macros that expand into + * the right method call. For the implementation of an interface, we need two + * structs and a macro to invoke the `bar` method: + * + * \code{.c} + * // this struct must be public and defines the interface to a + * // struct foo + * struct foo_methods { + * uint32_t version; + * void (*bar)(void *object, const char *msg); + * }; + * + * // this struct does not need to be public + * struct foo { + * struct spa_interface iface; // must be first element, see foo_bar() + * int some_other_field; + * ... + * }; + * + * // if struct foo is private, we need to cast to a + * // generic spa_interface object + * #define foo_bar(obj, ...) ({ \ + * struct foo *f = obj; + * spa_interface_call((struct spa_interface *)f, // pointer to spa_interface in foo + * struct foo_methods, // type of callbacks + * bar, // name of methods + * 0, // hardcoded version to match foo_methods->version + * __VA_ARGS__ // pass rest of args through + * );/ + * }) + * \endcode + * + * The `struct foo_methods` and the invocation macro `foo_bar()` must be + * available to the caller. The implementation of `struct foo` can be private. + * + * \code{.c} + * void main(void) { + * struct foo *myfoo = get_foo_from_somewhere(); + * foo_bar(myfoo, "Invoking bar() on myfoo"); + * } + * \endcode + * The expansion of `foo_bar()` resolves roughly into this code: + * \code{.c} + * void main(void) { + * struct foo *myfoo = get_foo_from_somewhere(); + * // foo_bar(myfoo, "Invoking bar() on myfoo"); + * const struct foo_methods *methods = ((struct spa_interface*)myfoo)->cb; + * if (0 >= methods->version && // version check + * methods->bar) // compile error if this function does not exist, + * methods->bar(myfoo, "Invoking bar() on myfoo"); + * } + * \endcode + * + * The typecast used in `foo_bar()` allows `struct foo` to be opaque to the + * caller. The implementation may assign the callback methods at object + * instantiation, and the caller will transparently invoke the method on the + * given object. For example, the following code assigns a different `bar()` method on + * Mondays - the caller does not need to know this. + * \code{.c} + * + * static void bar_stdout(struct foo *f, const char *msg) { + * printf(msg); + * } + * static void bar_stderr(struct foo *f, const char *msg) { + * fprintf(stderr, msg); + * } + * + * struct foo* get_foo_from_somewhere() { + * struct foo *f = calloc(sizeof struct foo); + * // illustrative only, use SPA_INTERFACE_INIT() + * f->iface->cb = (struct foo_methods*) { .bar = bar_stdout }; + * if (today_is_monday) + * f->iface->cb = (struct foo_methods*) { .bar = bar_stderr }; + * return f; + * } + * \endcode + */ + +/** + * \addtogroup spa_interfaces + * \{ + */ + +/** \struct spa_callbacks + * Callbacks, contains the structure with functions and the data passed + * to the functions. The structure should also contain a version field that + * is checked. */ +struct spa_callbacks { + const void *funcs; + void *data; +}; + +/** Check if a callback \a c is of at least version \a v */ +#define SPA_CALLBACK_VERSION_MIN(c,v) ((c) && ((v) == 0 || (c)->version > (v)-1)) + +/** Check if a callback \a c has method \a m of version \a v */ +#define SPA_CALLBACK_CHECK(c,m,v) (SPA_CALLBACK_VERSION_MIN(c,v) && (c)->m) + +/** + * Initialize the set of functions \a funcs as a \ref spa_callbacks, together + * with \a _data. + */ +#define SPA_CALLBACKS_INIT(_funcs,_data) ((struct spa_callbacks){ (_funcs), (_data), }) + +/** \struct spa_interface + */ +struct spa_interface { + const char *type; + uint32_t version; + struct spa_callbacks cb; +}; + +/** + * Initialize a \ref spa_interface. + * + * \code{.c} + * const static struct foo_methods foo_funcs = { + * .bar = some_bar_implementation, + * }; + * + * struct foo *f = malloc(...); + * f->iface = SPA_INTERFACE_INIT("foo type", 0, foo_funcs, NULL); + * \endcode + * + */ +#define SPA_INTERFACE_INIT(_type,_version,_funcs,_data) \ + ((struct spa_interface){ (_type), (_version), SPA_CALLBACKS_INIT(_funcs,_data), }) + +/** + * Invoke method named \a method in the \a callbacks. + * The \a method_type defines the type of the method struct. + * Returns true if the method could be called, false otherwise. + */ +#define spa_callbacks_call(callbacks,type,method,vers,...) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + bool _res = SPA_CALLBACK_CHECK(_f,method,vers); \ + if (SPA_LIKELY(_res)) \ + _f->method((callbacks)->data, ## __VA_ARGS__); \ + _res; \ +}) + +#define spa_callbacks_call_fast(callbacks,type,method,vers,...) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + _f->method((callbacks)->data, ## __VA_ARGS__); \ + true; \ +}) + + +/** + * True if the \a callbacks are of version \a vers, false otherwise + */ +#define spa_callback_version_min(callbacks,type,vers) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + SPA_CALLBACK_VERSION_MIN(_f,vers); \ +}) + +/** + * True if the \a callbacks contains \a method of version + * \a vers, false otherwise + */ +#define spa_callback_check(callbacks,type,method,vers) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + SPA_CALLBACK_CHECK(_f,method,vers); \ +}) + +/** + * Invoke method named \a method in the \a callbacks. + * The \a method_type defines the type of the method struct. + * + * The return value is stored in \a res. + */ +#define spa_callbacks_call_res(callbacks,type,res,method,vers,...) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + if (SPA_LIKELY(SPA_CALLBACK_CHECK(_f,method,vers))) \ + res = _f->method((callbacks)->data, ## __VA_ARGS__); \ + res; \ +}) +#define spa_callbacks_call_fast_res(callbacks,type,res,method,vers,...) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + res = _f->method((callbacks)->data, ## __VA_ARGS__); \ +}) + +/** + * True if the \a iface's callbacks are of version \a vers, false otherwise + */ +#define spa_interface_callback_version_min(iface,method_type,vers) \ + spa_callback_version_min(&(iface)->cb, method_type, vers) + +/** + * True if the \a iface's callback \a method is of version \a vers + * and exists, false otherwise + */ +#define spa_interface_callback_check(iface,method_type,method,vers) \ + spa_callback_check(&(iface)->cb, method_type, method, vers) + +/** + * Invoke method named \a method in the callbacks on the given interface object. + * The \a method_type defines the type of the method struct, not the interface + * itself. + */ +#define spa_interface_call(iface,method_type,method,vers,...) \ + spa_callbacks_call(&(iface)->cb,method_type,method,vers,##__VA_ARGS__) + +#define spa_interface_call_fast(iface,method_type,method,vers,...) \ + spa_callbacks_call_fast(&(iface)->cb,method_type,method,vers,##__VA_ARGS__) + +/** + * Invoke method named \a method in the callbacks on the given interface object. + * The \a method_type defines the type of the method struct, not the interface + * itself. + * + * The return value is stored in \a res. + */ +#define spa_interface_call_res(iface,method_type,res,method,vers,...) \ + spa_callbacks_call_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__) + +#define spa_interface_call_fast_res(iface,method_type,res,method,vers,...) \ + spa_callbacks_call_fast_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__) + +/** + * \} + */ + +/** \defgroup spa_hooks Hooks + * + * A SPA Hook is a data structure to keep track of callbacks. It is similar to + * the \ref spa_interfaces and typically used where an implementation allows + * for multiple external callback functions. For example, an implementation may + * use a hook list to implement signals with each caller using a hook to + * register callbacks to be invoked on those signals. + * + * The below (pseudo)code is a minimal example outlining the use of hooks: + * \code{.c} + * // the public interface + * #define VERSION_BAR_EVENTS 0 // version of the vtable + * struct bar_events { + * uint32_t version; // NOTE: an integral member named `version` + * // must be present in the vtable + * void (*boom)(void *data, const char *msg); + * }; + * + * // private implementation + * struct party { + * struct spa_hook_list bar_list; + * }; + * + * void party_add_event_listener(struct party *p, struct spa_hook *listener, + * const struct bar_events *events, void *data) + * { + * spa_hook_list_append(&p->bar_list, listener, events, data); + * } + * + * static void party_on(struct party *p) + * { + * // NOTE: this is a macro, it evaluates to an integer, + * // which is the number of hooks called + * spa_hook_list_call(&p->list, + * struct bar_events, // vtable type + * boom, // function name + * 0, // hardcoded version, + * // usually the version in which `boom` + * // has been added to the vtable + * "party on, wayne" // function argument(s) + * ); + * } + * \endcode + * + * In the caller, the hooks can be used like this: + * \code{.c} + * static void boom_cb(void *data, const char *msg) { + * // data is userdata from main() + * printf("%s", msg); + * } + * + * static const struct bar_events events = { + * .version = VERSION_BAR_EVENTS, // version of the implemented interface + * .boom = boom_cb, + * }; + * + * void main(void) { + * void *userdata = whatever; + * struct spa_hook hook; + * struct party *p = start_the_party(); + * + * party_add_event_listener(p, &hook, &events, userdata); + * + * mainloop(); + * return 0; + * } + * + * \endcode + */ + +/** + * \addtogroup spa_hooks + * \{ + */ + +/** \struct spa_hook_list + * A list of hooks. This struct is primarily used by + * implementation that use multiple caller-provided \ref spa_hook. */ +struct spa_hook_list { + struct spa_list list; +}; + + +/** \struct spa_hook + * A hook, contains the structure with functions and the data passed + * to the functions. + * + * A hook should be treated as opaque by the caller. + */ +struct spa_hook { + struct spa_list link; + struct spa_callbacks cb; + /** callback and data for the hook list, private to the + * hook_list implementor */ + void (*removed) (struct spa_hook *hook); + void *priv; +}; + +/** Initialize a hook list to the empty list*/ +static inline void spa_hook_list_init(struct spa_hook_list *list) +{ + spa_list_init(&list->list); +} + +static inline bool spa_hook_list_is_empty(struct spa_hook_list *list) +{ + return spa_list_is_empty(&list->list); +} + +/** Append a hook. */ +static inline void spa_hook_list_append(struct spa_hook_list *list, + struct spa_hook *hook, + const void *funcs, void *data) +{ + spa_zero(*hook); + hook->cb = SPA_CALLBACKS_INIT(funcs, data); + spa_list_append(&list->list, &hook->link); +} + +/** Prepend a hook */ +static inline void spa_hook_list_prepend(struct spa_hook_list *list, + struct spa_hook *hook, + const void *funcs, void *data) +{ + spa_zero(*hook); + hook->cb = SPA_CALLBACKS_INIT(funcs, data); + spa_list_prepend(&list->list, &hook->link); +} + +/** Remove a hook */ +static inline void spa_hook_remove(struct spa_hook *hook) +{ + if (spa_list_is_initialized(&hook->link)) + spa_list_remove(&hook->link); + if (hook->removed) + hook->removed(hook); +} + +/** Remove all hooks from the list */ +static inline void spa_hook_list_clean(struct spa_hook_list *list) +{ + struct spa_hook *h; + spa_list_consume(h, &list->list, link) + spa_hook_remove(h); +} + +static inline void +spa_hook_list_isolate(struct spa_hook_list *list, + struct spa_hook_list *save, + struct spa_hook *hook, + const void *funcs, void *data) +{ + /* init save list and move hooks to it */ + spa_hook_list_init(save); + spa_list_insert_list(&save->list, &list->list); + /* init hooks and add single hook */ + spa_hook_list_init(list); + spa_hook_list_append(list, hook, funcs, data); +} + +static inline void +spa_hook_list_join(struct spa_hook_list *list, + struct spa_hook_list *save) +{ + spa_list_insert_list(&list->list, &save->list); +} + +#define spa_hook_list_call_simple(l,type,method,vers,...) \ +({ \ + struct spa_hook_list *_l = l; \ + struct spa_hook *_h, *_t; \ + spa_list_for_each_safe(_h, _t, &_l->list, link) \ + spa_callbacks_call(&_h->cb,type,method,vers, ## __VA_ARGS__); \ +}) + +/** Call all hooks in a list, starting from the given one and optionally stopping + * after calling the first non-NULL function, returns the number of methods + * called */ +#define spa_hook_list_do_call(l,start,type,method,vers,once,...) \ +({ \ + struct spa_hook_list *_list = l; \ + struct spa_list *_s = start ? (struct spa_list *)start : &_list->list; \ + struct spa_hook _cursor = { 0 }, *_ci; \ + int _count = 0; \ + spa_list_cursor_start(_cursor, _s, link); \ + spa_list_for_each_cursor(_ci, _cursor, &_list->list, link) { \ + if (spa_callbacks_call(&_ci->cb,type,method,vers, ## __VA_ARGS__)) { \ + _count++; \ + if (once) \ + break; \ + } \ + } \ + spa_list_cursor_end(_cursor, link); \ + _count; \ +}) + +/** + * Call the method named \a m for each element in list \a l. + * \a t specifies the type of the callback struct. + */ +#define spa_hook_list_call(l,t,m,v,...) spa_hook_list_do_call(l,NULL,t,m,v,false,##__VA_ARGS__) +/** + * Call the method named \a m for each element in list \a l, stopping after + * the first invocation. + * \a t specifies the type of the callback struct. + */ +#define spa_hook_list_call_once(l,t,m,v,...) spa_hook_list_do_call(l,NULL,t,m,v,true,##__VA_ARGS__) + +#define spa_hook_list_call_start(l,s,t,m,v,...) spa_hook_list_do_call(l,s,t,m,v,false,##__VA_ARGS__) +#define spa_hook_list_call_once_start(l,s,t,m,v,...) spa_hook_list_do_call(l,s,t,m,v,true,##__VA_ARGS__) + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SPA_HOOK_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/keys.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/keys.h new file mode 100644 index 000000000000..2f007ade3869 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/keys.h @@ -0,0 +1,132 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_UTILS_KEYS_H +#define SPA_UTILS_KEYS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup spa_keys Key Names + * Key names used by SPA plugins + */ + +/** + * \addtogroup spa_keys + * \{ + */ + +/** for objects */ +#define SPA_KEY_OBJECT_PATH "object.path" /**< a unique path to + * identity the object */ + +#define SPA_KEY_MEDIA_CLASS "media.class" /**< Media class + * Ex. "Audio/Device", + * "Video/Source",... */ +#define SPA_KEY_MEDIA_ROLE "media.role" /**< Role: Movie, Music, Camera, + * Screen, Communication, Game, + * Notification, DSP, Production, + * Accessibility, Test */ +/** keys for udev api */ +#define SPA_KEY_API_UDEV "api.udev" /**< key for the udev api */ +#define SPA_KEY_API_UDEV_MATCH "api.udev.match" /**< udev subsystem match */ + +/** keys for alsa api */ +#define SPA_KEY_API_ALSA "api.alsa" /**< key for the alsa api */ +#define SPA_KEY_API_ALSA_PATH "api.alsa.path" /**< alsa device path as can be + * used in snd_pcm_open() and + * snd_ctl_open(). */ +#define SPA_KEY_API_ALSA_CARD "api.alsa.card" /**< alsa card number */ +#define SPA_KEY_API_ALSA_USE_UCM "api.alsa.use-ucm" /**< if UCM should be used */ +#define SPA_KEY_API_ALSA_IGNORE_DB "api.alsa.ignore-dB" /**< if decibel info should be ignored */ +#define SPA_KEY_API_ALSA_OPEN_UCM "api.alsa.open.ucm" /**< if UCM should be opened card */ +#define SPA_KEY_API_ALSA_DISABLE_LONGNAME \ + "api.alsa.disable-longname" /**< if card long name should not be passed to MIDI port */ +#define SPA_KEY_API_ALSA_BIND_CTLS "api.alsa.bind-ctls" /**< alsa controls to bind as params */ + +/** info from alsa card_info */ +#define SPA_KEY_API_ALSA_CARD_ID "api.alsa.card.id" /**< id from card_info */ +#define SPA_KEY_API_ALSA_CARD_COMPONENTS \ + "api.alsa.card.components" /**< components from card_info */ +#define SPA_KEY_API_ALSA_CARD_DRIVER "api.alsa.card.driver" /**< driver from card_info */ +#define SPA_KEY_API_ALSA_CARD_NAME "api.alsa.card.name" /**< name from card_info */ +#define SPA_KEY_API_ALSA_CARD_LONGNAME "api.alsa.card.longname" /**< longname from card_info */ +#define SPA_KEY_API_ALSA_CARD_MIXERNAME "api.alsa.card.mixername" /**< mixername from card_info */ + +/** info from alsa pcm_info */ +#define SPA_KEY_API_ALSA_PCM_ID "api.alsa.pcm.id" /**< id from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_CARD "api.alsa.pcm.card" /**< card from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_NAME "api.alsa.pcm.name" /**< name from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_SUBNAME "api.alsa.pcm.subname" /**< subdevice_name from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_STREAM "api.alsa.pcm.stream" /**< stream type from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_CLASS "api.alsa.pcm.class" /**< class from pcm_info as string */ +#define SPA_KEY_API_ALSA_PCM_DEVICE "api.alsa.pcm.device" /**< device from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_SUBDEVICE "api.alsa.pcm.subdevice" /**< subdevice from pcm_info */ +#define SPA_KEY_API_ALSA_PCM_SUBCLASS "api.alsa.pcm.subclass" /**< subclass from pcm_info as string */ +#define SPA_KEY_API_ALSA_PCM_SYNC_ID "api.alsa.pcm.sync-id" /**< sync id */ + +/** keys for v4l2 api */ +#define SPA_KEY_API_V4L2 "api.v4l2" /**< key for the v4l2 api */ +#define SPA_KEY_API_V4L2_PATH "api.v4l2.path" /**< v4l2 device path as can be + * used in open() */ + +/** keys for libcamera api */ +#define SPA_KEY_API_LIBCAMERA "api.libcamera" /**< key for the libcamera api */ +#define SPA_KEY_API_LIBCAMERA_PATH "api.libcamera.path" /**< libcamera device path as can be + * used in open() */ +#define SPA_KEY_API_LIBCAMERA_LOCATION "api.libcamera.location" /**< location of the camera: + * "front", "back" or "external" */ + +/** info from libcamera_capability */ +#define SPA_KEY_API_LIBCAMERA_CAP_DRIVER "api.libcamera.cap.driver" /**< driver from capbility */ +#define SPA_KEY_API_LIBCAMERA_CAP_CARD "api.libcamera.cap.card" /**< caps from capability */ +#define SPA_KEY_API_LIBCAMERA_CAP_BUS_INFO "api.libcamera.cap.bus_info"/**< bus_info from capability */ +#define SPA_KEY_API_LIBCAMERA_CAP_VERSION "api.libcamera.cap.version" /**< version from capability as %u.%u.%u */ +#define SPA_KEY_API_LIBCAMERA_CAP_CAPABILITIES \ + "api.libcamera.cap.capabilities" /**< capabilities from capability */ +#define SPA_KEY_API_LIBCAMERA_CAP_DEVICE_CAPS \ + "api.libcamera.cap.device-caps" /**< device_caps from capability */ +/** info from v4l2_capability */ +#define SPA_KEY_API_V4L2_CAP_DRIVER "api.v4l2.cap.driver" /**< driver from capbility */ +#define SPA_KEY_API_V4L2_CAP_CARD "api.v4l2.cap.card" /**< caps from capability */ +#define SPA_KEY_API_V4L2_CAP_BUS_INFO "api.v4l2.cap.bus_info" /**< bus_info from capability */ +#define SPA_KEY_API_V4L2_CAP_VERSION "api.v4l2.cap.version" /**< version from capability as %u.%u.%u */ +#define SPA_KEY_API_V4L2_CAP_CAPABILITIES \ + "api.v4l2.cap.capabilities" /**< capabilities from capability */ +#define SPA_KEY_API_V4L2_CAP_DEVICE_CAPS \ + "api.v4l2.cap.device-caps" /**< device_caps from capability */ + + +/** keys for bluez5 api */ +#define SPA_KEY_API_BLUEZ5 "api.bluez5" /**< key for the bluez5 api */ +#define SPA_KEY_API_BLUEZ5_PATH "api.bluez5.path" /**< a bluez5 path */ +#define SPA_KEY_API_BLUEZ5_DEVICE "api.bluez5.device" /**< an internal bluez5 device */ +#define SPA_KEY_API_BLUEZ5_CONNECTION "api.bluez5.connection" /**< bluez5 device connection status */ +#define SPA_KEY_API_BLUEZ5_TRANSPORT "api.bluez5.transport" /**< an internal bluez5 transport */ +#define SPA_KEY_API_BLUEZ5_PROFILE "api.bluez5.profile" /**< a bluetooth profile */ +#define SPA_KEY_API_BLUEZ5_ADDRESS "api.bluez5.address" /**< a bluetooth address */ +#define SPA_KEY_API_BLUEZ5_CODEC "api.bluez5.codec" /**< a bluetooth codec */ +#define SPA_KEY_API_BLUEZ5_CLASS "api.bluez5.class" /**< a bluetooth class */ +#define SPA_KEY_API_BLUEZ5_ICON "api.bluez5.icon" /**< a bluetooth icon */ +#define SPA_KEY_API_BLUEZ5_ROLE "api.bluez5.role" /**< "client" or "server" */ + +/** keys for jack api */ +#define SPA_KEY_API_JACK "api.jack" /**< key for the JACK api */ +#define SPA_KEY_API_JACK_SERVER "api.jack.server" /**< a jack server name */ +#define SPA_KEY_API_JACK_CLIENT "api.jack.client" /**< an internal jack client */ + +/** keys for glib api */ +#define SPA_KEY_API_GLIB_MAINLOOP "api.glib.mainloop" /**< whether glib mainloop runs + * in same thread as PW loop */ + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_UTILS_KEYS_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/list.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/list.h new file mode 100644 index 000000000000..0c03854b5455 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/list.h @@ -0,0 +1,146 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_LIST_H +#define SPA_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup spa_list List + * Doubly linked list data structure + */ + +/** + * \addtogroup spa_list List + * \{ + */ + +struct spa_list { + struct spa_list *next; + struct spa_list *prev; +}; + +#define SPA_LIST_INIT(list) ((struct spa_list){ (list), (list) }) + +static inline void spa_list_init(struct spa_list *list) +{ + *list = SPA_LIST_INIT(list); +} + +static inline int spa_list_is_initialized(struct spa_list *list) +{ + return !!list->prev; +} + +#define spa_list_is_empty(l) ((l)->next == (l)) + +static inline void spa_list_insert(struct spa_list *list, struct spa_list *elem) +{ + elem->prev = list; + elem->next = list->next; + list->next = elem; + elem->next->prev = elem; +} + +static inline void spa_list_insert_list(struct spa_list *list, struct spa_list *other) +{ + if (spa_list_is_empty(other)) + return; + other->next->prev = list; + other->prev->next = list->next; + list->next->prev = other->prev; + list->next = other->next; +} + +static inline void spa_list_remove(struct spa_list *elem) +{ + elem->prev->next = elem->next; + elem->next->prev = elem->prev; +} + +#define spa_list_first(head, type, member) \ + SPA_CONTAINER_OF((head)->next, type, member) + +#define spa_list_last(head, type, member) \ + SPA_CONTAINER_OF((head)->prev, type, member) + +#define spa_list_append(list, item) \ + spa_list_insert((list)->prev, item) + +#define spa_list_prepend(list, item) \ + spa_list_insert(list, item) + +#define spa_list_is_end(pos, head, member) \ + (&(pos)->member == (head)) + +#define spa_list_next(pos, member) \ + SPA_CONTAINER_OF((pos)->member.next, __typeof__(*(pos)), member) + +#define spa_list_prev(pos, member) \ + SPA_CONTAINER_OF((pos)->member.prev, __typeof__(*(pos)), member) + +#define spa_list_consume(pos, head, member) \ + for ((pos) = spa_list_first(head, __typeof__(*(pos)), member); \ + !spa_list_is_empty(head); \ + (pos) = spa_list_first(head, __typeof__(*(pos)), member)) + +#define spa_list_for_each_next(pos, head, curr, member) \ + for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member); \ + !spa_list_is_end(pos, head, member); \ + (pos) = spa_list_next(pos, member)) + +#define spa_list_for_each_prev(pos, head, curr, member) \ + for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member); \ + !spa_list_is_end(pos, head, member); \ + (pos) = spa_list_prev(pos, member)) + +#define spa_list_for_each(pos, head, member) \ + spa_list_for_each_next(pos, head, head, member) + +#define spa_list_for_each_reverse(pos, head, member) \ + spa_list_for_each_prev(pos, head, head, member) + +#define spa_list_for_each_safe_next(pos, tmp, head, curr, member) \ + for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member); \ + (tmp) = spa_list_next(pos, member), \ + !spa_list_is_end(pos, head, member); \ + (pos) = (tmp)) + +#define spa_list_for_each_safe_prev(pos, tmp, head, curr, member) \ + for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member); \ + (tmp) = spa_list_prev(pos, member), \ + !spa_list_is_end(pos, head, member); \ + (pos) = (tmp)) + +#define spa_list_for_each_safe(pos, tmp, head, member) \ + spa_list_for_each_safe_next(pos, tmp, head, head, member) + +#define spa_list_for_each_safe_reverse(pos, tmp, head, member) \ + spa_list_for_each_safe_prev(pos, tmp, head, head, member) + +#define spa_list_cursor_start(cursor, head, member) \ + spa_list_prepend(head, &(cursor).member) + +#define spa_list_for_each_cursor(pos, cursor, head, member) \ + for((pos) = spa_list_first(&(cursor).member, __typeof__(*(pos)), member); \ + spa_list_remove(&(pos)->member), \ + spa_list_append(&(cursor).member, &(pos)->member), \ + !spa_list_is_end(pos, head, member); \ + (pos) = spa_list_next(&(cursor), member)) + +#define spa_list_cursor_end(cursor, member) \ + spa_list_remove(&(cursor).member) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_LIST_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/string.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/string.h new file mode 100644 index 000000000000..cd044998f9b0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/string.h @@ -0,0 +1,394 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2021 Red Hat, Inc. */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_UTILS_STRING_H +#define SPA_UTILS_STRING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#include + +/** + * \defgroup spa_string String handling + * String handling utilities + */ + +/** + * \addtogroup spa_string + * \{ + */ + +/** + * \return true if the two strings are equal, false otherwise + * + * If both \a a and \a b are NULL, the two are considered equal. + * + */ +static inline bool spa_streq(const char *s1, const char *s2) +{ + return SPA_LIKELY(s1 && s2) ? strcmp(s1, s2) == 0 : s1 == s2; +} + +/** + * \return true if the two strings are equal, false otherwise + * + * If both \a a and \a b are NULL, the two are considered equal. + */ +static inline bool spa_strneq(const char *s1, const char *s2, size_t len) +{ + return SPA_LIKELY(s1 && s2) ? strncmp(s1, s2, len) == 0 : s1 == s2; +} + + +/** + * \return true if \a s starts with the \a prefix or false otherwise. + * A \a s is NULL, it never starts with the given \a prefix. A \a prefix of + * NULL is a bug in the caller. + */ +static inline bool spa_strstartswith(const char *s, const char *prefix) +{ + if (SPA_UNLIKELY(s == NULL)) + return false; + + spa_assert_se(prefix); + + return strncmp(s, prefix, strlen(prefix)) == 0; +} + + +/** + * \return true if \a s ends with the \a suffix or false otherwise. + * A \a s is NULL, it never ends with the given \a suffix. A \a suffix of + * NULL is a bug in the caller. + */ +static inline bool spa_strendswith(const char *s, const char *suffix) +{ + size_t l1, l2; + + if (SPA_UNLIKELY(s == NULL)) + return false; + + spa_assert_se(suffix); + + l1 = strlen(s); + l2 = strlen(suffix); + return l1 >= l2 && spa_streq(s + l1 - l2, suffix); +} + +/** + * Convert \a str to an int32_t with the given \a base and store the + * result in \a val. + * + * On failure, the value of \a val is unmodified. + * + * \return true on success, false otherwise + */ +static inline bool spa_atoi32(const char *str, int32_t *val, int base) +{ + char *endptr; + long v; + + if (!str || *str =='\0') + return false; + + errno = 0; + v = strtol(str, &endptr, base); + if (errno != 0 || *endptr != '\0') + return false; + + if (v != (int32_t)v) + return false; + + *val = v; + return true; +} + +/** + * Convert \a str to an uint32_t with the given \a base and store the + * result in \a val. + * + * On failure, the value of \a val is unmodified. + * + * \return true on success, false otherwise + */ +static inline bool spa_atou32(const char *str, uint32_t *val, int base) +{ + char *endptr; + unsigned long long v; + + if (!str || *str =='\0') + return false; + + errno = 0; + v = strtoull(str, &endptr, base); + if (errno != 0 || *endptr != '\0') + return false; + + if (v != (uint32_t)v) + return false; + + *val = v; + return true; +} + +/** + * Convert \a str to an int64_t with the given \a base and store the + * result in \a val. + * + * On failure, the value of \a val is unmodified. + * + * \return true on success, false otherwise + */ +static inline bool spa_atoi64(const char *str, int64_t *val, int base) +{ + char *endptr; + long long v; + + if (!str || *str =='\0') + return false; + + errno = 0; + v = strtoll(str, &endptr, base); + if (errno != 0 || *endptr != '\0') + return false; + + *val = v; + return true; +} + +/** + * Convert \a str to an uint64_t with the given \a base and store the + * result in \a val. + * + * On failure, the value of \a val is unmodified. + * + * \return true on success, false otherwise + */ +static inline bool spa_atou64(const char *str, uint64_t *val, int base) +{ + char *endptr; + unsigned long long v; + + if (!str || *str =='\0') + return false; + + errno = 0; + v = strtoull(str, &endptr, base); + if (errno != 0 || *endptr != '\0') + return false; + + *val = v; + return true; +} + +/** + * Convert \a str to a boolean. Allowed boolean values are "true" and a + * literal "1", anything else is false. + * + * \return true on success, false otherwise + */ +static inline bool spa_atob(const char *str) +{ + return spa_streq(str, "true") || spa_streq(str, "1"); +} + +/** + * "Safe" version of vsnprintf. Exactly the same as vsnprintf but the + * returned value is clipped to `size - 1` and a negative or zero size + * will abort() the program. + * + * \return The number of bytes printed, capped to `size-1`, or a negative + * number on error. + */ +SPA_PRINTF_FUNC(3, 0) +static inline int spa_vscnprintf(char *buffer, size_t size, const char *format, va_list args) +{ + int r; + + spa_assert_se((ssize_t)size > 0); + + r = vsnprintf(buffer, size, format, args); + if (SPA_UNLIKELY(r < 0)) + buffer[0] = '\0'; + if (SPA_LIKELY(r < (ssize_t)size)) + return r; + return size - 1; +} + +/** + * "Safe" version of snprintf. Exactly the same as snprintf but the + * returned value is clipped to `size - 1` and a negative or zero size + * will abort() the program. + * + * \return The number of bytes printed, capped to `size-1`, or a negative + * number on error. + */ +SPA_PRINTF_FUNC(3, 4) +static inline int spa_scnprintf(char *buffer, size_t size, const char *format, ...) +{ + int r; + va_list args; + + va_start(args, format); + r = spa_vscnprintf(buffer, size, format, args); + va_end(args); + + return r; +} + +/** + * Convert \a str to a float in the C locale. + * + * If \a endptr is not NULL, a pointer to the character after the last character + * used in the conversion is stored in the location referenced by endptr. + * + * \return the result float. + */ +static inline float spa_strtof(const char *str, char **endptr) +{ +#ifndef __LOCALE_C_ONLY + static locale_t locale = NULL; + locale_t prev; +#endif + float v; +#ifndef __LOCALE_C_ONLY + if (SPA_UNLIKELY(locale == NULL)) + locale = newlocale(LC_ALL_MASK, "C", NULL); + prev = uselocale(locale); +#endif + v = strtof(str, endptr); +#ifndef __LOCALE_C_ONLY + uselocale(prev); +#endif + return v; +} + +/** + * Convert \a str to a float and store the result in \a val. + * + * On failure, the value of \a val is unmodified. + * + * \return true on success, false otherwise + */ +static inline bool spa_atof(const char *str, float *val) +{ + char *endptr; + float v; + + if (!str || *str =='\0') + return false; + errno = 0; + v = spa_strtof(str, &endptr); + if (errno != 0 || *endptr != '\0') + return false; + + *val = v; + return true; +} + +/** + * Convert \a str to a double in the C locale. + * + * If \a endptr is not NULL, a pointer to the character after the last character + * used in the conversion is stored in the location referenced by endptr. + * + * \return the result float. + */ +static inline double spa_strtod(const char *str, char **endptr) +{ +#ifndef __LOCALE_C_ONLY + static locale_t locale = NULL; + locale_t prev; +#endif + double v; +#ifndef __LOCALE_C_ONLY + if (SPA_UNLIKELY(locale == NULL)) + locale = newlocale(LC_ALL_MASK, "C", NULL); + prev = uselocale(locale); +#endif + v = strtod(str, endptr); +#ifndef __LOCALE_C_ONLY + uselocale(prev); +#endif + return v; +} + +/** + * Convert \a str to a double and store the result in \a val. + * + * On failure, the value of \a val is unmodified. + * + * \return true on success, false otherwise + */ +static inline bool spa_atod(const char *str, double *val) +{ + char *endptr; + double v; + + if (!str || *str =='\0') + return false; + + errno = 0; + v = spa_strtod(str, &endptr); + if (errno != 0 || *endptr != '\0') + return false; + + *val = v; + return true; +} + +static inline char *spa_dtoa(char *str, size_t size, double val) +{ + int i, l; + l = spa_scnprintf(str, size, "%f", val); + for (i = 0; i < l; i++) + if (str[i] == ',') + str[i] = '.'; + return str; +} + +struct spa_strbuf { + char *buffer; + size_t maxsize; + size_t pos; +}; + +static inline void spa_strbuf_init(struct spa_strbuf *buf, char *buffer, size_t maxsize) +{ + buf->buffer = buffer; + buf->maxsize = maxsize; + buf->pos = 0; +} + +SPA_PRINTF_FUNC(2, 3) +static inline int spa_strbuf_append(struct spa_strbuf *buf, const char *fmt, ...) +{ + size_t remain = buf->maxsize - buf->pos; + ssize_t written; + va_list args; + va_start(args, fmt); + written = vsnprintf(&buf->buffer[buf->pos], remain, fmt, args); + va_end(args); + if (written > 0) + buf->pos += SPA_MIN(remain, (size_t)written); + return written; +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_UTILS_STRING_H */ diff --git a/thirdparty/linuxbsd_headers/pipewire/spa/utils/type.h b/thirdparty/linuxbsd_headers/pipewire/spa/utils/type.h new file mode 100644 index 000000000000..65610c11e883 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pipewire/spa/utils/type.h @@ -0,0 +1,134 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_TYPE_H +#define SPA_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \defgroup spa_types Types + * Data type information enumerations + */ + +/** + * \addtogroup spa_types + * \{ + */ + +enum { + /* Basic types */ + SPA_TYPE_START = 0x00000, + SPA_TYPE_None, + SPA_TYPE_Bool, + SPA_TYPE_Id, + SPA_TYPE_Int, + SPA_TYPE_Long, + SPA_TYPE_Float, + SPA_TYPE_Double, + SPA_TYPE_String, + SPA_TYPE_Bytes, + SPA_TYPE_Rectangle, + SPA_TYPE_Fraction, + SPA_TYPE_Bitmap, + SPA_TYPE_Array, + SPA_TYPE_Struct, + SPA_TYPE_Object, + SPA_TYPE_Sequence, + SPA_TYPE_Pointer, + SPA_TYPE_Fd, + SPA_TYPE_Choice, + SPA_TYPE_Pod, + _SPA_TYPE_LAST, /**< not part of ABI */ + + /* Pointers */ + SPA_TYPE_POINTER_START = 0x10000, + SPA_TYPE_POINTER_Buffer, + SPA_TYPE_POINTER_Meta, + SPA_TYPE_POINTER_Dict, + _SPA_TYPE_POINTER_LAST, /**< not part of ABI */ + + /* Events */ + SPA_TYPE_EVENT_START = 0x20000, + SPA_TYPE_EVENT_Device, + SPA_TYPE_EVENT_Node, + _SPA_TYPE_EVENT_LAST, /**< not part of ABI */ + + /* Commands */ + SPA_TYPE_COMMAND_START = 0x30000, + SPA_TYPE_COMMAND_Device, + SPA_TYPE_COMMAND_Node, + _SPA_TYPE_COMMAND_LAST, /**< not part of ABI */ + + /* Objects */ + SPA_TYPE_OBJECT_START = 0x40000, + SPA_TYPE_OBJECT_PropInfo, + SPA_TYPE_OBJECT_Props, + SPA_TYPE_OBJECT_Format, + SPA_TYPE_OBJECT_ParamBuffers, + SPA_TYPE_OBJECT_ParamMeta, + SPA_TYPE_OBJECT_ParamIO, + SPA_TYPE_OBJECT_ParamProfile, + SPA_TYPE_OBJECT_ParamPortConfig, + SPA_TYPE_OBJECT_ParamRoute, + SPA_TYPE_OBJECT_Profiler, + SPA_TYPE_OBJECT_ParamLatency, + SPA_TYPE_OBJECT_ParamProcessLatency, + SPA_TYPE_OBJECT_ParamTag, + _SPA_TYPE_OBJECT_LAST, /**< not part of ABI */ + + /* vendor extensions */ + SPA_TYPE_VENDOR_PipeWire = 0x02000000, + + SPA_TYPE_VENDOR_Other = 0x7f000000, +}; + +#define SPA_TYPE_INFO_BASE "Spa:" + +#define SPA_TYPE_INFO_Flags SPA_TYPE_INFO_BASE "Flags" +#define SPA_TYPE_INFO_FLAGS_BASE SPA_TYPE_INFO_Flags ":" + +#define SPA_TYPE_INFO_Enum SPA_TYPE_INFO_BASE "Enum" +#define SPA_TYPE_INFO_ENUM_BASE SPA_TYPE_INFO_Enum ":" + +#define SPA_TYPE_INFO_Pod SPA_TYPE_INFO_BASE "Pod" +#define SPA_TYPE_INFO_POD_BASE SPA_TYPE_INFO_Pod ":" + +#define SPA_TYPE_INFO_Struct SPA_TYPE_INFO_POD_BASE "Struct" +#define SPA_TYPE_INFO_STRUCT_BASE SPA_TYPE_INFO_Struct ":" + +#define SPA_TYPE_INFO_Object SPA_TYPE_INFO_POD_BASE "Object" +#define SPA_TYPE_INFO_OBJECT_BASE SPA_TYPE_INFO_Object ":" + +#define SPA_TYPE_INFO_Pointer SPA_TYPE_INFO_BASE "Pointer" +#define SPA_TYPE_INFO_POINTER_BASE SPA_TYPE_INFO_Pointer ":" + +#define SPA_TYPE_INFO_Interface SPA_TYPE_INFO_POINTER_BASE "Interface" +#define SPA_TYPE_INFO_INTERFACE_BASE SPA_TYPE_INFO_Interface ":" + +#define SPA_TYPE_INFO_Event SPA_TYPE_INFO_OBJECT_BASE "Event" +#define SPA_TYPE_INFO_EVENT_BASE SPA_TYPE_INFO_Event ":" + +#define SPA_TYPE_INFO_Command SPA_TYPE_INFO_OBJECT_BASE "Command" +#define SPA_TYPE_INFO_COMMAND_BASE SPA_TYPE_INFO_Command ":" + +struct spa_type_info { + uint32_t type; + uint32_t parent; + const char *name; + const struct spa_type_info *values; +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_TYPE_H */