Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 16
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Sat Oct 15 16:39:17 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.59 + +------------------------------------------------------------------- Sun Sep 18 13:29:55 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.58
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.58 +Version: 0.3.59 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks-c.c
Deleted
@@ -1,37 +0,0 @@ -/* Spa - * - * Copyright © 2018 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <math.h> - -#include "resample-peaks-impl.h" - -static inline float find_abs_max_c(const float *s, uint32_t n_samples, float m) -{ - uint32_t n; - for (n = 0; n < n_samples; n++) - m = fmaxf(fabsf(sn), m); - return m; -} - -MAKE_PEAKS(c);
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks-impl.h
Deleted
@@ -1,92 +0,0 @@ -/* Spa - * - * Copyright © 2020 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <math.h> - -#include <spa/utils/defs.h> - -#include "resample.h" - -struct peaks_data { - uint32_t o_count; - uint32_t i_count; - float max_f; -}; - -#define DEFINE_PEAKS(arch) \ -void resample_peaks_process_##arch(struct resample *r, \ - const void * SPA_RESTRICT src, uint32_t *in_len, \ - void * SPA_RESTRICT dst, uint32_t *out_len) - -#define MAKE_PEAKS(arch) \ -DEFINE_PEAKS(arch) \ -{ \ - struct peaks_data *pd = r->data; \ - uint32_t c, i, o, end, chunk, i_count, o_count; \ - \ - if (SPA_UNLIKELY(r->channels == 0)) \ - return; \ - \ - for (c = 0; c < r->channels; c++) { \ - const float *s = srcc; \ - float *d = dstc, m = pd->max_fc; \ - \ - o_count = pd->o_count; \ - i_count = pd->i_count; \ - o = i = 0; \ - \ - while (i < *in_len && o < *out_len) { \ - end = ((uint64_t) (o_count + 1) \ - * r->i_rate) / r->o_rate; \ - end = end > i_count ? end - i_count : 0; \ - chunk = SPA_MIN(end, *in_len); \ - \ - m = find_abs_max_##arch(&si, chunk - i, m); \ - \ - i += chunk; \ - \ - if (i == end) { \ - do++ = m; \ - m = 0.0f; \ - o_count++; \ - } \ - } \ - pd->max_fc = m; \ - } \ - *out_len = o; \ - *in_len = i; \ - pd->o_count = o_count; \ - pd->i_count = i_count + i; \ - \ - while (pd->i_count >= r->i_rate) { \ - pd->i_count -= r->i_rate; \ - pd->o_count -= r->o_rate; \ - } \ -} - - -DEFINE_PEAKS(c); -#if defined (HAVE_SSE) -DEFINE_PEAKS(sse); -#endif
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks-sse.c
Deleted
@@ -1,64 +0,0 @@ -/* Spa - * - * Copyright © 2018 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <math.h> - -#include <xmmintrin.h> - -#include "resample-peaks-impl.h" - -static inline float hmax_ps(__m128 val) -{ - __m128 t = _mm_movehl_ps(val, val); - t = _mm_max_ps(t, val); - val = _mm_shuffle_ps(t, t, 0x55); - val = _mm_max_ss(t, val); - return _mm_cvtss_f32(val); -} - -static inline float find_abs_max_sse(const float *s, uint32_t n_samples, float m) -{ - __m128 in2, max; - uint32_t n, unrolled; - const __m128 mask = _mm_set1_ps(-0.0f); - - max = _mm_set1_ps(m); - - unrolled = n_samples & ~7; - - for (n = 0; n < unrolled; n += 8) { - in0 = _mm_loadu_ps(&sn + 0); - in1 = _mm_loadu_ps(&sn + 4); - in0 = _mm_andnot_ps(mask, in0); - in1 = _mm_andnot_ps(mask, in1); - max = _mm_max_ps(max, in0); - max = _mm_max_ps(max, in1); - } - for (; n < n_samples; n++) - m = fmaxf(fabsf(sn), m); - - return fmaxf(hmax_ps(max), m); -} - -MAKE_PEAKS(sse);
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codecs.c
Deleted
@@ -1,209 +0,0 @@ -/* - * BlueALSA - bluez-a2dp.c - * Copyright (c) 2016-2017 Arkadiusz Bokowy - * - * This file is a part of bluez-alsa. - * - * This project is licensed under the terms of the MIT license. - * - */ - -#include <spa/utils/string.h> - -#include "a2dp-codecs.h" - -int a2dp_codec_select_config(const struct a2dp_codec_config configs, size_t n, - uint32_t cap, int preferred_value) -{ - size_t i; - int *scores, res; - unsigned int max_priority; - - if (n == 0) - return -EINVAL; - - scores = calloc(n, sizeof(int)); - if (scores == NULL) - return -errno; - - max_priority = configs0.priority; - for (i = 1; i < n; ++i) { - if (configsi.priority > max_priority) - max_priority = configsi.priority; - } - - for (i = 0; i < n; ++i) { - if (!(configsi.config & cap)) { - scoresi = -1; - continue; - } - if (configsi.value == preferred_value) - scoresi = 100 * (max_priority + 1); - else if (configsi.value > preferred_value) - scoresi = 10 * (max_priority + 1); - else - scoresi = 1; - - scoresi *= configsi.priority + 1; - } - - res = 0; - for (i = 1; i < n; ++i) { - if (scoresi > scoresres) - res = i; - } - - if (scoresres < 0) - res = -EINVAL; - - free(scores); - return res; -} - -bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id, - const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, - const struct spa_dict *global_settings) -{ - uint8_t configA2DP_MAX_CAPS_SIZE; - int res; - - if (codec_id != codec->codec_id) - return false; - - if (caps == NULL) - return false; - - res = codec->select_config(codec, 0, caps, caps_size, info, global_settings, config); - if (res < 0) - return false; - - return ((size_t)res == caps_size); -} - -#ifdef CODEC_PLUGIN - -struct impl { - struct spa_handle handle; - struct spa_bluez5_codec_a2dp bluez5_codec_a2dp; -}; - -static int -impl_get_interface(struct spa_handle *handle, const char *type, void **interface) -{ - struct impl *this; - - spa_return_val_if_fail(handle != NULL, -EINVAL); - spa_return_val_if_fail(interface != NULL, -EINVAL); - - this = (struct impl *) handle; - - if (spa_streq(type, SPA_TYPE_INTERFACE_Bluez5CodecA2DP)) - *interface = &this->bluez5_codec_a2dp; - else - return -ENOENT; - - return 0; -} - -static int -impl_clear(struct spa_handle *handle) -{ - spa_return_val_if_fail(handle != NULL, -EINVAL); - return 0; -} - -static size_t -impl_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params) -{ - return sizeof(struct impl); -} - -static int -impl_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) -{ - struct impl *this; - - spa_return_val_if_fail(factory != NULL, -EINVAL); - spa_return_val_if_fail(handle != NULL, -EINVAL); - - handle->get_interface = impl_get_interface; - handle->clear = impl_clear; - - this = (struct impl *) handle; - - this->bluez5_codec_a2dp.codecs = codec_plugin_a2dp_codecs; - this->bluez5_codec_a2dp.iface = SPA_INTERFACE_INIT( - SPA_TYPE_INTERFACE_Bluez5CodecA2DP, - SPA_VERSION_BLUEZ5_CODEC_A2DP, - NULL, - this); - - return 0; -} - -static const struct spa_interface_info impl_interfaces = { - {SPA_TYPE_INTERFACE_Bluez5CodecA2DP,}, -}; - -static int -impl_enum_interface_info(const struct spa_handle_factory *factory, - const struct spa_interface_info **info, - uint32_t *index) -{ - spa_return_val_if_fail(factory != NULL, -EINVAL); - spa_return_val_if_fail(info != NULL, -EINVAL); - spa_return_val_if_fail(index != NULL, -EINVAL); - - switch (*index) { - case 0: - *info = &impl_interfaces*index; - break; - default: - return 0; - } - (*index)++; - - return 1; -} - -static const struct spa_dict_item handle_info_items = { - { SPA_KEY_FACTORY_DESCRIPTION, "Bluetooth codec plugin" }, -}; - -static const struct spa_dict handle_info = SPA_DICT_INIT_ARRAY(handle_info_items); - -static struct spa_handle_factory handle_factory = { - SPA_VERSION_HANDLE_FACTORY, - NULL, - &handle_info, - impl_get_size, - impl_init, - impl_enum_interface_info, -}; - -SPA_EXPORT -int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) -{ - spa_return_val_if_fail(factory != NULL, -EINVAL); - spa_return_val_if_fail(index != NULL, -EINVAL); - - if (handle_factory.name == NULL) - handle_factory.name = codec_plugin_factory_name; - - switch (*index) { - case 0:
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codecs.h
Deleted
@@ -1,167 +0,0 @@ -/* Spa A2DP codec API - * - * Copyright © 2020 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#ifndef SPA_BLUEZ5_A2DP_CODECS_H_ -#define SPA_BLUEZ5_A2DP_CODECS_H_ - -#include <stdint.h> -#include <stddef.h> - -#include <spa/param/audio/format.h> -#include <spa/param/bluetooth/audio.h> -#include <spa/utils/names.h> -#include <spa/support/plugin.h> -#include <spa/pod/pod.h> -#include <spa/pod/builder.h> -#include <spa/support/log.h> - -#include "a2dp-codec-caps.h" - -/* - * The codec plugin SPA interface is private. The version should be incremented - * when any of the structs or semantics change. - */ - -#define SPA_TYPE_INTERFACE_Bluez5CodecA2DP SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:A2DP:Private" - -#define SPA_VERSION_BLUEZ5_CODEC_A2DP 5 - -struct spa_bluez5_codec_a2dp { - struct spa_interface iface; - const struct a2dp_codec * const *codecs; /**< NULL terminated array */ -}; - -#define A2DP_CODEC_FACTORY_NAME(basename) (SPA_NAME_API_CODEC_BLUEZ5_A2DP "." basename) - -#ifdef CODEC_PLUGIN -#define A2DP_CODEC_EXPORT_DEF(basename,...) \ - const char *codec_plugin_factory_name = A2DP_CODEC_FACTORY_NAME(basename); \ - static const struct a2dp_codec * const codec_plugin_a2dp_codec_list = { __VA_ARGS__, NULL }; \ - const struct a2dp_codec * const * const codec_plugin_a2dp_codecs = codec_plugin_a2dp_codec_list; - -extern const struct a2dp_codec * const * const codec_plugin_a2dp_codecs; -extern const char *codec_plugin_factory_name; -#endif - -#define A2DP_CODEC_FLAG_SINK (1 << 0) - -#define A2DP_CODEC_DEFAULT_RATE 48000 -#define A2DP_CODEC_DEFAULT_CHANNELS 2 - -enum { - NEED_FLUSH_NO = 0, - NEED_FLUSH_ALL = 1, - NEED_FLUSH_FRAGMENT = 2, -}; - -struct a2dp_codec_audio_info { - uint32_t rate; - uint32_t channels; -}; - -struct a2dp_codec { - enum spa_bluetooth_audio_codec id; - uint8_t codec_id; - a2dp_vendor_codec_t vendor; - - const char *name; - const char *description; - const char *endpoint_name; /**< Endpoint name. If NULL, same as name */ - const struct spa_dict *info; - - const size_t send_buf_size; - - const struct a2dp_codec *duplex_codec; /**< Codec for non-standard A2DP duplex channel */ - - int (*fill_caps) (const struct a2dp_codec *codec, uint32_t flags, - uint8_t capsA2DP_MAX_CAPS_SIZE); - int (*select_config) (const struct a2dp_codec *codec, uint32_t flags, - const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, - const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE); - int (*enum_config) (const struct a2dp_codec *codec, uint32_t flags, - const void *caps, size_t caps_size, uint32_t id, uint32_t idx, - struct spa_pod_builder *builder, struct spa_pod **param); - int (*validate_config) (const struct a2dp_codec *codec, uint32_t flags, - const void *caps, size_t caps_size, - struct spa_audio_info *info); - - /** qsort comparison sorting caps in order of preference for the codec. - * Used in codec switching to select best remote endpoints. - * The caps handed in correspond to this codec_id, but are - * otherwise not checked beforehand. - */ - int (*caps_preference_cmp) (const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, - const struct spa_dict *global_settings); - - void *(*init_props) (const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings); - void (*clear_props) (void *); - int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx, - struct spa_pod_builder *builder, struct spa_pod **param); - int (*set_props) (void *props, const struct spa_pod *param); - - void *(*init) (const struct a2dp_codec *codec, uint32_t flags, void *config, size_t config_size, - const struct spa_audio_info *info, void *props, size_t mtu); - void (*deinit) (void *data); - - int (*update_props) (void *data, void *props); - - int (*get_block_size) (void *data); - - int (*abr_process) (void *data, size_t unsent); - - int (*start_encode) (void *data, - void *dst, size_t dst_size, uint16_t seqnum, uint32_t timestamp); - int (*encode) (void *data, - const void *src, size_t src_size, - void *dst, size_t dst_size, - size_t *dst_out, int *need_flush); - - int (*start_decode) (void *data, - const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp); - int (*decode) (void *data, - const void *src, size_t src_size, - void *dst, size_t dst_size, - size_t *dst_out); - - int (*reduce_bitpool) (void *data); - int (*increase_bitpool) (void *data); - - void (*set_log) (struct spa_log *global_log); -}; - -struct a2dp_codec_config { - uint32_t config; - int value; - unsigned int priority; -}; - -int a2dp_codec_select_config(const struct a2dp_codec_config configs, size_t n, - uint32_t cap, int preferred_value); - -bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id, - const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info, - const struct spa_dict *global_settings); - -#endif
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-sink.c
Deleted
@@ -1,1786 +0,0 @@ -/* Spa A2DP Sink - * - * Copyright © 2018 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <unistd.h> -#include <stddef.h> -#include <stdio.h> -#include <arpa/inet.h> -#include <sys/ioctl.h> - -#include <spa/support/plugin.h> -#include <spa/support/loop.h> -#include <spa/support/log.h> -#include <spa/support/system.h> -#include <spa/utils/list.h> -#include <spa/utils/keys.h> -#include <spa/utils/names.h> -#include <spa/utils/result.h> -#include <spa/utils/string.h> -#include <spa/monitor/device.h> - -#include <spa/node/node.h> -#include <spa/node/utils.h> -#include <spa/node/io.h> -#include <spa/node/keys.h> -#include <spa/param/param.h> -#include <spa/param/latency-utils.h> -#include <spa/param/audio/format.h> -#include <spa/param/audio/format-utils.h> -#include <spa/pod/filter.h> - -#include <sbc/sbc.h> - -#include "defs.h" -#include "rtp.h" -#include "a2dp-codecs.h" - -static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.sink.a2dp"); -#undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT &log_topic - -#define DEFAULT_CLOCK_NAME "clock.system.monotonic" - -struct props { - uint32_t min_latency; - uint32_t max_latency; - int64_t latency_offset; - char clock_name64; -}; - -#define FILL_FRAMES 2 -#define MAX_BUFFERS 32 -#define MIN_LATENCY 128 -#define MAX_LATENCY 8192 -#define BUFFER_SIZE (MAX_LATENCY*8) - -struct buffer { - uint32_t id; -#define BUFFER_FLAG_OUT (1<<0) - uint32_t flags; - struct spa_buffer *buf; - struct spa_meta_header *h; - struct spa_list link; -}; - -struct port { - struct spa_audio_info current_format; - uint32_t frame_size; - unsigned int have_format:1; - - uint64_t info_all; - struct spa_port_info info; - struct spa_io_buffers *io; - struct spa_latency_info latency; -#define IDX_EnumFormat 0 -#define IDX_Meta 1 -#define IDX_IO 2 -#define IDX_Format 3 -#define IDX_Buffers 4 -#define IDX_Latency 5 -#define N_PORT_PARAMS 6 - struct spa_param_info paramsN_PORT_PARAMS; - - struct buffer buffersMAX_BUFFERS; - uint32_t n_buffers; - - struct spa_list free; - struct spa_list ready; - - size_t ready_offset; -}; - -struct impl { - struct spa_handle handle; - struct spa_node node; - - struct spa_log *log; - struct spa_loop *data_loop; - struct spa_system *data_system; - - struct spa_hook_list hooks; - struct spa_callbacks callbacks; - - uint64_t info_all; - struct spa_node_info info; -#define IDX_PropInfo 0 -#define IDX_Props 1 -#define N_NODE_PARAMS 2 - struct spa_param_info paramsN_NODE_PARAMS; - struct props props; - - struct spa_bt_transport *transport; - struct spa_hook transport_listener; - - struct port port; - - unsigned int started:1; - unsigned int following:1; - - unsigned int is_duplex:1; - - struct spa_source source; - int timerfd; - struct spa_source flush_source; - struct spa_source flush_timer_source; - int flush_timerfd; - - struct spa_io_clock *clock; - struct spa_io_position *position; - - uint64_t current_time; - uint64_t next_time; - uint64_t last_error; - - const struct a2dp_codec *codec; - bool codec_props_changed; - void *codec_props; - void *codec_data; - struct spa_audio_info codec_format; - - int need_flush; - bool fragment; - uint64_t fragment_timeout; - uint32_t block_size; - uint8_t bufferBUFFER_SIZE; - uint32_t buffer_used; - uint32_t header_size; - uint32_t frame_count; - uint16_t seqnum; - uint32_t timestamp; - uint64_t sample_count; - uint8_t tmp_bufferBUFFER_SIZE; - uint32_t tmp_buffer_used; - uint32_t fd_buffer_size; -}; - -#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) - -static void reset_props(struct impl *this, struct props *props) -{ - props->min_latency = MIN_LATENCY; - props->max_latency = MAX_LATENCY; - props->latency_offset = 0; - strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name)); -} - -static int impl_node_enum_params(void *object, int seq, - uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter) -{ - struct impl *this = object; - struct spa_pod *param; - struct spa_pod_builder b = { 0 }; - uint8_t buffer1024; - struct spa_result_node_params result; - uint32_t count = 0, index_offset = 0; - bool enum_codec = false; - - spa_return_val_if_fail(this != NULL, -EINVAL);
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-source.c
Deleted
@@ -1,1643 +0,0 @@ -/* Spa A2DP Source - * - * Copyright © 2018 Wim Taymans - * Copyright © 2019 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <unistd.h> -#include <stddef.h> -#include <stdio.h> -#include <time.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <spa/support/plugin.h> -#include <spa/support/loop.h> -#include <spa/support/log.h> -#include <spa/support/system.h> -#include <spa/utils/list.h> -#include <spa/utils/keys.h> -#include <spa/utils/names.h> -#include <spa/utils/result.h> -#include <spa/utils/string.h> -#include <spa/monitor/device.h> - -#include <spa/node/node.h> -#include <spa/node/utils.h> -#include <spa/node/io.h> -#include <spa/node/keys.h> -#include <spa/param/param.h> -#include <spa/param/latency-utils.h> -#include <spa/param/audio/format.h> -#include <spa/param/audio/format-utils.h> -#include <spa/pod/filter.h> - -#include "defs.h" -#include "rtp.h" -#include "a2dp-codecs.h" - -static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.source.a2dp"); -#undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT &log_topic - -#include "decode-buffer.h" - -#define DEFAULT_CLOCK_NAME "clock.system.monotonic" - -struct props { - char clock_name64; -}; - -#define FILL_FRAMES 2 -#define MAX_BUFFERS 32 - -struct buffer { - uint32_t id; - unsigned int outstanding:1; - struct spa_buffer *buf; - struct spa_meta_header *h; - struct spa_list link; -}; - -struct port { - struct spa_audio_info current_format; - uint32_t frame_size; - unsigned int have_format:1; - - uint64_t info_all; - struct spa_port_info info; - struct spa_io_buffers *io; - struct spa_io_rate_match *rate_match; - struct spa_latency_info latency; -#define IDX_EnumFormat 0 -#define IDX_Meta 1 -#define IDX_IO 2 -#define IDX_Format 3 -#define IDX_Buffers 4 -#define IDX_Latency 5 -#define N_PORT_PARAMS 6 - struct spa_param_info paramsN_PORT_PARAMS; - - struct buffer buffersMAX_BUFFERS; - uint32_t n_buffers; - - struct spa_list free; - struct spa_list ready; - - struct spa_bt_decode_buffer buffer; -}; - -struct impl { - struct spa_handle handle; - struct spa_node node; - - struct spa_log *log; - struct spa_loop *data_loop; - struct spa_system *data_system; - - struct spa_hook_list hooks; - struct spa_callbacks callbacks; - - uint32_t quantum_limit; - - uint64_t info_all; - struct spa_node_info info; -#define IDX_PropInfo 0 -#define IDX_Props 1 -#define IDX_NODE_IO 2 -#define N_NODE_PARAMS 3 - struct spa_param_info paramsN_NODE_PARAMS; - struct props props; - - struct spa_bt_transport *transport; - struct spa_hook transport_listener; - - struct port port; - - unsigned int started:1; - unsigned int transport_acquired:1; - unsigned int following:1; - unsigned int matching:1; - unsigned int resampling:1; - - unsigned int is_input:1; - unsigned int is_duplex:1; - unsigned int use_duplex_source:1; - - int fd; - struct spa_source source; - - struct spa_source timer_source; - int timerfd; - - struct spa_io_clock *clock; - struct spa_io_position *position; - - uint64_t current_time; - uint64_t next_time; - - const struct a2dp_codec *codec; - bool codec_props_changed; - void *codec_props; - void *codec_data; - struct spa_audio_info codec_format; - - uint8_t buffer_read4096; - struct timespec now; - uint64_t sample_count; - - int duplex_timerfd; - uint64_t duplex_timeout; -}; - -#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) - -static void reset_props(struct props *props) -{ - strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name)); -} - -static int impl_node_enum_params(void *object, int seq, - uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter) -{ - struct impl *this = object; - struct spa_pod *param; - struct spa_pod_builder b = { 0 }; - uint8_t buffer1024; - struct spa_result_node_params result; - uint32_t count = 0, index_offset = 0; - bool enum_codec = false; - - spa_return_val_if_fail(this != NULL, -EINVAL); - spa_return_val_if_fail(num != 0, -EINVAL); - - result.id = id; - result.next = start; - next: - result.index = result.next++; -
View file
pipewire-0.3.58.tar.gz/.gitlab-ci.yml -> pipewire-0.3.59.tar.gz/.gitlab-ci.yml
Changed
@@ -268,9 +268,9 @@ extends: - .build_on_fedora variables: - # Fedora doesn't have libfreeaptx, lc3plus, or roc + # Fedora doesn't have libfreeaptx, lc3plus, lc3, or roc # libcamera has no stable API, so let's not chase that target - MESON_OPTIONS: "-Dauto_features=enabled -Dbluez5-codec-aptx=disabled -Dbluez5-codec-lc3plus=disabled -Droc=disabled -Dlibcamera=disabled" + MESON_OPTIONS: "-Dauto_features=enabled -Dbluez5-codec-aptx=disabled -Dbluez5-codec-lc3plus=disabled -Dbluez5-codec-lc3=disabled -Droc=disabled -Dlibcamera=disabled" parallel: matrix: - CC: gcc, clang
View file
pipewire-0.3.58.tar.gz/NEWS -> pipewire-0.3.59.tar.gz/NEWS
Changed
@@ -1,3 +1,80 @@ +# PipeWire 0.3.59 (2022-09-30) + +This is a bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + - Fix possible wrong samplerate in loopback streams after suspend and + rate switch. + - module-filter-chain can now adapt to the graph samplerate. + - Fix some potential stuttering and crackling in pulse-server. + - Add Bluetooth LE support. This requires experimental kernel and bluez + support. + - The ALSA plugin has more options to control the buffer size. This can + be used to work around high latency in davinci resolve. + - Many bugfixes and improvements. + + +## PipeWire + - Add audio capture example with volume meter. + - Fix a case where a rate switch would not suspend all the nodes of the + driver first. This could cause wrong samplerates in streams. + - Fix a case where a node would be Paused while still added to the + graph, causing potential crashes. (#2701) + +## Modules + - module-filter-chain and module-loopback now use the resample.prefill + option to avoid buffering extra samples and causing unwanted latency + when resampling is activated. + - module-filter-chain can now adapt to the graph samplerate. + - Improve module-raop to support the ALAC codec as raw PCM. + - Improve RTSP parsing to improve compatibility. + +## Tools + - Fix 100% CPU in pw-cli monitor mode. (#2709) + - spa-acp-tool can now be exited with ctrl-D. + +## SPA + - Various libcamera fixes and improvements. + - Set stride on audioconvert output buffers. + - Make sure we always place the last requested size from the resampler + on the buffers in pw-stream. + - Add resample.prefill option in the resampler to fill the history with + 0 so that we don't have smaller buffers at the start. + - Make sure that when an overflow corrupts a POD, that it will always + stay corrupted. + - Rate limit some ALSA warnings and reduce some unwanted warnings. + - Don't recalculate the audioconverter state for each pause/play. (#2701) + - Fix some POD parsing inconsistencies and potential overflows. + - Add support for Asus Xonar SE. + - Fix Flush command handling. It should not stop playback. (#2726) + - Refactor the peaks function and add some unit tests and optimizations. + - The channelmix has an optimized nXm converter and new unit tests. + - Normalization in the channelmixer was fixed. + +## pulse-server + - The requested latency of record streams was reduced to fix some + stuttering in Teamspeak. (#2702) + - Tweak the max amount of bytes sent to a client. (#2711) (#2715) + - Improve maxlength calculations, this fixes some crackling noise with + high samplerate and channel counts in some players (audacious). + +## Bluetooth + - Merge Bluetooth LE support. + - Make sure we are backward compatible with WirePlumber. + - Fix some HFP and HSP AT command parsing. (#2463) + - Use HFP by default over HSP. + +## ALSA + - Increase max number of periods. + - The parameters handling was improved. There is now an option to set the + buffer-bytes of the ALSA plugin. + - PIPEWIRE_ALSA can now be used as an environment variable to restrict the + plugin formats and buffer size. + +Older versions: + + # PipeWire 0.3.58 (2022-09-15) This is a bugfix release that is API and ABI compatible with previous @@ -64,9 +141,6 @@ wakeups. (#1697) -Older versions: - - # PipeWire 0.3.57 (2022-09-02) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.58.tar.gz/man/pipewire.1.rst.in -> pipewire-0.3.59.tar.gz/man/pipewire.1.rst.in
Changed
@@ -47,6 +47,8 @@ SEE ALSO ======== +``pw-top(1)``, +``pw-dump(1)``, ``pw-mon(1)``, ``pw-cat(1)``, ``pw-cli(1)``,
View file
pipewire-0.3.58.tar.gz/man/pw-profiler.1.rst.in -> pipewire-0.3.59.tar.gz/man/pw-profiler.1.rst.in
Changed
@@ -27,6 +27,8 @@ SVG files from the .plot files is generated, along with a .html file to visualize the profiling results in a browser. +This function uses the same data used by *pw-top*. + OPTIONS ======= @@ -52,3 +54,4 @@ ======== ``pipewire(1)``, +``pw-top(1)``,
View file
pipewire-0.3.58.tar.gz/man/pw-top.1.rst.in -> pipewire-0.3.59.tar.gz/man/pw-top.1.rst.in
Changed
@@ -168,4 +168,7 @@ ======== ``pipewire(1)``, +``pw-dump(1)``, +``pw-cli(1)``, +``pw-profiler(1)``,
View file
pipewire-0.3.58.tar.gz/meson.build -> pipewire-0.3.59.tar.gz/meson.build
Changed
@@ -1,9 +1,9 @@ project('pipewire', 'c' , - version : '0.3.58', + version : '0.3.59', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.59.0', default_options : 'warning_level=3', - 'c_std=gnu99', + 'c_std=gnu11', 'cpp_std=c++17', 'b_pie=true', #'b_sanitize=address,undefined',
View file
pipewire-0.3.58.tar.gz/meson_options.txt -> pipewire-0.3.59.tar.gz/meson_options.txt
Changed
@@ -120,6 +120,10 @@ description: 'Enable Opus open source codec implementation', type: 'feature', value: 'auto') +option('bluez5-codec-lc3', + description: 'Enable LC3 open source codec implementation', + type: 'feature', + value: 'disabled') option('control', description: 'Enable control spa plugin integration', type: 'feature',
View file
pipewire-0.3.58.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.59.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -64,6 +64,26 @@ #define MIN_PERIOD 64 +#define MIN_PERIOD_BYTES (128) +#define MAX_PERIOD_BYTES (2*1024*1024) + +#define MIN_BUFFER_BYTES (2*MIN_PERIOD_BYTES) +#define MAX_BUFFER_BYTES (2*MAX_PERIOD_BYTES) + +struct params { + const char *node_name; + const char *server_name; + const char *playback_node; + const char *capture_node; + const char *role; + snd_pcm_format_t format; + int rate; + int channels; + int period_bytes; + int buffer_bytes; + uint32_t flags; +}; + typedef struct { snd_pcm_ioplug_t io; @@ -178,6 +198,7 @@ pw_thread_loop_destroy(pw->main_loop); free(pw->node_name); free(pw->target); + free(pw->role); snd_output_close(pw->output); fclose(pw->log_file); free(pw); @@ -942,8 +963,7 @@ .query_chmaps = snd_pcm_pipewire_query_chmaps, }; -static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw, int rate, - snd_pcm_format_t format, int channels, int period_bytes) +static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw, struct params *p) { unsigned int access_list = { SND_PCM_ACCESS_MMAP_INTERLEAVED, @@ -975,26 +995,38 @@ int max_channels; int min_period_bytes; int max_period_bytes; + int min_buffer_bytes; + int max_buffer_bytes; int err; - if (rate > 0) { - min_rate = max_rate = rate; + if (p->rate > 0) { + min_rate = max_rate = SPA_CLAMP(p->rate, 1, MAX_RATE); } else { min_rate = 1; max_rate = MAX_RATE; } - if (channels > 0) { - min_channels = max_channels = channels; + if (p->channels > 0) { + min_channels = max_channels = SPA_CLAMP(p->channels, 1, MAX_CHANNELS); } else { min_channels = 1; max_channels = MAX_CHANNELS; } - if (period_bytes > 0) { - min_period_bytes = max_period_bytes = period_bytes; + if (p->period_bytes > 0) { + min_period_bytes = max_period_bytes = SPA_CLAMP(p->period_bytes, + MIN_PERIOD_BYTES, MAX_PERIOD_BYTES); } else { - min_period_bytes = 128; - max_period_bytes = 2*1024*1024; + min_period_bytes = MIN_PERIOD_BYTES; + max_period_bytes = MAX_PERIOD_BYTES; } + if (p->buffer_bytes > 0) { + min_buffer_bytes = max_buffer_bytes = SPA_CLAMP(p->buffer_bytes, + MIN_BUFFER_BYTES, MAX_BUFFER_BYTES); + } else { + min_buffer_bytes = MIN_BUFFER_BYTES; + max_buffer_bytes = MAX_BUFFER_BYTES; + } + if (min_period_bytes * 2 > max_buffer_bytes) + min_period_bytes = max_period_bytes = max_buffer_bytes / 2; if ((err = snd_pcm_ioplug_set_param_list(&pw->io, SND_PCM_IOPLUG_HW_ACCESS, SPA_N_ELEMENTS(access_list), access_list)) < 0 || @@ -1003,22 +1035,22 @@ (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_RATE, min_rate, max_rate)) < 0 || (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, - MIN_BUFFERS*min_period_bytes, - MIN_BUFFERS*max_period_bytes)) < 0 || + min_buffer_bytes, + max_buffer_bytes)) < 0 || (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, min_period_bytes, max_period_bytes)) < 0 || (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_PERIODS, - MIN_BUFFERS, MAX_BUFFERS)) < 0) { + MIN_BUFFERS, 1024)) < 0) { pw_log_warn("Can't set param list: %s", snd_strerror(err)); return err; } - if (format != SND_PCM_FORMAT_UNKNOWN) { + if (p->format != SND_PCM_FORMAT_UNKNOWN) { err = snd_pcm_ioplug_set_param_list(&pw->io, SND_PCM_IOPLUG_HW_FORMAT, - 1, (unsigned int *)&format); + 1, (unsigned int *)&p->format); if (err < 0) { pw_log_warn("Can't set param list: %s", snd_strerror(err)); return err; @@ -1075,60 +1107,77 @@ .write = log_write, }; -static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, - const char *node_name, - const char *server_name, - const char *playback_node, - const char *capture_node, - const char *role, - snd_pcm_stream_t stream, - int mode, - uint32_t flags, - int rate, - snd_pcm_format_t format, - int channels, - int period_bytes) +static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, + struct params *p, snd_pcm_stream_t stream, int mode) { snd_pcm_pipewire_t *pw; int err; const char *str; struct pw_properties *props = NULL; struct pw_loop *loop; + uint32_t val; assert(pcmp); pw = calloc(1, sizeof(*pw)); if (!pw) return -ENOMEM; + props = pw_properties_new(NULL, NULL); + if (props == NULL) { + err = -errno; + goto error; + } + + str = getenv("PIPEWIRE_ALSA"); + if (str != NULL) { + pw_properties_update_string(props, str, strlen(str)); + if ((str = pw_properties_get(props, "alsa.format"))) + p->format = snd_pcm_format_value(str); + if ((str = pw_properties_get(props, "alsa.rate")) && + spa_atou32(str, &val, 0)) + p->rate = val; + if ((str = pw_properties_get(props, "alsa.channels")) && + spa_atou32(str, &val, 0)) + p->channels = val; + if ((str = pw_properties_get(props, "alsa.period-bytes")) && + spa_atou32(str, &val, 0)) + p->period_bytes = val; + if ((str = pw_properties_get(props, "alsa.buffer-bytes")) && + spa_atou32(str, &val, 0)) + p->buffer_bytes = val; + } + str = getenv("PIPEWIRE_REMOTE"); if (str != NULL && str0 != '\0') - server_name = str; + p->server_name = str; str = getenv("PIPEWIRE_NODE"); pw_log_debug("%p: open name:%s stream:%s mode:%d flags:%08x rate:%d format:%s " - "channels:%d period-bytes:%d target:'%s'", pw, name, - snd_pcm_stream_name(stream), mode, flags, rate, - snd_pcm_format_name(format), channels, period_bytes, str); + "channels:%d period-bytes:%d buffer-bytes:%d target:'%s'", pw, p->node_name, + snd_pcm_stream_name(stream), mode, p->flags, p->rate, + snd_pcm_format_name(p->format), p->channels, p->period_bytes, + p->buffer_bytes, str); pw->fd = -1; pw->io.poll_fd = -1; - pw->flags = flags; + pw->flags = p->flags; pw->log_file = fopencookie(pw, "w", io_funcs); if (pw->log_file == NULL) { pw_log_error("can't create log file: %m");
View file
pipewire-0.3.58.tar.gz/pipewire-alsa/conf/50-pipewire.conf -> pipewire-0.3.59.tar.gz/pipewire-alsa/conf/50-pipewire.conf
Changed
@@ -4,9 +4,14 @@ defaults.pipewire.node "-1" defaults.pipewire.exclusive false defaults.pipewire.role "" +defaults.pipewire.rate 0 +defaults.pipewire.format "" +defaults.pipewire.channels 0 +defaults.pipewire.period_bytes 0 +defaults.pipewire.buffer_bytes 0 pcm.pipewire { - @args SERVER NODE EXCLUSIVE ROLE + @args SERVER NODE EXCLUSIVE ROLE RATE FORMAT CHANNELS PERIOD_BYTES BUFFER_BYTES @args.SERVER { type string default { @@ -35,7 +40,41 @@ name defaults.pipewire.role } } - + @args.RATE { + type integer + default { + @func refer + name defaults.pipewire.rate + } + } + @args.FORMAT { + type string + default { + @func refer + name defaults.pipewire.format + } + } + @args.CHANNELS { + type integer + default { + @func refer + name defaults.pipewire.channels + } + } + @args.PERIOD_BYTES { + type integer + default { + @func refer + name defaults.pipewire.period_bytes + } + } + @args.BUFFER_BYTES { + type integer + default { + @func refer + name defaults.pipewire.buffer_bytes + } + } type pipewire server $SERVER @@ -43,6 +82,11 @@ capture_node $NODE exclusive $EXCLUSIVE role $ROLE + rate $RATE + format $FORMAT + channels $CHANNELS + period_bytes $PERIOD_BYTES + buffer_bytes $BUFFER_BYTES hint { show on description "PipeWire Sound Server"
View file
pipewire-0.3.58.tar.gz/pipewire-jack/src/pipewire-jack-extensions.h -> pipewire-0.3.59.tar.gz/pipewire-jack/src/pipewire-jack-extensions.h
Changed
@@ -24,6 +24,7 @@ #ifndef PIPEWIRE_JACK_EXTENSIONS_H #define PIPEWIRE_JACK_EXTENSIONS_H +#include <stdint.h> #ifdef __cplusplus extern "C" {
View file
pipewire-0.3.58.tar.gz/po/hu.po -> pipewire-0.3.59.tar.gz/po/hu.po
Changed
@@ -1,18 +1,18 @@ -# Hungarian translation of PipeWire -# Copyright (C) 2012, 2016. Free Software Foundation, Inc. +# Hungarian translation for PipeWire. +# Copyright (C) 2012, 2016, 2022. Free Software Foundation, Inc. # This file is distributed under the same license as the PipeWire package. # -# KAMI <kami911@gmail.com>, 2012. +# KAMI <kami911 at gmail dot com>, 2012. # Gabor Kelemen <kelemeng at ubuntu dot com>, 2016. -# Balázs Úr <urbalazs at gmail dot com>, 2016. +# Balázs Úr <ur.balazs at fsf dot hu>, 2016, 2022. msgid "" msgstr "" "Project-Id-Version: PipeWire master\n" -"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/" -"issues/new\n" -"POT-Creation-Date: 2021-04-18 16:54+0800\n" -"PO-Revision-Date: 2020-07-21 15:29+0000\n" -"Last-Translator: Balázs Meskó <meskobalazs@mailbox.org>\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" +"issues\n" +"POT-Creation-Date: 2022-09-15 15:26+0000\n" +"PO-Revision-Date: 2022-09-21 22:35+0200\n" +"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n" "Language-Team: Hungarian <https://translate.fedoraproject.org/projects/" "pipewire/pipewire/hu/>\n" "Language: hu\n" @@ -20,12 +20,9 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.1.1\n" -"X-Poedit-Language: Hungarian\n" -"X-Poedit-Country: HUNGARY\n" -"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Lokalize 19.12.3\n" -#: src/daemon/pipewire.c:43 +#: src/daemon/pipewire.c:46 #, c-format msgid "" "%s options\n" @@ -33,40 +30,64 @@ " --version Show version\n" " -c, --config Load config (Default %s)\n" msgstr "" +"%s kapcsolók\n" +" -h, --help Ezen súgó megjelenítése\n" +" --version Verzió megjelenítése\n" +" -c, --config Beállítás betöltése (alapérték: %s)\n" #: src/daemon/pipewire.desktop.in:4 msgid "PipeWire Media System" -msgstr "" +msgstr "PipeWire médiarendszer" #: src/daemon/pipewire.desktop.in:5 msgid "Start the PipeWire Media System" -msgstr "" +msgstr "A PipeWire médiarendszer indítása" -#: src/examples/media-session/alsa-monitor.c:526 -#: spa/plugins/alsa/acp/compat.c:187 -msgid "Built-in Audio" -msgstr "Belső hangforrás" +#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180 +#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180 +#, c-format +msgid "Tunnel to %s/%s" +msgstr "Alagút ide: %s/%s" -#: src/examples/media-session/alsa-monitor.c:530 -#: spa/plugins/alsa/acp/compat.c:192 -msgid "Modem" -msgstr "Modem" +#: src/modules/module-fallback-sink.c:51 +msgid "Dummy Output" +msgstr "Üres kimenet" + +#: src/modules/module-pulse-tunnel.c:662 +#, c-format +msgid "Tunnel for %s@%s" +msgstr "Alagút ehhez: %s@%s" -#: src/examples/media-session/alsa-monitor.c:539 +#: src/modules/module-zeroconf-discover.c:332 msgid "Unknown device" -msgstr "" +msgstr "Ismeretlen eszköz" + +#: src/modules/module-zeroconf-discover.c:344 +#, c-format +msgid "%s on %s@%s" +msgstr "%s ezen: %s@%s" -#: src/tools/pw-cat.c:991 +#: src/modules/module-zeroconf-discover.c:348 +#, c-format +msgid "%s on %s" +msgstr "%s ezen: %s" + +#: src/tools/pw-cat.c:784 #, c-format msgid "" -"%s options <file>\n" +"%s options <file>|-\n" " -h, --help Show this help\n" " --version Show version\n" " -v, --verbose Enable verbose operations\n" "\n" msgstr "" +"%s kapcsolók <fájl>|-\n" +" -h, --help Ezen súgó megjelenítése\n" +" --version Verzió megjelenítése\n" +" -v, --verbose Részletes műveletek engedélyezése\n" +"\n" -#: src/tools/pw-cat.c:998 +#: src/tools/pw-cat.c:791 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -80,11 +101,30 @@ " or direct samples (256)\n" " the rate is the one of the source " "file\n" -" --list-targets List available targets for --target\n" +" -P --properties Set node properties\n" "\n" msgstr "" +" -R, --remote Távoli démon neve\n" +" --media-type Médiatípus beállítása (alapérték: " +"%s)\n" +" --media-category Médiakategória beállítása\n" +" (alapérték: %s)\n" +" --media-role Médiaszerep beállítása (alapérték: " +"%s)\n" +" --target Csomópont céljának beállítása\n" +" (alapérték: %s), a 0 azt jelenti,\n" +" hogy ne linkeljen\n" +" --latency Csomópont késleltetésének " +"beállítása\n" +" (alapérték: %s)\n" +" Xegység (egység = s, ms, us, ns)\n" +" vagy közvetlen minták (256)\n" +" a gyakoriság a forrásfájl egyike\n" +" -P --properties Csomópont tulajdonságainak " +"beállítása\n" +"\n" -#: src/tools/pw-cat.c:1016 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -103,16 +143,39 @@ "%d)\n" "\n" msgstr "" +" --rate Mintavételi gyakoriság (kötelező a\n" +" rögzítéshez) (alapérték: %u)\n" +" --channels Csatornák száma (kötelező a\n" +" rögzítéshez) (alapérték: %u)\n" +" --channel-map Csatornaleképezés\n" +" ezek egyike: „stereo”, " +"„surround-51”\n" +" stb. vagy csatornanevek vesszővel\n" +" tagolt listája, például: „FL,FR”\n" +" --format Mintavételi formátum: %s (kötelező " +"a\n" +" rögzítéshez) (alapérték: %s)\n" +" --volume Adatfolyam hangereje 0-1.0\n" +" (alapérték: %.3f)\n" +" -q --quality Újramintavételezési minőség (0-15)\n" +" (alapérték: %d)\n" +"\n" -#: src/tools/pw-cat.c:1033 +#: src/tools/pw-cat.c:826 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" " -m, --midi Midi mode\n" +" -d, --dsd DSD mode\n" "\n" msgstr "" +" -p, --playback Lejátszási mód\n" +" -r, --record Rögzítési mód\n" +" -m, --midi Midi mód\n" +" -d, --dsd DSD mód\n" +"\n" -#: src/tools/pw-cli.c:2932 +#: src/tools/pw-cli.c:2255 #, c-format msgid "" "%s options command\n" @@ -122,360 +185,353 @@ " -r, --remote Remote daemon name\n"
View file
pipewire-0.3.58.tar.gz/po/it.po -> pipewire-0.3.59.tar.gz/po/it.po
Changed
@@ -34,11 +34,11 @@ #: src/daemon/pipewire.desktop.in:4 msgid "PipeWire Media System" -msgstr "Sistema Multimediale PipeWire" +msgstr "Sistema multimediale PipeWire" #: src/daemon/pipewire.desktop.in:5 msgid "Start the PipeWire Media System" -msgstr "Avvia il Sistema Multimediale PipeWire" +msgstr "Avvia il sistema multimediale PipeWire" #: src/examples/media-session/alsa-monitor.c:526 #: spa/plugins/alsa/acp/compat.c:187 @@ -144,16 +144,16 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2711 msgid "Docking Station Microphone" -msgstr "Microfono docking station" +msgstr "Microfono della docking station" #: spa/plugins/alsa/acp/alsa-mixer.c:2712 msgid "Docking Station Line In" -msgstr "Linea in docking station" +msgstr "Linea di ingresso nella docking station" #: spa/plugins/alsa/acp/alsa-mixer.c:2713 #: spa/plugins/alsa/acp/alsa-mixer.c:2804 msgid "Line In" -msgstr "Line-In" +msgstr "Linea di ingresso" #: spa/plugins/alsa/acp/alsa-mixer.c:2714 #: spa/plugins/alsa/acp/alsa-mixer.c:2798 @@ -258,7 +258,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2811 msgid "Line Out" -msgstr "Line-Out" +msgstr "Linea di uscita" #: spa/plugins/alsa/acp/alsa-mixer.c:2812 msgid "Analog Mono Output" @@ -350,7 +350,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4542 #: spa/plugins/alsa/acp/alsa-mixer.c:4543 msgid "Multichannel" -msgstr "Multi canale" +msgstr "Multicanale" #: spa/plugins/alsa/acp/alsa-mixer.c:4544 msgid "Analog Surround 2.1" @@ -442,7 +442,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4701 msgid "Multichannel Duplex" -msgstr "Duplex multi canale" +msgstr "Duplex multicanale" #: spa/plugins/alsa/acp/alsa-mixer.c:4702 msgid "Stereo Duplex" @@ -477,11 +477,11 @@ msgstr0 "" "snd_pcm_avail() ha restituito un valore molto grande: %lu byte (%lu ms).\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." msgstr1 "" "snd_pcm_avail() ha restituito un valore molto grande: %lu byte (%lu ms).\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." #: spa/plugins/alsa/acp/alsa-util.c:1241 #, c-format @@ -498,11 +498,11 @@ msgstr0 "" "snd_pcm_delay() ha restituito un valore molto grande: %li byte (%s%lu ms).\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." msgstr1 "" "snd_pcm_delay() ha restituito un valore molto grande: %li byte (%s%lu ms).\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." #: spa/plugins/alsa/acp/alsa-util.c:1288 #, c-format @@ -515,7 +515,7 @@ "snd_pcm_avail() ha restituito dei valori strani: delay %lu è minore di avail " "%lu.\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." #: spa/plugins/alsa/acp/alsa-util.c:1331 #, c-format @@ -533,12 +533,12 @@ "snd_pcm_mmap_begin() ha restituito un valore molto grande: %lu byte (%lu " "ms).\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." msgstr1 "" "snd_pcm_mmap_begin() ha restituito un valore molto grande: %lu byte (%lu " "ms).\n" "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare " -"questo problema agli sviluppatori ALSA." +"questo problema ai suoi sviluppatori." #: spa/plugins/bluez5/bluez5-device.c:1010 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" @@ -547,20 +547,20 @@ #: spa/plugins/bluez5/bluez5-device.c:1033 #, c-format msgid "High Fidelity Playback (A2DP Sink, codec %s)" -msgstr "Riproduzione ad Alta Fedeltà (A2DP Sink, codec %s)" +msgstr "Riproduzione ad alta fedeltà (A2DP Sink, codec %s)" #: spa/plugins/bluez5/bluez5-device.c:1035 #, c-format msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)" -msgstr "Duplex ad Alta Fedeltà (Sorgente/Sink, A2DP codec %s)" +msgstr "Duplex ad alta fedeltà (Sorgente/Sink, A2DP codec %s)" #: spa/plugins/bluez5/bluez5-device.c:1041 msgid "High Fidelity Playback (A2DP Sink)" -msgstr "Riproduzione ad Alta Fedeltà (A2DP Sink)" +msgstr "Riproduzione ad alta fedeltà (A2DP Sink)" #: spa/plugins/bluez5/bluez5-device.c:1043 msgid "High Fidelity Duplex (A2DP Source/Sink)" -msgstr "Duplex ad Alta Fedeltà (A2DP Source/Sink)" +msgstr "Duplex ad alta fedeltà (A2DP Source/Sink)" #: spa/plugins/bluez5/bluez5-device.c:1070 #, c-format @@ -573,7 +573,7 @@ #: spa/plugins/bluez5/bluez5-device.c:1140 msgid "Handsfree" -msgstr "Sistema mani-libere" +msgstr "Vivavoce" #: spa/plugins/bluez5/bluez5-device.c:1155 msgid "Headphone"
View file
pipewire-0.3.58.tar.gz/po/pl.po -> pipewire-0.3.59.tar.gz/po/pl.po
Changed
@@ -8,8 +8,8 @@ "Project-Id-Version: pipewire\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" "issues\n" -"POT-Creation-Date: 2022-08-27 13:57+0000\n" -"PO-Revision-Date: 2022-08-27 16:00+0200\n" +"POT-Creation-Date: 2022-09-15 15:26+0000\n" +"PO-Revision-Date: 2022-09-25 15:20+0200\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Language-Team: Polish <community-poland@mozilla.org>\n" "Language: pl\n" @@ -51,7 +51,7 @@ msgid "Dummy Output" msgstr "Głuche wyjście" -#: src/modules/module-pulse-tunnel.c:648 +#: src/modules/module-pulse-tunnel.c:662 #, c-format msgid "Tunnel for %s@%s" msgstr "Tunel dla %s@%s" @@ -195,7 +195,7 @@ msgstr "Dźwięk w zastosowaniach profesjonalnych" #: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1188 +#: spa/plugins/bluez5/bluez5-device.c:1236 msgid "Off" msgstr "Wyłączone" @@ -222,7 +222,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2657 #: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:1360 +#: spa/plugins/bluez5/bluez5-device.c:1454 msgid "Microphone" msgstr "Mikrofon" @@ -288,7 +288,7 @@ msgstr "Brak podbicia basów" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1366 +#: spa/plugins/bluez5/bluez5-device.c:1460 msgid "Speaker" msgstr "Głośnik" @@ -403,7 +403,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4484 #: spa/plugins/alsa/acp/alsa-mixer.c:4642 -#: spa/plugins/bluez5/bluez5-device.c:1348 +#: spa/plugins/bluez5/bluez5-device.c:1442 msgid "Headset" msgstr "Słuchawki z mikrofonem" @@ -627,77 +627,92 @@ msgid "Modem" msgstr "Modem" -#: spa/plugins/bluez5/bluez5-device.c:1199 +#: spa/plugins/bluez5/bluez5-device.c:1247 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" msgstr "Bramka dźwięku (źródło A2DP i AG HSP/HFP)" -#: spa/plugins/bluez5/bluez5-device.c:1224 +#: spa/plugins/bluez5/bluez5-device.c:1272 #, c-format msgid "High Fidelity Playback (A2DP Sink, codec %s)" msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1227 +#: spa/plugins/bluez5/bluez5-device.c:1275 #, c-format msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)" msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1235 +#: spa/plugins/bluez5/bluez5-device.c:1283 msgid "High Fidelity Playback (A2DP Sink)" msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP)" -#: spa/plugins/bluez5/bluez5-device.c:1237 +#: spa/plugins/bluez5/bluez5-device.c:1285 msgid "High Fidelity Duplex (A2DP Source/Sink)" msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP)" -#: spa/plugins/bluez5/bluez5-device.c:1265 +#: spa/plugins/bluez5/bluez5-device.c:1322 +#, c-format +msgid "High Fidelity Playback (BAP Sink, codec %s)" +msgstr "Odtwarzanie o wysokiej dokładności (odpływ BAP, kodek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1326 +#, c-format +msgid "High Fidelity Input (BAP Source, codec %s)" +msgstr "Wejście o wysokiej dokładności (źródło BAP, kodek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1330 +#, c-format +msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)" +msgstr "Dupleks o wysokiej dokładności (źródło/odpływ BAP, kodek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1359 #, c-format msgid "Headset Head Unit (HSP/HFP, codec %s)" msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1270 +#: spa/plugins/bluez5/bluez5-device.c:1364 msgid "Headset Head Unit (HSP/HFP)" msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP)" -#: spa/plugins/bluez5/bluez5-device.c:1349 -#: spa/plugins/bluez5/bluez5-device.c:1354 -#: spa/plugins/bluez5/bluez5-device.c:1361 -#: spa/plugins/bluez5/bluez5-device.c:1367 -#: spa/plugins/bluez5/bluez5-device.c:1373 -#: spa/plugins/bluez5/bluez5-device.c:1379 -#: spa/plugins/bluez5/bluez5-device.c:1385 -#: spa/plugins/bluez5/bluez5-device.c:1391 -#: spa/plugins/bluez5/bluez5-device.c:1397 +#: spa/plugins/bluez5/bluez5-device.c:1443 +#: spa/plugins/bluez5/bluez5-device.c:1448 +#: spa/plugins/bluez5/bluez5-device.c:1455 +#: spa/plugins/bluez5/bluez5-device.c:1461 +#: spa/plugins/bluez5/bluez5-device.c:1467 +#: spa/plugins/bluez5/bluez5-device.c:1473 +#: spa/plugins/bluez5/bluez5-device.c:1479 +#: spa/plugins/bluez5/bluez5-device.c:1485 +#: spa/plugins/bluez5/bluez5-device.c:1491 msgid "Handsfree" msgstr "Zestaw głośnomówiący" -#: spa/plugins/bluez5/bluez5-device.c:1355 +#: spa/plugins/bluez5/bluez5-device.c:1449 msgid "Handsfree (HFP)" msgstr "Zestaw głośnomówiący (HFP)" -#: spa/plugins/bluez5/bluez5-device.c:1372 +#: spa/plugins/bluez5/bluez5-device.c:1466 msgid "Headphone" msgstr "Słuchawki" -#: spa/plugins/bluez5/bluez5-device.c:1378 +#: spa/plugins/bluez5/bluez5-device.c:1472 msgid "Portable" msgstr "Przenośne" -#: spa/plugins/bluez5/bluez5-device.c:1384 +#: spa/plugins/bluez5/bluez5-device.c:1478 msgid "Car" msgstr "Samochód" -#: spa/plugins/bluez5/bluez5-device.c:1390 +#: spa/plugins/bluez5/bluez5-device.c:1484 msgid "HiFi" msgstr "HiFi" -#: spa/plugins/bluez5/bluez5-device.c:1396 +#: spa/plugins/bluez5/bluez5-device.c:1490 msgid "Phone" msgstr "Telefon" -#: spa/plugins/bluez5/bluez5-device.c:1403 +#: spa/plugins/bluez5/bluez5-device.c:1497 msgid "Bluetooth" msgstr "Bluetooth" -#: spa/plugins/bluez5/bluez5-device.c:1404 +#: spa/plugins/bluez5/bluez5-device.c:1498 msgid "Bluetooth (HFP)" msgstr "Bluetooth (HFP)"
View file
pipewire-0.3.58.tar.gz/spa/include/spa/buffer/alloc.h -> pipewire-0.3.59.tar.gz/spa/include/spa/buffer/alloc.h
Changed
@@ -161,8 +161,9 @@ *target += info->chunk_size; for (i = 0, size = 0; i < n_datas; i++) { + int64_t align = data_alignsi; info->max_align = SPA_MAX(info->max_align, data_alignsi); - size = SPA_ROUND_UP_N(size, data_alignsi); + size = SPA_ROUND_UP_N(size, align); size += datasi.maxsize; } info->data_size = size;
View file
pipewire-0.3.58.tar.gz/spa/include/spa/buffer/meta.h -> pipewire-0.3.59.tar.gz/spa/include/spa/buffer/meta.h
Changed
@@ -64,9 +64,15 @@ void *data; /**< pointer to metadata */ }; -#define spa_meta_first(m) ((m)->data) -#define spa_meta_end(m) SPA_PTROFF((m)->data,(m)->size,void) -#define spa_meta_check(p,m) (SPA_PTROFF(p,sizeof(*p),void) <= spa_meta_end(m)) +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 @@ -92,11 +98,14 @@ struct spa_region region; }; -#define spa_meta_region_is_valid(m) ((m)->region.size.width != 0 && (m)->region.size.height != 0) +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); \ + for ((pos) = (__typeof(pos))spa_meta_first(meta); \ spa_meta_check(pos, meta); \ (pos)++)
View file
pipewire-0.3.58.tar.gz/spa/include/spa/debug/log.h -> pipewire-0.3.59.tar.gz/spa/include/spa/debug/log.h
Changed
@@ -36,10 +36,10 @@ */ #ifndef spa_debug -#define spa_debug(fmt,...) ({ printf(fmt"\n", ## __VA_ARGS__); }) +#define spa_debug(fmt,...) ({ printf((fmt"\n"), ## __VA_ARGS__); }) #endif #ifndef spa_debugn -#define spa_debugn(fmt,...) ({ printf(fmt, ## __VA_ARGS__); }) +#define spa_debugn(fmt,...) ({ printf((fmt), ## __VA_ARGS__); }) #endif /**
View file
pipewire-0.3.58.tar.gz/spa/include/spa/graph/graph.h -> pipewire-0.3.59.tar.gz/spa/include/spa/graph/graph.h
Changed
@@ -121,12 +121,12 @@ int __res = 0; \ spa_callbacks_call_res(&(n)->callbacks, \ struct spa_graph_node_callbacks, __res, \ - method, version, ##__VA_ARGS__); \ + method, (version), ##__VA_ARGS__); \ __res; \ }) -#define spa_graph_node_process(n) spa_graph_node_call(n, process, 0, n) -#define spa_graph_node_reuse_buffer(n,p,i) spa_graph_node_call(n, reuse_buffer, 0, n, p, i) +#define spa_graph_node_process(n) spa_graph_node_call((n), process, 0, (n)) +#define spa_graph_node_reuse_buffer(n,p,i) spa_graph_node_call((n), reuse_buffer, 0, (n), (p), (i)) struct spa_graph_port { struct spa_list link; /**< link in node port list */
View file
pipewire-0.3.58.tar.gz/spa/include/spa/interfaces/audio/aec.h -> pipewire-0.3.59.tar.gz/spa/include/spa/interfaces/audio/aec.h
Changed
@@ -80,10 +80,10 @@ #define spa_audio_aec_method(o,method,version,...) \ ({ \ int _res = -ENOTSUP; \ - struct spa_audio_aec *_o = o; \ + struct spa_audio_aec *_o = (o); \ spa_interface_call_res(&_o->iface, \ struct spa_audio_aec_methods, _res, \ - method, version, ##__VA_ARGS__); \ + method, (version), ##__VA_ARGS__); \ _res; \ })
View file
pipewire-0.3.58.tar.gz/spa/include/spa/monitor/device.h -> pipewire-0.3.59.tar.gz/spa/include/spa/monitor/device.h
Changed
@@ -71,7 +71,7 @@ uint32_t n_params; /**< number of elements in params */ }; -#define SPA_DEVICE_INFO_INIT() (struct spa_device_info){ SPA_VERSION_DEVICE_INFO, } +#define SPA_DEVICE_INFO_INIT() ((struct spa_device_info){ SPA_VERSION_DEVICE_INFO, }) /** * Information about a device object @@ -92,7 +92,7 @@ const struct spa_dict *props; /**< extra object properties */ }; -#define SPA_DEVICE_OBJECT_INFO_INIT() (struct spa_device_object_info){ SPA_VERSION_DEVICE_OBJECT_INFO, } +#define SPA_DEVICE_OBJECT_INFO_INIT() ((struct spa_device_object_info){ SPA_VERSION_DEVICE_OBJECT_INFO, }) /** the result of spa_device_enum_params() */ #define SPA_RESULT_TYPE_DEVICE_PARAMS 1 @@ -243,10 +243,10 @@ #define spa_device_method(o,method,version,...) \ ({ \ int _res = -ENOTSUP; \ - struct spa_device *_o = o; \ + struct spa_device *_o = (o); \ spa_interface_call_res(&_o->iface, \ struct spa_device_methods, _res, \ - method, version, ##__VA_ARGS__); \ + method, (version), ##__VA_ARGS__); \ _res; \ })
View file
pipewire-0.3.58.tar.gz/spa/include/spa/node/io.h -> pipewire-0.3.59.tar.gz/spa/include/spa/node/io.h
Changed
@@ -100,7 +100,7 @@ uint32_t buffer_id; /**< a buffer id */ }; -#define SPA_IO_BUFFERS_INIT (struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, } +#define SPA_IO_BUFFERS_INIT ((struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, }) /** * IO area to exchange a memory region @@ -110,7 +110,7 @@ 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, } +#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 {
View file
pipewire-0.3.58.tar.gz/spa/include/spa/node/node.h -> pipewire-0.3.59.tar.gz/spa/include/spa/node/node.h
Changed
@@ -85,7 +85,7 @@ uint32_t n_params; /**< number of items in \a params */ }; -#define SPA_NODE_INFO_INIT() (struct spa_node_info) { 0, } +#define SPA_NODE_INFO_INIT() ((struct spa_node_info) { 0, }) /** * Port information structure @@ -124,7 +124,7 @@ uint32_t n_params; /**< number of items in \a params */ }; -#define SPA_PORT_INFO_INIT() (struct spa_port_info) { 0, } +#define SPA_PORT_INFO_INIT() ((struct spa_port_info) { 0, }) #define SPA_RESULT_TYPE_NODE_ERROR 1 #define SPA_RESULT_TYPE_NODE_PARAMS 2
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/audio/dsd.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/audio/dsd.h
Changed
@@ -68,7 +68,7 @@ uint32_t positionSPA_AUDIO_MAX_CHANNELS; /*< channel position from enum spa_audio_channel */ }; -#define SPA_AUDIO_INFO_DSD_INIT(...) (struct spa_audio_info_dsd) { __VA_ARGS__ } +#define SPA_AUDIO_INFO_DSD_INIT(...) ((struct spa_audio_info_dsd) { __VA_ARGS__ }) /** * \}
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/audio/iec958.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/audio/iec958.h
Changed
@@ -56,7 +56,7 @@ uint32_t rate; /*< sample rate */ }; -#define SPA_AUDIO_INFO_IEC958_INIT(...) (struct spa_audio_info_iec958) { __VA_ARGS__ } +#define SPA_AUDIO_INFO_IEC958_INIT(...) ((struct spa_audio_info_iec958) { __VA_ARGS__ }) /** * \}
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/audio/raw.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/audio/raw.h
Changed
@@ -294,7 +294,7 @@ uint32_t positionSPA_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_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" */ @@ -311,7 +311,7 @@ enum spa_audio_format format; /*< format, one of the DSP formats in enum spa_audio_format_dsp */ }; -#define SPA_AUDIO_INFO_DSP_INIT(...) (struct spa_audio_info_dsp) { __VA_ARGS__ } +#define SPA_AUDIO_INFO_DSP_INIT(...) ((struct spa_audio_info_dsp) { __VA_ARGS__ }) /** * \}
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/bluetooth/audio.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/bluetooth/audio.h
Changed
@@ -58,6 +58,9 @@ /* HFP */ SPA_BLUETOOTH_AUDIO_CODEC_CVSD = 0x100, SPA_BLUETOOTH_AUDIO_CODEC_MSBC, + + /* BAP */ + SPA_BLUETOOTH_AUDIO_CODEC_LC3 = 0x200, }; /**
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/bluetooth/type-info.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/bluetooth/type-info.h
Changed
@@ -62,6 +62,8 @@ { SPA_BLUETOOTH_AUDIO_CODEC_CVSD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "cvsd", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_MSBC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "msbc", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_LC3, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "lc3", NULL }, + { 0, 0, NULL, NULL }, };
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/latency-utils.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/latency-utils.h
Changed
@@ -50,7 +50,7 @@ uint64_t max_ns; }; -#define SPA_LATENCY_INFO(dir,...) (struct spa_latency_info) { .direction = (dir), ## __VA_ARGS__ } +#define SPA_LATENCY_INFO(dir,...) ((struct spa_latency_info) { .direction = (dir), ## __VA_ARGS__ }) static inline int spa_latency_info_compare(const struct spa_latency_info *a, struct spa_latency_info *b) @@ -146,7 +146,7 @@ uint64_t ns; }; -#define SPA_PROCESS_LATENCY_INFO_INIT(...) (struct spa_process_latency_info) { __VA_ARGS__ } +#define SPA_PROCESS_LATENCY_INFO_INIT(...) ((struct spa_process_latency_info) { __VA_ARGS__ }) static inline int spa_process_latency_parse(const struct spa_pod *latency, struct spa_process_latency_info *info)
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/param.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/param.h
Changed
@@ -75,7 +75,7 @@ uint32_t padding5; }; -#define SPA_PARAM_INFO(id,flags) (struct spa_param_info){ (id), (flags) } +#define SPA_PARAM_INFO(id,flags) ((struct spa_param_info){ (id), (flags) }) /** properties for SPA_TYPE_OBJECT_ParamBuffers */ enum spa_param_buffers {
View file
pipewire-0.3.58.tar.gz/spa/include/spa/param/video/raw.h -> pipewire-0.3.59.tar.gz/spa/include/spa/param/video/raw.h
Changed
@@ -206,14 +206,14 @@ enum spa_video_color_primaries color_primaries; /**< color primaries. used to convert between R'G'B' and CIE XYZ */ }; -#define SPA_VIDEO_INFO_RAW_INIT(...) (struct spa_video_info_raw) { __VA_ARGS__ } +#define SPA_VIDEO_INFO_RAW_INIT(...) ((struct spa_video_info_raw) { __VA_ARGS__ }) struct spa_video_info_dsp { enum spa_video_format format; int64_t modifier; }; -#define SPA_VIDEO_INFO_DSP_INIT(...) (struct spa_video_info_dsp) { __VA_ARGS__ } +#define SPA_VIDEO_INFO_DSP_INIT(...) ((struct spa_video_info_dsp) { __VA_ARGS__ }) /** * \}
View file
pipewire-0.3.58.tar.gz/spa/include/spa/pod/builder.h -> pipewire-0.3.59.tar.gz/spa/include/spa/pod/builder.h
Changed
@@ -69,7 +69,7 @@ struct spa_callbacks callbacks; }; -#define SPA_POD_BUILDER_INIT(buffer,size) (struct spa_pod_builder){ buffer, size, 0, {}, {} } +#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) @@ -143,8 +143,10 @@ if (offset + size > builder->size) { res = -ENOSPC; - spa_callbacks_call_res(&builder->callbacks, struct spa_pod_builder_callbacks, res, - overflow, 0, offset + size); + 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); @@ -212,7 +214,7 @@ return res; } -#define SPA_POD_INIT(size,type) (struct spa_pod) { size, type } +#define SPA_POD_INIT(size,type) ((struct spa_pod) { (size), (type) }) #define SPA_POD_INIT_None() SPA_POD_INIT(0, SPA_TYPE_None) @@ -229,7 +231,7 @@ 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 } +#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) { @@ -237,7 +239,7 @@ return spa_pod_builder_primitive(builder, &p.pod); } -#define SPA_POD_INIT_Id(val) (struct spa_pod_id){ { sizeof(uint32_t), SPA_TYPE_Id }, (uint32_t)val, 0 } +#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) { @@ -245,7 +247,7 @@ return spa_pod_builder_primitive(builder, &p.pod); } -#define SPA_POD_INIT_Int(val) (struct spa_pod_int){ { sizeof(int32_t), SPA_TYPE_Int }, (int32_t)val, 0 } +#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) { @@ -253,7 +255,7 @@ return spa_pod_builder_primitive(builder, &p.pod); } -#define SPA_POD_INIT_Long(val) (struct spa_pod_long){ { sizeof(int64_t), SPA_TYPE_Long }, (int64_t)val } +#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) { @@ -261,7 +263,7 @@ 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 } +#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) { @@ -269,7 +271,7 @@ return spa_pod_builder_primitive(builder, &p.pod); } -#define SPA_POD_INIT_Double(val) (struct spa_pod_double){ { sizeof(double), SPA_TYPE_Double }, val } +#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) { @@ -277,7 +279,7 @@ return spa_pod_builder_primitive(builder, &p.pod); } -#define SPA_POD_INIT_String(len) (struct spa_pod_string){ { len, SPA_TYPE_String } } +#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) @@ -307,7 +309,7 @@ return spa_pod_builder_string_len(builder, str ? str : "", len); } -#define SPA_POD_INIT_Bytes(len) (struct spa_pod_bytes){ { len, SPA_TYPE_Bytes } } +#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) @@ -327,7 +329,7 @@ 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 } } +#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) @@ -336,7 +338,7 @@ 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 } +#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) { @@ -344,7 +346,7 @@ 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 } +#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) @@ -353,7 +355,7 @@ 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 } +#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) @@ -389,12 +391,12 @@ } #define SPA_POD_INIT_CHOICE_BODY(type, flags, child_size, child_type) \ - (struct spa_pod_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 valsn_vals;}) \ - { { { n_vals * sizeof(ctype) + sizeof(struct spa_pod_choice_body), SPA_TYPE_Choice }, \ - { type, 0, { sizeof(ctype), child_type } } }, { __VA_ARGS__ } } + ((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, @@ -409,7 +411,7 @@ return res; } -#define SPA_POD_INIT_Struct(size) (struct spa_pod_struct){ { size, SPA_TYPE_Struct } } +#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) @@ -421,7 +423,7 @@ return res; } -#define SPA_POD_INIT_Object(size,type,id,...) (struct spa_pod_object){ { size, SPA_TYPE_Object }, { type, id }, ##__VA_ARGS__ } +#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, @@ -436,7 +438,7 @@ } #define SPA_POD_INIT_Prop(key,flags,size,type) \ - (struct spa_pod_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) @@ -446,7 +448,7 @@ } #define SPA_POD_INIT_Sequence(size,unit) \ - (struct spa_pod_sequence){ { size, SPA_TYPE_Sequence}, {unit, 0 } } + ((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) @@ -650,26 +652,29 @@ #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); \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/pod/command.h -> pipewire-0.3.59.tar.gz/spa/include/spa/pod/command.h
Changed
@@ -47,12 +47,12 @@ }; #define SPA_COMMAND_TYPE(cmd) ((cmd)->body.body.type) -#define SPA_COMMAND_ID(cmd,type) (SPA_COMMAND_TYPE(cmd) == 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_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, \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/pod/event.h -> pipewire-0.3.59.tar.gz/spa/include/spa/pod/event.h
Changed
@@ -46,7 +46,7 @@ }; #define SPA_EVENT_TYPE(ev) ((ev)->body.body.type) -#define SPA_EVENT_ID(ev,type) (SPA_EVENT_TYPE(ev) == 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) \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/pod/parser.h -> pipewire-0.3.59.tar.gz/spa/include/spa/pod/parser.h
Changed
@@ -53,7 +53,7 @@ struct spa_pod_parser_state state; }; -#define SPA_POD_PARSER_INIT(buffer,size) (struct spa_pod_parser){ buffer, size, 0, {} } +#define SPA_POD_PARSER_INIT(buffer,size) ((struct spa_pod_parser){ (buffer), (size), 0, {} }) static inline void spa_pod_parser_init(struct spa_pod_parser *parser, const void *data, uint32_t size) @@ -82,12 +82,20 @@ static inline struct spa_pod * spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t size) { - if (offset + 8 <= size) { - struct spa_pod *pod = SPA_PTROFF(parser->data, offset, struct spa_pod); - if (offset + SPA_POD_SIZE(pod) <= size) - return pod; + /* Cast to uint64_t to avoid wraparound. Add 8 for the pod itself. */ + const uint64_t long_offset = (uint64_t)offset + 8; + if (long_offset <= size && (offset & 7) == 0) { + /* Use void* because creating a misaligned pointer is undefined. */ + void *pod = SPA_PTROFF(parser->data, offset, void); + /* + * Check that the pointer is aligned and that the size (rounded + * to the next multiple of 8) is in bounds. + */ + if (SPA_IS_ALIGNED(pod, __alignof__(struct spa_pod)) && + long_offset + SPA_ROUND_UP_N((uint64_t)SPA_POD_BODY_SIZE(pod), 8) <= size) + return (struct spa_pod *)pod; } - return NULL; + return NULL; } static inline struct spa_pod *spa_pod_parser_frame(struct spa_pod_parser *parser, struct spa_pod_frame *frame) @@ -285,10 +293,15 @@ if (pod == NULL) return false; - if (spa_pod_is_choice(pod) && - SPA_POD_CHOICE_TYPE(pod) == SPA_CHOICE_None && - spa_pod_parser_can_collect(SPA_POD_CHOICE_CHILD(pod), type)) - return true; + if (SPA_POD_TYPE(pod) == SPA_TYPE_Choice) { + if (!spa_pod_is_choice(pod)) + return false; + if (type == 'V') + return true; + if (SPA_POD_CHOICE_TYPE(pod) != SPA_CHOICE_None) + return false; + pod = SPA_POD_CHOICE_CHILD(pod); + } switch (type) { case 'P': @@ -328,7 +341,6 @@ case 'O': return spa_pod_is_object(pod) || spa_pod_is_none(pod); case 'V': - return spa_pod_is_choice(pod); default: return false; } @@ -355,7 +367,7 @@ break; \ case 's': \ *va_arg(args, char**) = \ - (pod == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \ + ((pod) == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \ ? NULL \ : (char *)SPA_POD_CONTENTS(struct spa_pod_string, pod)); \ break; \ @@ -407,8 +419,8 @@ { \ const struct spa_pod **d = va_arg(args, const struct spa_pod**); \ if (d) \ - *d = (pod == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \ - ? NULL : pod); \ + *d = ((pod) == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \ + ? NULL : (pod)); \ break; \ } \ default: \ @@ -493,8 +505,7 @@ } SPA_POD_PARSER_SKIP(*format, args); } else { - if (pod->type == SPA_TYPE_Choice && *format != 'V' && - SPA_POD_CHOICE_TYPE(pod) == SPA_CHOICE_None) + if (pod->type == SPA_TYPE_Choice && *format != 'V') pod = SPA_POD_CHOICE_CHILD(pod); SPA_POD_PARSER_COLLECT(pod, *format, args);
View file
pipewire-0.3.58.tar.gz/spa/include/spa/pod/pod.h -> pipewire-0.3.59.tar.gz/spa/include/spa/pod/pod.h
Changed
@@ -39,7 +39,7 @@ #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) (sizeof(struct spa_pod) + SPA_POD_BODY_SIZE(pod)) +#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) @@ -52,7 +52,7 @@ uint32_t type; /* a basic id of enum spa_type */ }; -#define SPA_POD_VALUE(type,pod) (((type*)pod)->value) +#define SPA_POD_VALUE(type,pod) (((type*)(pod))->value) struct spa_pod_bool { struct spa_pod pod;
View file
pipewire-0.3.58.tar.gz/spa/include/spa/support/log-impl.h -> pipewire-0.3.59.tar.gz/spa/include/spa/support/log-impl.h
Changed
@@ -121,7 +121,7 @@ #define SPA_LOG_IMPL_INIT(name) \ { { { SPA_TYPE_INTERFACE_Log, SPA_VERSION_LOG, \ - SPA_CALLBACKS_INIT(&name.methods, &name) }, \ + SPA_CALLBACKS_INIT(&(name).methods, &(name)) }, \ SPA_LOG_LEVEL_INFO, }, \ { SPA_VERSION_LOG_METHODS, \ spa_log_impl_log, \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/support/log.h -> pipewire-0.3.59.tar.gz/spa/include/spa/support/log.h
Changed
@@ -212,7 +212,7 @@ #define SPA_LOG_TOPIC(v, t) \ - (struct spa_log_topic){ .version = v, .topic = (t)} + (struct spa_log_topic){ .version = (v), .topic = (t)} #define spa_log_topic_init(l, topic) \ do { \ @@ -231,10 +231,10 @@ ({ \ struct spa_log *_log = l; \ enum spa_log_level _lev = _log ? _log->level : SPA_LOG_LEVEL_NONE; \ - struct spa_log_topic *_t = (struct spa_log_topic *)topic; \ + struct spa_log_topic *_t = (struct spa_log_topic *)(topic); \ if (_t && _t->has_custom_level) \ _lev = _t->level; \ - _lev >= lev; \ + _lev >= (lev); \ }) /* Transparently calls to version 0 log if v1 is not supported */ @@ -269,26 +269,32 @@ } \ }) +#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_log(l,SPA_LOG_LEVEL_ERROR,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_log_warn(l,...) spa_log_log(l,SPA_LOG_LEVEL_WARN,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_log_info(l,...) spa_log_log(l,SPA_LOG_LEVEL_INFO,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_log_debug(l,...) spa_log_log(l,SPA_LOG_LEVEL_DEBUG,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_log_trace(l,...) spa_log_log(l,SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__) +#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_log_logt(l,SPA_LOG_LEVEL_ERROR,t,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_logt_warn(l,t,...) spa_log_logt(l,SPA_LOG_LEVEL_WARN,t,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_logt_info(l,t,...) spa_log_logt(l,SPA_LOG_LEVEL_INFO,t,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_logt_debug(l,t,...) spa_log_logt(l,SPA_LOG_LEVEL_DEBUG,t,__FILE__,__LINE__,__func__,__VA_ARGS__) -#define spa_logt_trace(l,t,...) spa_log_logt(l,SPA_LOG_LEVEL_TRACE,t,__FILE__,__LINE__,__func__,__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_log(l,SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__) +#define spa_log_trace_fp(l,...) spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__) #else #define spa_log_trace_fp(l,...) #endif @@ -296,18 +302,16 @@ #define spa_log_hexdump(l,lev,indent,data,len) \ ({ \ char str512; \ - uint8_t *buf = (uint8_t *)data; \ - size_t i; \ + uint8_t *buf = (uint8_t *)(data); \ + size_t i, j = (len); \ int pos = 0; \ \ - for (i = 0; i < len; i++) { \ + for (i = 0; i < j; i++) { \ if (i % 16 == 0) \ pos = 0; \ pos += sprintf(str + pos, "%02x ", bufi); \ - if (i % 16 == 15 || i == len - 1) { \ - spa_log_log(l,lev,__FILE__,__LINE__,__func__, \ - "%*s" "%s",indent,"", str); \ - } \ + if (i % 16 == 15 || i == j - 1) \ + spa_log_lev(l,lev, "%*s" "%s",indent,"", str); \ } \ })
View file
pipewire-0.3.58.tar.gz/spa/include/spa/support/plugin.h -> pipewire-0.3.59.tar.gz/spa/include/spa/support/plugin.h
Changed
@@ -105,7 +105,7 @@ return NULL; } -#define SPA_SUPPORT_INIT(type,data) (struct spa_support) { (type), (data) } +#define SPA_SUPPORT_INIT(type,data) ((struct spa_support) { (type), (data) }) struct spa_handle_factory { /** The version of this structure */
View file
pipewire-0.3.58.tar.gz/spa/include/spa/support/system.h -> pipewire-0.3.59.tar.gz/spa/include/spa/support/system.h
Changed
@@ -119,7 +119,7 @@ #define spa_system_method_r(o,method,version,...) \ ({ \ - int _res = -ENOTSUP; \ + volatile int _res = -ENOTSUP; \ struct spa_system *_o = o; \ spa_interface_call_res(&_o->iface, \ struct spa_system_methods, _res, \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/defs.h
Changed
@@ -27,8 +27,18 @@ #ifdef __cplusplus extern "C" { +# if __cplusplus >= 201103L +# define SPA_STATIC_ASSERT static_assert +# endif #else -#include <stdbool.h> +# include <stdbool.h> +# if __STDC_VERSION__ >= 201112L +# define SPA_STATIC_ASSERT _Static_assert +# endif +#endif +#ifndef SPA_STATIC_ASSERT +#define SPA_STATIC_ASSERT(a, b) \ + ((void)sizeof(struct { int spa_static_assertion_failed : 2 * !!(a) - 1; })) #endif #include <inttypes.h> #include <signal.h> @@ -74,8 +84,16 @@ #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) ((field) &= ~(flag)) -#define SPA_FLAG_UPDATE(field,flag,val) ((val) ? SPA_FLAG_SET(field,flag) : SPA_FLAG_CLEAR(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, @@ -84,25 +102,25 @@ #define SPA_DIRECTION_REVERSE(d) ((d) ^ 1) -#define SPA_RECTANGLE(width,height) (struct spa_rectangle){ width, height } +#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 } +#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) } +#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 } +#define SPA_FRACTION(num,denom) ((struct spa_fraction){ (num), (denom) }) struct spa_fraction { uint32_t num; uint32_t denom; @@ -120,7 +138,7 @@ * ``` */ #define SPA_FOR_EACH_ELEMENT(arr, ptr) \ - for (ptr = arr; (void*)ptr < SPA_PTROFF(arr, sizeof(arr), void); ptr++) + for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++) #define SPA_ABS(a) \ ({ \ @@ -156,7 +174,7 @@ #define SPA_SWAP(a,b) \ ({ \ __typeof__(a) _t = (a); \ - a = b; b = _t; \ + (a) = b; (b) = _t; \ }) #define SPA_TYPECHECK(type,x) \ @@ -180,7 +198,7 @@ #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_CONTAINER_OF(p,t,m) ((t*)((uintptr_t)(p) - offsetof(t,m))) #define SPA_PTRDIFF(p1,p2) ((intptr_t)(p1) - (intptr_t)(p2)) @@ -194,7 +212,7 @@ #define SPA_IDX_INVALID ((unsigned int)-1) #define SPA_ID_INVALID ((uint32_t)0xffffffff) -#define SPA_NSEC_PER_SEC (1000000000ll) +#define SPA_NSEC_PER_SEC (1000000000LL) #define SPA_NSEC_PER_MSEC (1000000ll) #define SPA_NSEC_PER_USEC (1000ll) #define SPA_USEC_PER_SEC (1000000ll) @@ -239,7 +257,17 @@ #define SPA_ROUND_DOWN(num,value) ((num) - ((num) % (value))) #define SPA_ROUND_UP(num,value) ((((num) + (value) - 1) / (value)) * (value)) -#define SPA_ROUND_DOWN_N(num,align) ((num) & ~((align) - 1)) +#define SPA_MASK_NEGATED(num1, num2) \ +({ \ + SPA_STATIC_ASSERT(__builtin_constant_p(num2) ? \ + (__typeof__(num2))(__typeof__(num1))(__typeof__(num2))(num2) == (num2) : \ + sizeof(num1) >= sizeof(num2), \ + "truncation problem when masking " #num1 \ + " with ~" #num2); \ + ((num1) & ~(__typeof__(num1))(num2)); \ +}) + +#define SPA_ROUND_DOWN_N(num,align) SPA_MASK_NEGATED((num), (align) - 1) #define SPA_ROUND_UP_N(num,align) SPA_ROUND_DOWN_N((num) + ((align) - 1),align) #define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1))
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/dict.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/dict.h
Changed
@@ -48,7 +48,7 @@ const char *value; }; -#define SPA_DICT_ITEM_INIT(key,value) (struct spa_dict_item) { key, 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 */ @@ -57,8 +57,8 @@ 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_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; \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/hook.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/hook.h
Changed
@@ -142,7 +142,7 @@ * 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, } +#define SPA_CALLBACKS_INIT(_funcs,_data) ((struct spa_callbacks){ (_funcs), (_data), }) /** \struct spa_interface */
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/json.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/json.h
Changed
@@ -58,20 +58,20 @@ uint32_t depth; }; -#define SPA_JSON_INIT(data,size) (struct spa_json) { (data), (data)+(size), } +#define SPA_JSON_INIT(data,size) ((struct spa_json) { (data), (data)+(size), }) static inline void spa_json_init(struct spa_json * iter, const char *data, size_t size) { *iter = SPA_JSON_INIT(data, size); } -#define SPA_JSON_ENTER(iter) (struct spa_json) { (iter)->cur, (iter)->end, (iter), } +#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), }) static inline void spa_json_enter(struct spa_json * iter, struct spa_json * sub) { *sub = SPA_JSON_ENTER(iter); } -#define SPA_JSON_SAVE(iter) (struct spa_json) { (iter)->cur, (iter)->end, } +#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, }) /** Get the next token. \a value points to the token and the return value * is the length. */
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/list.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/list.h
Changed
@@ -44,7 +44,7 @@ struct spa_list *prev; }; -#define SPA_LIST_INIT(list) (struct spa_list){ list, list } +#define SPA_LIST_INIT(list) ((struct spa_list){ (list), (list) }) static inline void spa_list_init(struct spa_list *list) { @@ -98,25 +98,25 @@ (&(pos)->member == (head)) #define spa_list_next(pos, member) \ - SPA_CONTAINER_OF((pos)->member.next, __typeof__(*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) + 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); \ + for ((pos) = spa_list_first(head, __typeof__(*(pos)), member); \ !spa_list_is_empty(head); \ - pos = spa_list_first(head, __typeof__(*pos), member)) + (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); \ + for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member); \ !spa_list_is_end(pos, head, member); \ - pos = spa_list_next(pos, 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); \ + for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member); \ !spa_list_is_end(pos, head, member); \ - pos = spa_list_prev(pos, member)) + (pos) = spa_list_prev(pos, member)) #define spa_list_for_each(pos, head, member) \ spa_list_for_each_next(pos, head, head, member) @@ -125,16 +125,16 @@ 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), \ + for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member); \ + (tmp) = spa_list_next(pos, member), \ !spa_list_is_end(pos, head, member); \ - pos = tmp) + (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), \ + for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member); \ + (tmp) = spa_list_prev(pos, member), \ !spa_list_is_end(pos, head, member); \ - pos = tmp) + (pos) = (tmp)) #define spa_list_for_each_safe(pos, tmp, head, member) \ spa_list_for_each_safe_next(pos, tmp, head, head, member) @@ -146,11 +146,11 @@ 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); \ + 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)) + (pos) = spa_list_next(&(cursor), member)) #define spa_list_cursor_end(cursor, member) \ spa_list_remove(&(cursor).member)
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/names.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/names.h
Changed
@@ -114,13 +114,15 @@ /** keys for bluez5 factory names */ #define SPA_NAME_API_BLUEZ5_ENUM_DBUS "api.bluez5.enum.dbus" /**< a dbus Device interface */ #define SPA_NAME_API_BLUEZ5_DEVICE "api.bluez5.device" /**< a Device interface */ -#define SPA_NAME_API_BLUEZ5_A2DP_SINK "api.bluez5.a2dp.sink" /**< a playback Node interface for A2DP profiles */ -#define SPA_NAME_API_BLUEZ5_A2DP_SOURCE "api.bluez5.a2dp.source" /**< a capture Node interface for A2DP profiles */ +#define SPA_NAME_API_BLUEZ5_MEDIA_SINK "api.bluez5.media.sink" /**< a playback Node interface for A2DP/BAP profiles */ +#define SPA_NAME_API_BLUEZ5_MEDIA_SOURCE "api.bluez5.media.source" /**< a capture Node interface for A2DP/BAP profiles */ +#define SPA_NAME_API_BLUEZ5_A2DP_SINK "api.bluez5.a2dp.sink" /**< alias for media.sink */ +#define SPA_NAME_API_BLUEZ5_A2DP_SOURCE "api.bluez5.a2dp.source" /**< alias for media.source */ #define SPA_NAME_API_BLUEZ5_SCO_SINK "api.bluez5.sco.sink" /**< a playback Node interface for HSP/HFP profiles */ #define SPA_NAME_API_BLUEZ5_SCO_SOURCE "api.bluez5.sco.source" /**< a capture Node interface for HSP/HFP profiles */ /** keys for codec factory names */ -#define SPA_NAME_API_CODEC_BLUEZ5_A2DP "api.codec.bluez5.a2dp" /**< Bluez5 A2DP codec plugin */ +#define SPA_NAME_API_CODEC_BLUEZ5_MEDIA "api.codec.bluez5.media" /**< Bluez5 Media codec plugin */ /** keys for v4l2 factory names */ #define SPA_NAME_API_V4L2_ENUM_UDEV "api.v4l2.enum.udev" /**< a v4l2 udev Device interface */
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/result.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/result.h
Changed
@@ -55,7 +55,7 @@ #define spa_strerror(err) \ ({ \ - int _err = -err; \ + int _err = -(err); \ if (SPA_RESULT_IS_ASYNC(err)) \ _err = EINPROGRESS; \ strerror(_err); \
View file
pipewire-0.3.58.tar.gz/spa/include/spa/utils/ringbuffer.h -> pipewire-0.3.59.tar.gz/spa/include/spa/utils/ringbuffer.h
Changed
@@ -53,7 +53,7 @@ uint32_t writeindex; /*< the current write index */ }; -#define SPA_RINGBUFFER_INIT() (struct spa_ringbuffer) { 0, 0 } +#define SPA_RINGBUFFER_INIT() ((struct spa_ringbuffer) { 0, 0 }) /** * Initialize a spa_ringbuffer with \a size.
View file
pipewire-0.3.58.tar.gz/spa/meson.build -> pipewire-0.3.59.tar.gz/spa/meson.build
Changed
@@ -64,6 +64,8 @@ summary({'LC3plus': lc3plus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') opus_dep = dependency('opus', required : get_option('bluez5-codec-opus')) summary({'Opus': opus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') + lc3_dep = dependency('lc3', required : get_option('bluez5-codec-lc3')) + summary({'LC3': lc3_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') endif avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg')) jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack'))
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/90-pipewire-alsa.rules -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/90-pipewire-alsa.rules
Changed
@@ -181,6 +181,9 @@ # have any digital outputs. ATTRS{idVendor}=="0a12", ATTRS{idProduct}=="4007", ENV{ACP_PROFILE_SET}="analog-only.conf" +# Asus Xonar SE +ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="189d", ENV{ACP_PROFILE_SET}="asus-xonar-se.conf" + GOTO="pipewire_end" LABEL="pipewire_check_pci"
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/acp-tool.c -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/acp-tool.c
Changed
@@ -584,6 +584,9 @@ return -errno; bufr = 0; + if (r == 0) + return -EPIPE; + if ((p = strchr(buf, '#'))) *p = '\0'; @@ -679,8 +682,12 @@ if (err < 0) return -errno; - if (pfds0.revents & POLLIN) - handle_input(data); + if (pfds0.revents & POLLIN) { + if ((err = handle_input(data)) < 0) { + if (err == -EPIPE) + break; + } + } if (count < 2) continue;
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/acp/acp.h -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/acp/acp.h
Changed
@@ -49,7 +49,7 @@ const char *key; const char *value; }; -#define ACP_DICT_ITEM_INIT(key,value) (struct acp_dict_item) { key, value } +#define ACP_DICT_ITEM_INIT(key,value) ((struct acp_dict_item) { (key), (value) }) struct acp_dict { uint32_t flags; @@ -115,8 +115,8 @@ uint32_t mapACP_MAX_CHANNELS; }; -#define ACP_DICT_INIT(items,n_items) (struct acp_dict) { 0, n_items, items } -#define ACP_DICT_INIT_ARRAY(items) (struct acp_dict) { 0, sizeof(items)/sizeof((items)0), items } +#define ACP_DICT_INIT(items,n_items) ((struct acp_dict) { 0, (n_items), (items) }) +#define ACP_DICT_INIT_ARRAY(items) ((struct acp_dict) { 0, sizeof(items)/sizeof((items)0), (items) }) #define acp_dict_for_each(item, dict) \ for ((item) = (dict)->items; \
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/acp/array.h -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/acp/array.h
Changed
@@ -39,7 +39,7 @@ size_t extend; /**< number of bytes to extend with */ } pa_array; -#define PW_ARRAY_INIT(extend) (struct pa_array) { NULL, 0, 0, extend } +#define PW_ARRAY_INIT(extend) ((struct pa_array) { NULL, 0, 0, (extend) }) #define pa_array_get_len_s(a,s) ((a)->size / (s)) #define pa_array_get_unchecked_s(a,idx,s,t) (t*)((uint8_t*)(a)->data + (int)((idx)*(s)))
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -511,6 +511,9 @@ } CHECK(snd_output_stdio_attach(&state->output, state->log_file, 0), "attach failed"); + state->rate_limit.interval = 2 * SPA_NSEC_PER_SEC; + state->rate_limit.burst = 1; + return 0; } @@ -1779,15 +1782,17 @@ static int get_avail(struct state *state, uint64_t current_time) { - int res; + int res, missed; snd_pcm_sframes_t avail; if (SPA_UNLIKELY((avail = snd_pcm_avail(state->hndl)) < 0)) { if ((res = alsa_recover(state, avail)) < 0) return res; if ((avail = snd_pcm_avail(state->hndl)) < 0) { - spa_log_warn(state->log, "%s: snd_pcm_avail after recover: %s", - state->props.device, snd_strerror(avail)); + if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) { + spa_log_warn(state->log, "%s: (%d missed) snd_pcm_avail after recover: %s", + state->props.device, missed, snd_strerror(avail)); + } avail = state->threshold * 2; } } else { @@ -1799,7 +1804,7 @@ #if 0 static int get_avail_htimestamp(struct state *state, uint64_t current_time) { - int res; + int res, missed; snd_pcm_uframes_t avail; snd_htimestamp_t tstamp; uint64_t then; @@ -1808,8 +1813,10 @@ if ((res = alsa_recover(state, avail)) < 0) return res; if ((res = snd_pcm_htimestamp(state->hndl, &avail, &tstamp)) < 0) { - spa_log_warn(state->log, "%s: snd_pcm_htimestamp error: %s", - state->props.device, snd_strerror(res)); + if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) { + spa_log_warn(state->log, "%s: (%d missed) snd_pcm_htimestamp error: %s", + state->props.device, missed, snd_strerror(res)); + } avail = state->threshold * 2; } } else { @@ -1880,15 +1887,14 @@ state, follower, state->last_threshold, state->threshold, diff, err); state->last_threshold = state->threshold; state->alsa_sync = true; + state->alsa_sync_warning = false; } if (err > state->max_error) { err = state->max_error; state->alsa_sync = true; - state->alsa_sync_warning = (diff == 0); } else if (err < -state->max_error) { err = -state->max_error; state->alsa_sync = true; - state->alsa_sync_warning = (diff == 0); } if (!follower || state->matching) @@ -1985,7 +1991,7 @@ const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t written, frames, offset, off, to_write, total_written, max_write; snd_pcm_sframes_t commitres; - int res = 0; + int res = 0, missed; size_t frame_size = state->frame_size; check_position_config(state); @@ -2005,13 +2011,18 @@ return res; if (SPA_UNLIKELY(state->alsa_sync)) { - if (SPA_UNLIKELY(state->alsa_sync_warning)) { - spa_log_warn(state->log, "%s: follower delay:%ld target:%ld thr:%u, resync", - state->props.device, delay, target, state->threshold); - state->alsa_sync_warning = false; - } else - spa_log_info(state->log, "%s: follower delay:%ld target:%ld thr:%u, resync", - state->props.device, delay, target, state->threshold); + enum spa_log_level lev; + + if (SPA_UNLIKELY(state->alsa_sync_warning)) + lev = SPA_LOG_LEVEL_WARN; + else + lev = SPA_LOG_LEVEL_INFO; + + if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) { + spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u, " + "resync (%d missed)", state->props.device, delay, + target, state->threshold, missed); + } if (delay > target) snd_pcm_rewind(state->hndl, delay - target); @@ -2019,7 +2030,8 @@ spa_alsa_silence(state, target - delay); delay = target; state->alsa_sync = false; - } + } else + state->alsa_sync_warning = true; } total_written = 0; @@ -2212,7 +2224,7 @@ const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t read, frames, offset; snd_pcm_sframes_t commitres; - int res = 0; + int res = 0, missed; check_position_config(state); @@ -2221,7 +2233,6 @@ if (state->following && state->alsa_started) { uint64_t current_time; snd_pcm_uframes_t avail, delay, target; - uint32_t threshold = state->threshold; current_time = state->position->clock.nsec; @@ -2234,13 +2245,18 @@ return res; if (state->alsa_sync) { - if (SPA_UNLIKELY(state->alsa_sync_warning)) { - spa_log_warn(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync", - state->props.device, delay, target, threshold); - state->alsa_sync_warning = false; - } else - spa_log_info(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync", - state->props.device, delay, target, threshold); + enum spa_log_level lev; + + if (SPA_UNLIKELY(state->alsa_sync_warning)) + lev = SPA_LOG_LEVEL_WARN; + else + lev = SPA_LOG_LEVEL_INFO; + + if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) { + spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u, " + "resync (%d missed)", state->props.device, delay, + target, state->threshold, missed); + } if (delay < target) max_read = target - delay; @@ -2248,7 +2264,8 @@ snd_pcm_forward(state->hndl, delay - target); delay = target; state->alsa_sync = false; - } + } else + state->alsa_sync_warning = true; if (avail < state->read_size) max_read = 0; @@ -2537,6 +2554,7 @@ reset_buffers(state); state->alsa_sync = true; + state->alsa_sync_warning = false; state->alsa_recovering = false; state->alsa_started = false;
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
@@ -87,7 +87,6 @@ uint32_t posSPA_AUDIO_MAX_CHANNELS; }; - struct card { struct spa_list link; int ref; @@ -98,6 +97,13 @@ uint32_t rate; }; +struct ratelimit { + uint64_t interval; + uint64_t begin; + unsigned burst; + unsigned n_printed, n_missed; +}; + struct state { struct spa_handle handle; struct spa_node node; @@ -107,6 +113,7 @@ struct spa_loop *data_loop; FILE *log_file; + struct ratelimit rate_limit; uint32_t card_index; struct card *card; @@ -342,6 +349,23 @@ return i; } +static inline int ratelimit_test(struct ratelimit *r, uint64_t now) +{ + unsigned missed = 0; + if (r->begin + r->interval < now) { + missed = r->n_missed; + r->begin = now; + r->n_printed = 0; + r->n_missed = 0; + } else if (r->n_printed >= r->burst) { + r->n_missed++; + return -1; + } + r->n_printed++; + return missed; +} + + #ifdef __cplusplus } /* extern "C" */ #endif
View file
pipewire-0.3.58.tar.gz/spa/plugins/alsa/alsa-udev.c -> pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-udev.c
Changed
@@ -256,7 +256,7 @@ /* Check device class */ spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s/pcm_class", devname); - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) return -errno; sz = fread(buf, 1, sizeof(buf) - 1, f); @@ -361,7 +361,7 @@ spa_scnprintf(path, sizeof(path), "/proc/asound/card%u/%s/%s/status", (unsigned int)device->id, entry->d_name, entry_pcm->d_name); - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) goto done; sz = fread(buf, 1, 6, f);
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/mixer/profile-sets/asus-xonar-se.conf
Added
@@ -0,0 +1,79 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. + +; ASUS Xonar SE card. +; This card has two devices for each rear and front panel jacks. +; +; See default.conf for an explanation on the directives used here. + +General +auto-profiles = yes + +Mapping analog-stereo-front +description = Analog Stereo Front +device-strings = hw:%f,1 +channel-map = left,right +paths-output = analog-output analog-output-headphones +paths-input = analog-input-mic analog-input-headphone-mic analog-input-headset-mic +priority = 15 + +Mapping analog-stereo-rear +description = Analog Stereo Rear +device-strings = hw:%f,0 +channel-map = left,right +paths-output = analog-output analog-output-speaker +paths-input = analog-input analog-input-mic analog-input-linein +priority = 14 + +Mapping analog-surround-21 +device-strings = surround21:%f +channel-map = front-left,front-right,lfe +paths-output = analog-output-speaker +priority = 13 +direction = output + +Mapping analog-surround-40 +device-strings = surround40:%f +channel-map = front-left,front-right,rear-left,rear-right +paths-output = analog-output-speaker +priority = 12 +direction = output + +Mapping analog-surround-41 +device-strings = surround41:%f +channel-map = front-left,front-right,rear-left,rear-right,lfe +paths-output = analog-output-speaker +priority = 13 +direction = output + +Mapping analog-surround-50 +device-strings = surround50:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center +paths-output = analog-output-speaker +priority = 12 +direction = output + +Mapping analog-surround-51 +device-strings = surround51:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +paths-output = analog-output-speaker +priority = 13 +direction = output + +Mapping iec958-stereo +device-strings = iec958:%f +channel-map = left,right +paths-output = iec958-stereo-output +priority = 5 \ No newline at end of file
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -336,7 +336,7 @@ struct spa_data *datas; uint32_t follower_flags, conv_flags; - spa_log_debug(this->log, "%p: %d", this, this->n_buffers); + spa_log_debug(this->log, "%p: n_buffers:%d", this, this->n_buffers); if (this->target == this->follower) return 0; @@ -738,6 +738,8 @@ struct spa_pod_builder b = { 0 }; int res; + spa_log_debug(this->log, "%p: have_format:%d", this, this->have_format); + if (this->have_format) return 0; @@ -746,7 +748,6 @@ spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_log_debug(this->log, "%p: negiotiate", this); spa_node_send_command(this->follower, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_ParamBegin)); @@ -813,6 +814,8 @@ switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Start: + if (this->started) + return 0; if ((res = negotiate_format(this)) < 0) return res; if ((res = negotiate_buffers(this)) < 0) @@ -821,11 +824,12 @@ case SPA_NODE_COMMAND_Suspend: configure_format(this, 0, NULL); SPA_FALLTHROUGH - case SPA_NODE_COMMAND_Flush: - this->io_buffers.status = SPA_STATUS_OK; - SPA_FALLTHROUGH case SPA_NODE_COMMAND_Pause: this->started = false; + spa_log_debug(this->log, "%p: stopped", this); + break; + case SPA_NODE_COMMAND_Flush: + this->io_buffers.status = SPA_STATUS_OK; break; default: break; @@ -849,6 +853,7 @@ switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Start: this->started = true; + spa_log_debug(this->log, "%p: started", this); break; } return res; @@ -1396,6 +1401,11 @@ struct impl *this = object; int status = 0, fstatus, retry = 8; + if (!this->started) { + spa_log_warn(this->log, "%p: scheduling stopped node", this); + return -EIO; + } + spa_log_trace_fp(this->log, "%p: process convert:%p driver:%d", this, this->convert, this->driver);
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -90,8 +90,8 @@ struct volumes monitor; unsigned int have_soft_volume:1; unsigned int mix_disabled:1; - unsigned int resample_quality; unsigned int resample_disabled:1; + unsigned int resample_quality; double rate; }; @@ -105,10 +105,11 @@ init_volumes(&props->channel); init_volumes(&props->soft); init_volumes(&props->monitor); + props->have_soft_volume = false; props->mix_disabled = false; - props->rate = 1.0; - props->resample_quality = RESAMPLE_DEFAULT_QUALITY; props->resample_disabled = false; + props->resample_quality = RESAMPLE_DEFAULT_QUALITY; + props->rate = 1.0; } struct buffer { @@ -215,7 +216,8 @@ uint32_t in_offset; uint32_t out_offset; unsigned int started:1; - unsigned int peaks:1; + unsigned int setup:1; + unsigned int resample_peaks:1; unsigned int is_passthrough:1; unsigned int drained:1; @@ -834,6 +836,8 @@ snprintf(value, sizeof(value), "%s", SPA_POD_VALUE(struct spa_pod_bool, pod) ? "true" : "false"); + } else if (spa_pod_is_none(pod)) { + spa_zero(value); } else continue; @@ -1353,7 +1357,7 @@ this->resample.quality = this->props.resample_quality; this->resample.cpu_flags = this->cpu_flags; - if (this->peaks) + if (this->resample_peaks) res = resample_peaks_init(&this->resample); else res = resample_native_init(&this->resample); @@ -1463,6 +1467,12 @@ in = &this->dirSPA_DIRECTION_INPUT; out = &this->dirSPA_DIRECTION_OUTPUT; + spa_log_debug(this->log, "%p: setup:%d in_format:%d out_format:%d", this, + this->setup, in->have_format, out->have_format); + + if (this->setup) + return 0; + if (!in->have_format || !out->have_format) return -EINVAL; @@ -1506,6 +1516,7 @@ this->tmp_datas1i = SPA_PTROFF(this->tmp1, this->empty_size * i, void); this->tmp_datas1i = SPA_PTR_ALIGN(this->tmp_datas1i, MAX_ALIGN, void); } + this->setup = true; emit_node_info(this, false); @@ -1537,13 +1548,14 @@ this->started = true; break; case SPA_NODE_COMMAND_Suspend: - SPA_FALLTHROUGH; - case SPA_NODE_COMMAND_Flush: - reset_node(this); + this->setup = false; SPA_FALLTHROUGH; case SPA_NODE_COMMAND_Pause: this->started = false; break; + case SPA_NODE_COMMAND_Flush: + reset_node(this); + break; default: return -ENOTSUP; } @@ -2467,6 +2479,7 @@ volume, mon_max); bd->chunk->size = mon_max * port->stride; + bd->chunk->stride = port->stride; spa_log_trace_fp(this->log, "%p: monitor %d %d", this, remap, mon_max); @@ -2667,9 +2680,10 @@ for (j = 0; j < port->blocks; j++) { bd = &buf->buf->datasj; bd->chunk->size = this->out_offset * port->stride; + bd->chunk->stride = port->stride; SPA_FLAG_UPDATE(bd->chunk->flags, SPA_CHUNK_FLAG_EMPTY, in_empty); - spa_log_trace_fp(this->log, "out: %d %d %d", this->out_offset, - port->stride, bd->chunk->size); + spa_log_trace_fp(this->log, "out: offs:%d stride:%d size:%d", + this->out_offset, port->stride, bd->chunk->size); } io->status = SPA_STATUS_HAVE_DATA; io->buffer_id = buf->id; @@ -2678,7 +2692,7 @@ this->drained = draining; this->out_offset = 0; } - else if (n_samples == 0 && this->peaks) { + else if (n_samples == 0 && this->resample_peaks) { for (i = 0; i < dir->n_ports; i++) { port = GET_OUT_PORT(this, i); if (port->is_monitor || port->is_control) @@ -2841,15 +2855,20 @@ if (spa_streq(k, "clock.quantum-limit")) spa_atou32(s, &this->quantum_limit, 0); else if (spa_streq(k, "resample.peaks")) - this->peaks = spa_atob(s); + this->resample_peaks = spa_atob(s); + else if (spa_streq(k, "resample.prefill")) + SPA_FLAG_UPDATE(this->resample.options, + RESAMPLE_OPTION_PREFILL, spa_atob(s)); else if (spa_streq(k, "factory.mode")) { if (spa_streq(s, "merge")) this->direction = SPA_DIRECTION_OUTPUT; else this->direction = SPA_DIRECTION_INPUT; } - else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) - this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s)); + else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { + if (s != NULL) + this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s)); + } else audioconvert_set_param(this, k, s); }
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/channelmix-ops-c.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops-c.c
Changed
@@ -46,6 +46,16 @@ dn = sn * vol; } } +static inline void conv_c(float *d, const float **s, float *c, uint32_t n_c, uint32_t n_samples) +{ + uint32_t n, j; + for (n = 0; n < n_samples; n++) { + float sum = 0.0f; + for (j = 0; j < n_c; j++) + sum += sjn * cj; + dn = sum; + } +} static inline void avg_c(float *d, const float *s0, const float *s1, uint32_t n_samples) { @@ -78,7 +88,7 @@ channelmix_f32_n_m_c(struct channelmix *mix, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples) { - uint32_t i, j, n, n_dst = mix->dst_chan, n_src = mix->src_chan; + uint32_t i, j, n_dst = mix->dst_chan, n_src = mix->src_chan; float **d = (float **) dst; const float **s = (const float **) src; @@ -94,16 +104,27 @@ clear_c(di, n_samples); } else { - for (n = 0; n < n_samples; n++) { - for (i = 0; i < n_dst; i++) { - float sum = 0.0f; - for (j = 0; j < n_src; j++) - sum += sjn * mix->matrixij; - din = sum; + for (i = 0; i < n_dst; i++) { + float *di = di; + float mjn_src; + const float *sjn_src; + uint32_t n_j = 0; + + for (j = 0; j < n_src; j++) { + if (mix->matrixij == 0.0f) + continue; + mjn_j = mix->matrixij; + sjn_j++ = sj; + } + if (n_j == 0) { + clear_c(di, n_samples); + } else if (n_j == 1) { + lr4_process(&mix->lr4i, di, sj0, mj0, n_samples); + } else { + conv_c(di, sj, mj, n_j, n_samples); + lr4_process(&mix->lr4i, di, di, 1.0f, n_samples); } } - for (i = 0; i < n_dst; i++) - lr4_process(&mix->lr4i, di, di, 1.0f, n_samples); } }
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/channelmix-ops-sse.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops-sse.c
Changed
@@ -68,6 +68,39 @@ } } +static inline void conv_sse(float *d, const float **s, float *c, uint32_t n_c, uint32_t n_samples) +{ + __m128 min_c, sum2; + uint32_t n, j, unrolled; + bool aligned = true; + + for (j = 0; j < n_c; j++) { + mij = _mm_set1_ps(cj); + aligned &= SPA_IS_ALIGNED(sj, 16); + } + + if (aligned && SPA_IS_ALIGNED(d, 16)) + unrolled = n_samples & ~7; + else + unrolled = 0; + + for (n = 0; n < unrolled; n += 8) { + sum0 = sum1 = _mm_setzero_ps(); + for (j = 0; j < n_c; j++) { + sum0 = _mm_add_ps(sum0, _mm_mul_ps(_mm_load_ps(&sjn + 0), mij)); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_load_ps(&sjn + 4), mij)); + } + _mm_store_ps(&dn + 0, sum0); + _mm_store_ps(&dn + 4, sum1); + } + for (; n < n_samples; n++) { + sum0 = _mm_setzero_ps(); + for (j = 0; j < n_c; j++) + sum0 = _mm_add_ss(sum0, _mm_mul_ss(_mm_load_ss(&sjn), mij)); + _mm_store_ss(&dn, sum0); + } +} + void channelmix_copy_sse(struct channelmix *mix, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples) { @@ -78,6 +111,40 @@ vol_sse(di, si, mix->matrixii, n_samples); } +void +channelmix_f32_n_m_sse(struct channelmix *mix, void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_samples) +{ + float **d = (float **) dst; + const float **s = (const float **) src; + uint32_t i, j, n_dst = mix->dst_chan, n_src = mix->src_chan; + + for (i = 0; i < n_dst; i++) { + float *di = di; + float mjn_src; + const float *sjn_src; + uint32_t n_j = 0; + + for (j = 0; j < n_src; j++) { + if (mix->matrixij == 0.0f) + continue; + mjn_j = mix->matrixij; + sjn_j++ = sj; + } + if (n_j == 0) { + clear_sse(di, n_samples); + } else if (n_j == 1) { + if (mix->lr4i.active) + lr4_process(&mix->lr4i, di, sj0, mj0, n_samples); + else + vol_sse(di, sj0, mj0, n_samples); + } else { + conv_sse(di, sj, mj, n_j, n_samples); + lr4_process(&mix->lr4i, di, di, 1.0f, n_samples); + } + } +} + /* FL+FR+FC+LFE -> FL+FR */ void channelmix_f32_3p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
@@ -94,6 +94,9 @@ MAKE(8, MASK_7_1, 4, MASK_QUAD, channelmix_f32_7p1_4_c), MAKE(8, MASK_7_1, 4, MASK_3_1, channelmix_f32_7p1_3p1_c), +#if defined (HAVE_SSE) + MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_sse), +#endif MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_c), }; #undef MAKE @@ -142,6 +145,8 @@ float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS = {{ 0.0f }}; uint64_t src_mask = mix->src_mask; uint64_t dst_mask = mix->dst_mask; + uint32_t src_chan = mix->src_chan; + uint32_t dst_chan = mix->dst_chan; uint64_t unassigned, keep; uint32_t i, j, ic, jc, matrix_encoding = MATRIX_NORMAL; float clev = SQRT1_2; @@ -157,7 +162,7 @@ /* move the MONO mask to FRONT so that the lower bits can be shifted * away. */ if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0) { - if (mix->src_chan == 1) + if (src_chan == 1) src_mask = 0; else src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC); @@ -171,19 +176,19 @@ /* unknown channels or just 1 channel */ if (src_mask == 0 || dst_mask == 0) { - if (mix->src_chan == 1) { + if (src_chan == 1) { /* one FC/MONO src goes everywhere */ - spa_log_debug(mix->log, "distribute FC/MONO"); + spa_log_debug(mix->log, "distribute FC/MONO (%f)", 1.0f); for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) matrixi0= 1.0f; - } else if (mix->dst_chan == 1) { + } else if (dst_chan == 1) { /* one FC/MONO dst get average of everything */ - spa_log_debug(mix->log, "average FC/MONO"); + spa_log_debug(mix->log, "average FC/MONO (%f)", 1.0f / src_chan); for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) - matrix0i= 1.0f / mix->src_chan; + matrix0i= 1.0f / src_chan; } else { /* just pair channels */ - spa_log_debug(mix->log, "pairing channels"); + spa_log_debug(mix->log, "pairing channels (%f)", 1.0f); for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) matrixii= 1.0f; } @@ -197,7 +202,7 @@ spa_log_debug(mix->log, "matching channels"); for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { if ((src_mask & dst_mask & (1ULL << i))) { - spa_log_debug(mix->log, "matched %u", i); + spa_log_debug(mix->log, "matched channel %u (%f)", i, 1.0f); matrixii= 1.0f; } } @@ -222,11 +227,12 @@ if (unassigned & FRONT){ if ((dst_mask & STEREO) == STEREO){ - spa_log_debug(mix->log, "assign FC to STEREO"); if(src_mask & STEREO) { + spa_log_debug(mix->log, "assign FC to STEREO (%f)", clev); _MATRIX(FL,FC) += clev; _MATRIX(FR,FC) += clev; } else { + spa_log_debug(mix->log, "assign FC to STEREO (%f)", SQRT1_2); _MATRIX(FL,FC) += SQRT1_2; _MATRIX(FR,FC) += SQRT1_2; } @@ -237,11 +243,13 @@ if (unassigned & STEREO){ if (dst_mask & FRONT) { - spa_log_debug(mix->log, "assign STEREO to FC"); + spa_log_debug(mix->log, "assign STEREO to FC (%f)", SQRT1_2); _MATRIX(FC,FL) += SQRT1_2; _MATRIX(FC,FR) += SQRT1_2; - if (src_mask & FRONT) + if (src_mask & FRONT) { + spa_log_debug(mix->log, "assign FC to FC (%f)", clev * SQRT2); _MATRIX(FC,FC) = clev * SQRT2; + } keep &= ~FRONT; } else { spa_log_warn(mix->log, "can't assign STEREO"); @@ -250,11 +258,11 @@ if (unassigned & _MASK(RC)) { if (dst_mask & REAR){ - spa_log_debug(mix->log, "assign RC to RL+RR"); + spa_log_debug(mix->log, "assign RC to RL+RR (%f)", SQRT1_2); _MATRIX(RL,RC) += SQRT1_2; _MATRIX(RR,RC) += SQRT1_2; } else if (dst_mask & SIDE) { - spa_log_debug(mix->log, "assign RC to SL+SR"); + spa_log_debug(mix->log, "assign RC to SL+SR (%f)", SQRT1_2); _MATRIX(SL,RC) += SQRT1_2; _MATRIX(SR,RC) += SQRT1_2; } else if(dst_mask & STEREO) { @@ -273,7 +281,7 @@ _MATRIX(FR,RC) += slev * SQRT1_2; } } else if (dst_mask & FRONT) { - spa_log_debug(mix->log, "assign RC to FC"); + spa_log_debug(mix->log, "assign RC to FC (%f)", slev * SQRT1_2); _MATRIX(FC,RC) += slev * SQRT1_2; } else { spa_log_warn(mix->log, "can't assign RC"); @@ -295,7 +303,7 @@ _MATRIX(SR,RR) += 1.0f; } } else if (dst_mask & STEREO) { - spa_log_debug(mix->log, "assign RL+RR to FL+FR %f", slev); + spa_log_debug(mix->log, "assign RL+RR to FL+FR (%f)", slev); if (matrix_encoding == MATRIX_DOLBY) { _MATRIX(FL,RL) -= slev * SQRT1_2; _MATRIX(FL,RR) -= slev * SQRT1_2; @@ -311,7 +319,8 @@ _MATRIX(FR,RR) += slev; } } else if (dst_mask & FRONT) { - spa_log_debug(mix->log, "assign RL+RR to FC"); + spa_log_debug(mix->log, "assign RL+RR to FC (%f)", + slev * SQRT1_2); _MATRIX(FC,RL)+= slev * SQRT1_2; _MATRIX(FC,RR)+= slev * SQRT1_2; } else { @@ -321,36 +330,41 @@ if (unassigned & SIDE) { if (dst_mask & REAR) { - spa_log_debug(mix->log, "assign SL+SR to RL+RR"); if (src_mask & _MASK(RL)) { + spa_log_debug(mix->log, "assign SL+SR to RL+RR (%f)", SQRT1_2); _MATRIX(RL,SL) += SQRT1_2; _MATRIX(RR,SR) += SQRT1_2; } else { + spa_log_debug(mix->log, "assign SL+SR to RL+RR (%f)", 1.0f); _MATRIX(RL,SL) += 1.0f; _MATRIX(RR,SR) += 1.0f; } } else if (dst_mask & _MASK(RC)) { - spa_log_debug(mix->log, "assign SL+SR to RC"); + spa_log_debug(mix->log, "assign SL+SR to RC (%f)", SQRT1_2); _MATRIX(RC,SL)+= SQRT1_2; _MATRIX(RC,SR)+= SQRT1_2; } else if (dst_mask & STEREO) { - spa_log_debug(mix->log, "assign SL+SR to FL+FR"); if (matrix_encoding == MATRIX_DOLBY) { + spa_log_debug(mix->log, "assign SL+SR to FL+FR (%f)", + slev * SQRT1_2); _MATRIX(FL,SL) -= slev * SQRT1_2; _MATRIX(FL,SR) -= slev * SQRT1_2; _MATRIX(FR,SL) += slev * SQRT1_2; _MATRIX(FR,SR) += slev * SQRT1_2; } else if (matrix_encoding == MATRIX_DPLII) { + spa_log_debug(mix->log, "assign SL+SR to FL+FR (%f / %f)", + slev * SQRT3_2, slev * SQRT1_2); _MATRIX(FL,SL) -= slev * SQRT3_2; _MATRIX(FL,SR) -= slev * SQRT1_2; _MATRIX(FR,SL) += slev * SQRT1_2; _MATRIX(FR,SR) += slev * SQRT3_2; } else { + spa_log_debug(mix->log, "assign SL+SR to FL+FR (%f)", slev); _MATRIX(FL,SL) += slev; _MATRIX(FR,SR) += slev; } } else if (dst_mask & FRONT) { - spa_log_debug(mix->log, "assign SL+SR to FC"); + spa_log_debug(mix->log, "assign SL+SR to FC (%f)", slev * SQRT1_2); _MATRIX(FC,SL) += slev * SQRT1_2; _MATRIX(FC,SR) += slev * SQRT1_2; } else { @@ -360,11 +374,11 @@ if (unassigned & _MASK(FLC)) { if (dst_mask & STEREO) { - spa_log_debug(mix->log, "assign FLC+FRC to FL+FR"); + spa_log_debug(mix->log, "assign FLC+FRC to FL+FR (%f)", 1.0f); _MATRIX(FL,FLC)+= 1.0f; _MATRIX(FR,FRC)+= 1.0f; } else if(dst_mask & FRONT) { - spa_log_debug(mix->log, "assign FLC+FRC to FC"); + spa_log_debug(mix->log, "assign FLC+FRC to FC (%f)", SQRT1_2); _MATRIX(FC,FLC)+= SQRT1_2; _MATRIX(FC,FRC)+= SQRT1_2; } else { @@ -374,10 +388,11 @@ if (unassigned & _MASK(LFE) && SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_MIX_LFE)) { if (dst_mask & FRONT) { - spa_log_debug(mix->log, "assign LFE to FC");
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/channelmix-ops.h -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops.h
Changed
@@ -147,6 +147,7 @@ #if defined (HAVE_SSE) DEFINE_FUNCTION(copy, sse); +DEFINE_FUNCTION(f32_n_m, sse); DEFINE_FUNCTION(f32_3p1_2, sse); DEFINE_FUNCTION(f32_5p1_2, sse); DEFINE_FUNCTION(f32_5p1_3p1, sse);
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/fmt-ops-c.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops-c.c
Changed
@@ -230,38 +230,57 @@ return (int32_t)(*state); } -static inline void update_noise_c(struct convert *conv, uint32_t n_samples) +void conv_noise_none_c(struct convert *conv, float *noise, uint32_t n_samples) +{ + memset(noise, 0, n_samples * sizeof(float)); +} + +void conv_noise_rect_c(struct convert *conv, float *noise, uint32_t n_samples) +{ + uint32_t n; + uint32_t *state = &conv->random0; + const float scale = conv->scale; + + for (n = 0; n < n_samples; n++) + noisen = lcnoise(state) * scale; +} + +void conv_noise_tri_c(struct convert *conv, float *noise, uint32_t n_samples) +{ + uint32_t n; + const float scale = conv->scale; + uint32_t *state = &conv->random0; + + for (n = 0; n < n_samples; n++) + noisen = (lcnoise(state) - lcnoise(state)) * scale; +} + +void conv_noise_tri_hf_c(struct convert *conv, float *noise, uint32_t n_samples) { uint32_t n; - float *noise = conv->noise, scale = conv->scale; + const float scale = conv->scale; uint32_t *state = &conv->random0; int32_t *prev = &conv->prev0, old, new; - switch (conv->noise_method) { - case NOISE_METHOD_RECTANGULAR: - for (n = 0; n < n_samples; n++) - noisen = lcnoise(state) * scale; - break; - case NOISE_METHOD_TRIANGULAR: - for (n = 0; n < n_samples; n++) - noisen = (lcnoise(state) - lcnoise(state)) * scale; - break; - case NOISE_METHOD_TRIANGULAR_HF: - old = *prev; - for (n = 0; n < n_samples; n++) { - new = lcnoise(state); - noisen = (new - old) * scale; - old = new; - } - *prev = old; - break; - case NOISE_METHOD_PATTERN: - old = *prev; - for (n = 0; n < n_samples; n++) - noisen = conv->scale * (1-((old++>>10)&1)); - *prev = old; - break; + old = *prev; + for (n = 0; n < n_samples; n++) { + new = lcnoise(state); + noisen = (new - old) * scale; + old = new; } + *prev = old; +} + +void conv_noise_pattern_c(struct convert *conv, float *noise, uint32_t n_samples) +{ + uint32_t n; + const float scale = conv->scale; + int32_t *prev = &conv->prev0, old; + + old = *prev; + for (n = 0; n < n_samples; n++) + noisen = scale * (1-((old++>>10)&1)); + *prev = old; } #define MAKE_D_noise(dname,dtype,func) \ @@ -271,7 +290,7 @@ { \ uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size; \ float *noise = conv->noise; \ - update_noise_c(conv, SPA_MIN(n_samples, noise_size)); \ + convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size)); \ for (i = 0; i < n_channels; i++) { \ const float *s = srci; \ dtype *d = dsti; \ @@ -292,7 +311,7 @@ dtype *d = dst0; \ uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size; \ float *noise = conv->noise; \ - update_noise_c(conv, SPA_MIN(n_samples, noise_size)); \ + convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size)); \ for (j = 0; j < n_samples;) { \ chunk = SPA_MIN(n_samples - j, noise_size); \ for (k = 0; k < chunk; k++, j++) { \ @@ -342,9 +361,10 @@ uint32_t n_samples) \ { \ uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size; \ - const float *noise = conv->noise, *ns = conv->ns; \ + float *noise = conv->noise; \ + const float *ns = conv->ns; \ uint32_t n, n_ns = conv->n_ns; \ - update_noise_c(conv, SPA_MIN(n_samples, noise_size)); \ + convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size)); \ for (i = 0; i < n_channels; i++) { \ const float *s = srci; \ dtype *d = dsti; \ @@ -366,9 +386,10 @@ { \ dtype *d0 = dst0; \ uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size; \ - const float *noise = conv->noise, *ns = conv->ns; \ + float *noise = conv->noise; \ + const float *ns = conv->ns; \ uint32_t n, n_ns = conv->n_ns; \ - update_noise_c(conv, SPA_MIN(n_samples, noise_size)); \ + convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size)); \ for (i = 0; i < n_channels; i++) { \ const float *s = srci; \ dtype *d = &d0i; \
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/fmt-ops-sse2.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops-sse2.c
Changed
@@ -576,61 +576,64 @@ i; \ }) +void conv_noise_rect_sse2(struct convert *conv, float *noise, uint32_t n_samples) +{ + uint32_t n; + const uint32_t *r = conv->random; + __m128 scale = _mm_set1_ps(conv->scale); + __m128i in1; + __m128 out1; + + for (n = 0; n < n_samples; n += 4) { + in0 = _MM_XORSHIFT_EPI32(r); + out0 = _mm_cvtepi32_ps(in0); + out0 = _mm_mul_ps(out0, scale); + _mm_store_ps(&noisen, out0); + } +} -static inline void update_noise_sse2(struct convert *conv, uint32_t n_samples) +void conv_noise_tri_sse2(struct convert *conv, float *noise, uint32_t n_samples) { uint32_t n; - const uint32_t *r = SPA_PTR_ALIGN(conv->random, 16, uint32_t); - int32_t *p = SPA_PTR_ALIGN(conv->prev, 16, int32_t), op; + const uint32_t *r = conv->random; __m128 scale = _mm_set1_ps(conv->scale); + __m128i in1; __m128 out1; - float *noise = SPA_PTR_ALIGN(conv->noise, 16, float); + + for (n = 0; n < n_samples; n += 4) { + in0 = _mm_sub_epi32( _MM_XORSHIFT_EPI32(r), _MM_XORSHIFT_EPI32(r)); + out0 = _mm_cvtepi32_ps(in0); + out0 = _mm_mul_ps(out0, scale); + _mm_store_ps(&noisen, out0); + } +} + +void conv_noise_tri_hf_sse2(struct convert *conv, float *noise, uint32_t n_samples) +{ + uint32_t n; + int32_t *p = conv->prev; + const uint32_t *r = conv->random; + __m128 scale = _mm_set1_ps(conv->scale); __m128i in1, old1, new1; + __m128 out1; - switch (conv->noise_method) { - case DITHER_METHOD_RECTANGULAR: - for (n = 0; n < n_samples; n += 4) { - in0 = _MM_XORSHIFT_EPI32(r); - out0 = _mm_cvtepi32_ps(_MM_XORSHIFT_EPI32(r)); - out0 = _mm_mul_ps(out0, scale); - _mm_store_ps(&noisen, out0); - } - break; - case DITHER_METHOD_TRIANGULAR: - for (n = 0; n < n_samples; n += 4) { - in0 = _mm_sub_epi32( _MM_XORSHIFT_EPI32(r), _MM_XORSHIFT_EPI32(r)); - out0 = _mm_cvtepi32_ps(in0); - out0 = _mm_mul_ps(out0, scale); - _mm_store_ps(&noisen, out0); - } - break; - case DITHER_METHOD_TRIANGULAR_HF: - old0 = _mm_load_si128((__m128i*)p); - for (n = 0; n < n_samples; n += 4) { - new0 = _MM_XORSHIFT_EPI32(r); - in0 = _mm_sub_epi32(old0, new0); - old0 = new0; - out0 = _mm_cvtepi32_ps(in0); - out0 = _mm_mul_ps(out0, scale); - _mm_store_ps(&noisen, out0); - } - _mm_store_si128((__m128i*)p, old0); - break; - case NOISE_METHOD_PATTERN: - op = *p; - for (n = 0; n < n_samples; n++) - noisen = conv->scale * (1-((op++>>10)&1)); - *p = op; - break; + old0 = _mm_load_si128((__m128i*)p); + for (n = 0; n < n_samples; n += 4) { + new0 = _MM_XORSHIFT_EPI32(r); + in0 = _mm_sub_epi32(old0, new0); + old0 = new0; + out0 = _mm_cvtepi32_ps(in0); + out0 = _mm_mul_ps(out0, scale); + _mm_store_ps(&noisen, out0); } + _mm_store_si128((__m128i*)p, old0); } static void conv_f32d_to_s32_1s_noise_sse2(struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, - uint32_t n_channels, uint32_t n_samples) + float *noise, uint32_t n_channels, uint32_t n_samples) { const float *s = src; - float *noise = SPA_PTR_ALIGN(conv->noise, 16, float); int32_t *d = dst; uint32_t n, unrolled; __m128 in1; @@ -676,14 +679,16 @@ { int32_t *d = dst0; uint32_t i, k, chunk, n_channels = conv->n_channels; + float *noise = conv->noise; - update_noise_sse2(conv, SPA_MIN(n_samples, conv->noise_size)); + convert_update_noise(conv, noise, SPA_MIN(n_samples, conv->noise_size)); for(i = 0; i < n_channels; i++) { const float *s = srci; for(k = 0; k < n_samples; k += chunk) { chunk = SPA_MIN(n_samples - k, conv->noise_size); - conv_f32d_to_s32_1s_noise_sse2(conv, &di + k*n_channels, &sk, n_channels, chunk); + conv_f32d_to_s32_1s_noise_sse2(conv, &di + k*n_channels, + &sk, noise, n_channels, chunk); } } } @@ -1261,11 +1266,10 @@ static void conv_f32d_to_s16_1s_noise_sse2(struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, - uint32_t n_channels, uint32_t n_samples) + const float *noise, uint32_t n_channels, uint32_t n_samples) { const float *s0 = src; int16_t *d = dst; - float *noise = SPA_PTR_ALIGN(conv->noise, 16, float); uint32_t n, unrolled; __m128 in2; __m128i out2; @@ -1312,25 +1316,26 @@ { int16_t *d = dst0; uint32_t i, k, chunk, n_channels = conv->n_channels; + float *noise = conv->noise; - update_noise_sse2(conv, SPA_MIN(n_samples, conv->noise_size)); + convert_update_noise(conv, noise, SPA_MIN(n_samples, conv->noise_size)); for(i = 0; i < n_channels; i++) { const float *s = srci; for(k = 0; k < n_samples; k += chunk) { chunk = SPA_MIN(n_samples - k, conv->noise_size); - conv_f32d_to_s16_1s_noise_sse2(conv, &di + k*n_channels, &sk, n_channels, chunk); + conv_f32d_to_s16_1s_noise_sse2(conv, &di + k*n_channels, + &sk, noise, n_channels, chunk); } } } static void conv_f32_to_s16_1_noise_sse2(struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, - uint32_t n_samples) + const float *noise, uint32_t n_samples) { const float *s = src; int16_t *d = dst; - float *noise = SPA_PTR_ALIGN(conv->noise, 16, float); uint32_t n, unrolled; __m128 in2; __m128i out2; @@ -1366,15 +1371,16 @@ uint32_t n_samples) { uint32_t i, k, chunk, n_channels = conv->n_channels; + float *noise = conv->noise; - update_noise_sse2(conv, SPA_MIN(n_samples, conv->noise_size)); + convert_update_noise(conv, noise, SPA_MIN(n_samples, conv->noise_size)); for(i = 0; i < n_channels; i++) { const float *s = srci; int16_t *d = dsti; for(k = 0; k < n_samples; k += chunk) { chunk = SPA_MIN(n_samples - k, conv->noise_size); - conv_f32_to_s16_1_noise_sse2(conv, &dk, &sk, chunk); + conv_f32_to_s16_1_noise_sse2(conv, &dk, &sk, noise, chunk); } } }
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/fmt-ops.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops.c
Changed
@@ -32,7 +32,8 @@ #include "fmt-ops.h" -#define DITHER_SIZE (1<<10) +#define NOISE_SIZE (1<<10) +#define RANDOM_SIZE (16) typedef void (*convert_func_t) (struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples); @@ -359,7 +360,6 @@ uint32_t n_channels, uint32_t cpu_flags, uint32_t conv_flags) { size_t i; - for (i = 0; i < SPA_N_ELEMENTS(conv_table); i++) { if (conv_tablei.src_fmt == src_fmt && conv_tablei.dst_fmt == dst_fmt && @@ -371,11 +371,52 @@ return NULL; } +typedef void (*noise_func_t) (struct convert *conv, float * noise, uint32_t n_samples); + +struct noise_info { + uint32_t method; + + noise_func_t noise; + const char *name; + + uint32_t cpu_flags; +}; + +#define MAKE(method,func,...) \ + { NOISE_METHOD_ ##method, func, #func , __VA_ARGS__ } + +static struct noise_info noise_table = +{ +#if defined (HAVE_SSE2) + MAKE(RECTANGULAR, conv_noise_rect_sse2, SPA_CPU_FLAG_SSE2), + MAKE(TRIANGULAR, conv_noise_tri_sse2, SPA_CPU_FLAG_SSE2), + MAKE(TRIANGULAR_HF, conv_noise_tri_hf_sse2, SPA_CPU_FLAG_SSE2), +#endif + MAKE(NONE, conv_noise_none_c), + MAKE(RECTANGULAR, conv_noise_rect_c), + MAKE(TRIANGULAR, conv_noise_tri_c), + MAKE(TRIANGULAR_HF, conv_noise_tri_hf_c), + MAKE(PATTERN, conv_noise_pattern_c), +}; +#undef MAKE + +static const struct noise_info *find_noise_info(uint32_t method, + uint32_t cpu_flags) +{ + size_t i; + for (i = 0; i < SPA_N_ELEMENTS(noise_table); i++) { + if (noise_tablei.method == method && + MATCH_CPU_FLAGS(noise_tablei.cpu_flags, cpu_flags)) + return &noise_tablei; + } + return NULL; +} + static void impl_convert_free(struct convert *conv) { conv->process = NULL; - free(conv->noise); - conv->noise = NULL; + free(conv->data); + conv->data = NULL; } static bool need_dither(uint32_t format) @@ -449,7 +490,8 @@ { const struct conv_info *info; const struct dither_info *dinfo; - uint32_t i, conv_flags; + const struct noise_info *ninfo; + uint32_t i, conv_flags, data_size3; conv->scale = 1.0f / (float)(INT32_MAX); @@ -494,17 +536,31 @@ if (info == NULL) return -ENOTSUP; - conv->noise_size = DITHER_SIZE; - conv->noise = calloc(conv->noise_size + 16 + - FMT_OPS_MAX_ALIGN / sizeof(float), sizeof(float)); - if (conv->noise == NULL) + ninfo = find_noise_info(conv->noise_method, conv->cpu_flags); + if (ninfo == NULL) + return -ENOTSUP; + + conv->noise_size = NOISE_SIZE; + + data_size0 = SPA_ROUND_UP(conv->noise_size * sizeof(float), FMT_OPS_MAX_ALIGN); + data_size1 = SPA_ROUND_UP(RANDOM_SIZE * sizeof(uint32_t), FMT_OPS_MAX_ALIGN); + data_size2 = SPA_ROUND_UP(RANDOM_SIZE * sizeof(int32_t), FMT_OPS_MAX_ALIGN); + + conv->data = calloc(FMT_OPS_MAX_ALIGN + + data_size0 + data_size1 + data_size2, 1); + if (conv->data == NULL) return -errno; - for (i = 0; i < SPA_N_ELEMENTS(conv->random); i++) + conv->noise = SPA_PTR_ALIGN(conv->data, FMT_OPS_MAX_ALIGN, float); + conv->random = SPA_PTROFF(conv->noise, data_size0, uint32_t); + conv->prev = SPA_PTROFF(conv->random, data_size1, int32_t); + + for (i = 0; i < RANDOM_SIZE; i++) conv->randomi = random(); conv->is_passthrough = conv->src_fmt == conv->dst_fmt; conv->cpu_flags = info->cpu_flags; + conv->update_noise = ninfo->noise; conv->process = info->process; conv->free = impl_convert_free; conv->func_name = info->name;
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/fmt-ops.h -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops.h
Changed
@@ -226,8 +226,8 @@ unsigned int is_passthrough:1; float scale; - uint32_t random16 + FMT_OPS_MAX_ALIGN/4; - int32_t prev16 + FMT_OPS_MAX_ALIGN/4; + uint32_t *random; + int32_t *prev; #define NOISE_METHOD_NONE 0 #define NOISE_METHOD_RECTANGULAR 1 #define NOISE_METHOD_TRIANGULAR 2 @@ -240,9 +240,12 @@ uint32_t n_ns; struct shaper shaper64; + void (*update_noise) (struct convert *conv, float *noise, uint32_t n_samples); void (*process) (struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples); void (*free) (struct convert *conv); + + void *data; }; int convert_init(struct convert *conv); @@ -276,12 +279,30 @@ return DITHER_METHOD_NONE; } +#define convert_update_noise(conv,...) (conv)->update_noise(conv, __VA_ARGS__) #define convert_process(conv,...) (conv)->process(conv, __VA_ARGS__) #define convert_free(conv) (conv)->free(conv) -#define DEFINE_FUNCTION(name,arch) \ +#define DEFINE_NOISE_FUNCTION(name,arch) \ +void conv_noise_##name##_##arch(struct convert *conv, float *noise, \ + uint32_t n_samples) + +DEFINE_NOISE_FUNCTION(none, c); +DEFINE_NOISE_FUNCTION(rect, c); +DEFINE_NOISE_FUNCTION(tri, c); +DEFINE_NOISE_FUNCTION(tri_hf, c); +DEFINE_NOISE_FUNCTION(pattern, c); +#if defined(HAVE_SSE2) +DEFINE_NOISE_FUNCTION(rect, sse2); +DEFINE_NOISE_FUNCTION(tri, sse2); +DEFINE_NOISE_FUNCTION(tri_hf, sse2); +#endif + +#undef DEFINE_NOISE_FUNCTION + +#define DEFINE_FUNCTION(name,arch) \ void conv_##name##_##arch(struct convert *conv, void * SPA_RESTRICT dst, \ - const void * SPA_RESTRICT src, uint32_t n_samples) \ + const void * SPA_RESTRICT src, uint32_t n_samples) DEFINE_FUNCTION(copy8d, c); DEFINE_FUNCTION(copy8, c);
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/meson.build -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/meson.build
Changed
@@ -12,8 +12,8 @@ 'biquad.c', 'crossover.c', 'volume-ops-c.c', + 'peaks-ops-c.c', 'resample-native-c.c', - 'resample-peaks-c.c', 'fmt-ops-c.c' , c_args : '-Ofast', '-ffast-math', dependencies : spa_dep , @@ -24,8 +24,8 @@ if have_sse audioconvert_sse = static_library('audioconvert_sse', 'resample-native-sse.c', - 'resample-peaks-sse.c', 'volume-ops-sse.c', + 'peaks-ops-sse.c', 'channelmix-ops-sse.c' , c_args : sse_args, '-Ofast', '-DHAVE_SSE', dependencies : spa_dep , @@ -101,6 +101,7 @@ audioconvert_lib = static_library('audioconvert', 'fmt-ops.c', 'channelmix-ops.c', + 'peaks-ops.c', 'resample-native.c', 'resample-peaks.c', 'volume-ops.c' , @@ -132,6 +133,7 @@ 'test-audioconvert', 'test-channelmix', 'test-fmt-ops', + 'test-peaks', 'test-resample',
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops-c.c
Added
@@ -0,0 +1,50 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <math.h> + +#include "peaks-ops.h" + +void peaks_min_max_c(struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float *min, float *max) +{ + uint32_t n; + float t, mi = *min, ma = *max; + for (n = 0; n < n_samples; n++) { + t = srcn; + mi = fminf(mi, t); + ma = fmaxf(ma, t); + } + *min = mi; + *max = ma; +} + +float peaks_abs_max_c(struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float max) +{ + uint32_t n; + for (n = 0; n < n_samples; n++) + max = fmaxf(fabsf(srcn), max); + return max; +}
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops-sse.c
Added
@@ -0,0 +1,122 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <math.h> + +#include <xmmintrin.h> + +#include "peaks-ops.h" + +static inline float hmin_ps(__m128 val) +{ + __m128 t = _mm_movehl_ps(val, val); + t = _mm_min_ps(t, val); + val = _mm_shuffle_ps(t, t, 0x55); + val = _mm_min_ss(t, val); + return _mm_cvtss_f32(val); +} + +static inline float hmax_ps(__m128 val) +{ + __m128 t = _mm_movehl_ps(val, val); + t = _mm_max_ps(t, val); + val = _mm_shuffle_ps(t, t, 0x55); + val = _mm_max_ss(t, val); + return _mm_cvtss_f32(val); +} + +void peaks_min_max_sse(struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float *min, float *max) +{ + uint32_t n; + __m128 in; + __m128 mi = _mm_set1_ps(*min); + __m128 ma = _mm_set1_ps(*max); + + for (n = 0; n < n_samples; n++) { + if (SPA_IS_ALIGNED(&srcn, 16)) + break; + in = _mm_set1_ps(srcn); + mi = _mm_min_ps(mi, in); + ma = _mm_max_ps(ma, in); + } + for (; n + 15 < n_samples; n += 16) { + in = _mm_load_ps(&srcn + 0); + mi = _mm_min_ps(mi, in); + ma = _mm_max_ps(ma, in); + in = _mm_load_ps(&srcn + 4); + mi = _mm_min_ps(mi, in); + ma = _mm_max_ps(ma, in); + in = _mm_load_ps(&srcn + 8); + mi = _mm_min_ps(mi, in); + ma = _mm_max_ps(ma, in); + in = _mm_load_ps(&srcn + 12); + mi = _mm_min_ps(mi, in); + ma = _mm_max_ps(ma, in); + } + for (; n < n_samples; n++) { + in = _mm_set1_ps(srcn); + mi = _mm_min_ps(mi, in); + ma = _mm_max_ps(ma, in); + } + *min = hmin_ps(mi); + *max = hmax_ps(ma); +} + +float peaks_abs_max_sse(struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float max) +{ + uint32_t n; + __m128 in; + __m128 ma = _mm_set1_ps(max); + const __m128 mask = _mm_set1_ps(-0.0f); + + for (n = 0; n < n_samples; n++) { + if (SPA_IS_ALIGNED(&srcn, 16)) + break; + in = _mm_set1_ps(srcn); + in = _mm_andnot_ps(mask, in); + ma = _mm_max_ps(ma, in); + } + for (; n + 15 < n_samples; n += 16) { + in = _mm_load_ps(&srcn + 0); + in = _mm_andnot_ps(mask, in); + ma = _mm_max_ps(ma, in); + in = _mm_load_ps(&srcn + 4); + in = _mm_andnot_ps(mask, in); + ma = _mm_max_ps(ma, in); + in = _mm_load_ps(&srcn + 8); + in = _mm_andnot_ps(mask, in); + ma = _mm_max_ps(ma, in); + in = _mm_load_ps(&srcn + 12); + in = _mm_andnot_ps(mask, in); + ma = _mm_max_ps(ma, in); + } + for (; n < n_samples; n++) { + in = _mm_set1_ps(srcn); + in = _mm_andnot_ps(mask, in); + ma = _mm_max_ps(ma, in); + } + return hmax_ps(ma); +}
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops.c
Added
@@ -0,0 +1,91 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <errno.h> + +#include <spa/support/cpu.h> +#include <spa/support/log.h> +#include <spa/utils/defs.h> + +#include "peaks-ops.h" + +typedef void (*peaks_min_max_func_t) (struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float *min, float *max); +typedef float (*peaks_abs_max_func_t) (struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float max); + +#define MAKE(min_max,abs_max,...) \ + { min_max, abs_max, #min_max , __VA_ARGS__ } + +static const struct peaks_info { + peaks_min_max_func_t min_max; + peaks_abs_max_func_t abs_max; + const char *name; + uint32_t cpu_flags; +} peaks_table = +{ +#if defined (HAVE_SSE) + MAKE(peaks_min_max_sse, peaks_abs_max_sse, SPA_CPU_FLAG_SSE), +#endif + MAKE(peaks_min_max_c, peaks_abs_max_c), +}; +#undef MAKE + +#define MATCH_CPU_FLAGS(a,b) ((a) == 0 || ((a) & (b)) == a) + +static const struct peaks_info *find_peaks_info(uint32_t cpu_flags) +{ + size_t i; + for (i = 0; i < SPA_N_ELEMENTS(peaks_table); i++) { + if (!MATCH_CPU_FLAGS(peaks_tablei.cpu_flags, cpu_flags)) + continue; + return &peaks_tablei; + } + return NULL; +} + +static void impl_peaks_free(struct peaks *peaks) +{ + peaks->min_max = NULL; + peaks->abs_max = NULL; +} + +int peaks_init(struct peaks *peaks) +{ + const struct peaks_info *info; + + info = find_peaks_info(peaks->cpu_flags); + if (info == NULL) + return -ENOTSUP; + + peaks->cpu_flags = info->cpu_flags; + peaks->func_name = info->name; + peaks->free = impl_peaks_free; + peaks->min_max = info->min_max; + peaks->abs_max = info->abs_max; + return 0; +}
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops.h
Added
@@ -0,0 +1,72 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> + +#include <spa/utils/defs.h> + +struct peaks { + uint32_t cpu_flags; + const char *func_name; + + struct spa_log *log; + + uint32_t flags; + + void (*min_max) (struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float *min, float *max); + float (*abs_max) (struct peaks *peaks, const float * SPA_RESTRICT src, + uint32_t n_samples, float max); + + void (*free) (struct peaks *peaks); +}; + +int peaks_init(struct peaks *peaks); + +#define peaks_min_max(peaks,...) (peaks)->min_max(peaks, __VA_ARGS__) +#define peaks_abs_max(peaks,...) (peaks)->abs_max(peaks, __VA_ARGS__) +#define peaks_free(peaks) (peaks)->free(peaks) + +#define DEFINE_MIN_MAX_FUNCTION(arch) \ +void peaks_min_max_##arch(struct peaks *peaks, \ + const float * SPA_RESTRICT src, \ + uint32_t n_samples, float *min, float *max); + +#define DEFINE_ABS_MAX_FUNCTION(arch) \ +float peaks_abs_max_##arch(struct peaks *peaks, \ + const float * SPA_RESTRICT src, \ + uint32_t n_samples, float max); + +#define PEAKS_OPS_MAX_ALIGN 16 + +DEFINE_MIN_MAX_FUNCTION(c); +DEFINE_ABS_MAX_FUNCTION(c); + +#if defined (HAVE_SSE) +DEFINE_MIN_MAX_FUNCTION(sse); +DEFINE_ABS_MAX_FUNCTION(sse); +#endif + +#undef DEFINE_FUNCTION
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-native.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/resample-native.c
Changed
@@ -304,7 +304,10 @@ if (d == NULL) return; memset(d->hist_mem, 0, r->channels * sizeof(float) * d->n_taps * 2); - d->hist = (d->n_taps / 2) - 1; + if (r->options & RESAMPLE_OPTION_PREFILL) + d->hist = d->n_taps - 1; + else + d->hist = (d->n_taps / 2) - 1; d->phase = 0; }
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/resample-peaks.c
Changed
@@ -27,40 +27,70 @@ #include <spa/param/audio/format.h> -#include "resample-peaks-impl.h" - -struct resample_info { - uint32_t format; - uint32_t cpu_flags; - void (*process) (struct resample *r, - const void * SPA_RESTRICT src, uint32_t *in_len, - void * SPA_RESTRICT dst, uint32_t *out_len); +#include "peaks-ops.h" +#include "resample.h" + +struct peaks_data { + uint32_t o_count; + uint32_t i_count; + struct peaks peaks; + float max_f; }; -static struct resample_info resample_table = +static void resample_peaks_process(struct resample *r, + const void * SPA_RESTRICT src, uint32_t *in_len, + void * SPA_RESTRICT dst, uint32_t *out_len) { -#if defined (HAVE_SSE) - { SPA_AUDIO_FORMAT_F32, SPA_CPU_FLAG_SSE, resample_peaks_process_sse, }, -#endif - { SPA_AUDIO_FORMAT_F32, 0, resample_peaks_process_c, }, -}; + struct peaks_data *pd = r->data; + uint32_t c, i, o, end, chunk, i_count, o_count; -#define MATCH_CPU_FLAGS(a,b) ((a) == 0 || ((a) & (b)) == a) -static const struct resample_info *find_resample_info(uint32_t format, uint32_t cpu_flags) -{ - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(resample_table); i++) { - if (resample_tablei.format == format && - MATCH_CPU_FLAGS(resample_tablei.cpu_flags, cpu_flags)) { - return &resample_tablei; + if (SPA_UNLIKELY(r->channels == 0)) + return; + + for (c = 0; c < r->channels; c++) { + const float *s = srcc; + float *d = dstc, m = pd->max_fc; + + o_count = pd->o_count; + i_count = pd->i_count; + o = i = 0; + + while (i < *in_len && o < *out_len) { + end = ((uint64_t) (o_count + 1) + * r->i_rate) / r->o_rate; + end = end > i_count ? end - i_count : 0; + chunk = SPA_MIN(end, *in_len); + + m = peaks_abs_max(&pd->peaks, &si, chunk - i, m); + + i += chunk; + + if (i == end) { + do++ = m; + m = 0.0f; + o_count++; + } } + pd->max_fc = m; + } + *out_len = o; + *in_len = i; + pd->o_count = o_count; + pd->i_count = i_count + i; + + while (pd->i_count >= r->i_rate) { + pd->i_count -= r->i_rate; + pd->o_count -= r->o_rate; } - return NULL; } static void impl_peaks_free(struct resample *r) { - free(r->data); + struct peaks_data *d = r->data; + if (d != NULL) { + peaks_free(&d->peaks); + free(d); + } r->data = NULL; } @@ -87,27 +117,32 @@ int resample_peaks_init(struct resample *r) { struct peaks_data *d; - const struct resample_info *info; + int res; r->free = impl_peaks_free; r->update_rate = impl_peaks_update_rate; - if ((info = find_resample_info(SPA_AUDIO_FORMAT_F32, r->cpu_flags)) == NULL) - return -ENOTSUP; + d = calloc(1, sizeof(struct peaks_data) + sizeof(float) * r->channels); + if (d == NULL) + return -errno; + + d->peaks.log = r->log; + d->peaks.cpu_flags = r->cpu_flags; + if ((res = peaks_init(&d->peaks)) < 0) { + free(d); + return res; + } - r->process = info->process; + r->data = d; + r->process = resample_peaks_process; r->reset = impl_peaks_reset; r->delay = impl_peaks_delay; r->in_len = impl_peaks_in_len; - d = r->data = calloc(1, sizeof(struct peaks_data) + sizeof(float) * r->channels); - if (r->data == NULL) - return -errno; - spa_log_debug(r->log, "peaks %p: in:%d out:%d features:%08x:%08x", r, - r->i_rate, r->o_rate, r->cpu_flags, info->cpu_flags); + r->i_rate, r->o_rate, r->cpu_flags, d->peaks.cpu_flags); - r->cpu_flags = info->cpu_flags; + r->cpu_flags = d->peaks.cpu_flags; d->i_count = d->o_count = 0; return 0; }
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample.h -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/resample.h
Changed
@@ -32,6 +32,8 @@ struct resample { struct spa_log *log; +#define RESAMPLE_OPTION_PREFILL (1<<0) + uint32_t options; uint32_t cpu_flags; const char *func_name;
View file
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/test-channelmix.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-channelmix.c
Changed
@@ -22,6 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ +#include "config.h" + #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -32,20 +34,26 @@ #include <spa/support/log-impl.h> #include <spa/debug/mem.h> +static uint32_t cpu_flags; + SPA_LOG_IMPL(logger); #define MATRIX(...) (float) { __VA_ARGS__ } +#include "test-helper.h" #include "channelmix-ops.c" + +#define CLOSE_ENOUGH(a,b) (fabs((a)-(b)) < 0.000001f) + static void dump_matrix(struct channelmix *mix, float *coeff) { uint32_t i, j; for (i = 0; i < mix->dst_chan; i++) { for (j = 0; j < mix->src_chan; j++) { - float v = mix->matrix_origij; + float v = mix->matrixij; spa_log_debug(mix->log, "%d %d: %f <-> %f", i, j, v, *coeff); - spa_assert_se(fabs(v - *coeff) < 0.000001); + spa_assert_se(CLOSE_ENOUGH(v, *coeff)); coeff++; } } @@ -65,7 +73,8 @@ mix.dst_mask = dst_mask; mix.log = &logger.log; - channelmix_init(&mix); + spa_assert_se(channelmix_init(&mix) == 0); + channelmix_set_volume(&mix, 1.0f, false, 0, NULL); dump_matrix(&mix, coeff); } @@ -220,10 +229,87 @@ 0.0, 1.0, 0.707107, 0.0, 0.0, 0.707107, 0.0, 0.707107)); } +static void run_n_m_impl(struct channelmix *mix, const void **src, uint32_t n_samples) +{ + uint32_t dst_chan = mix->dst_chan, i, j; + float dst_c_datadst_chann_samples; + float dst_x_datadst_chann_samples; + void *dst_cdst_chan, *dst_xdst_chan; + + for (i = 0; i < dst_chan; i++) { + dst_ci = dst_c_datai; + dst_xi = dst_x_datai; + } + + channelmix_f32_n_m_c(mix, dst_c, src, n_samples); + +#if defined(HAVE_SSE) + if (cpu_flags & SPA_CPU_FLAG_SSE) { + channelmix_f32_n_m_sse(mix, dst_x, src, n_samples); + for (i = 0; i < mix->dst_chan; i++) { + for (j = 0; j < n_samples; j++) { + spa_assert_se(CLOSE_ENOUGH(dst_c_dataij, dst_x_dataij)); + } + } + } +#endif +} + +static void test_n_m_impl(void) +{ + struct channelmix mix; + unsigned int i, j; +#define N_SAMPLES 251 + float src_data16N_SAMPLES, *src16; + + spa_log_debug(&logger.log, "start"); + + for (i = 0; i < 16; i++) { + for (j = 0; j < N_SAMPLES; j++) + src_dataij = (drand48() - 0.5f) * 2.5f; + srci = src_datai; + } + + spa_zero(mix); + mix.src_chan = 16; + mix.dst_chan = 12; + mix.log = &logger.log; + mix.cpu_flags = cpu_flags; + spa_assert_se(channelmix_init(&mix) == 0); + channelmix_set_volume(&mix, 1.0f, false, 0, NULL); + + /* identity matrix */ + run_n_m_impl(&mix, (const void**)src, N_SAMPLES); + + /* some zero destination */ + mix.matrix_orig22 = 0.0f; + mix.matrix_orig77 = 0.0f; + channelmix_set_volume(&mix, 1.0f, false, 0, NULL); + run_n_m_impl(&mix, (const void**)src, N_SAMPLES); + + /* random matrix */ + for (i = 0; i < mix.dst_chan; i++) { + for (j = 0; j < mix.src_chan; j++) { + mix.matrix_origij = drand48() - 0.5f; + } + } + channelmix_set_volume(&mix, 1.0f, false, 0, NULL); + + run_n_m_impl(&mix, (const void**)src, N_SAMPLES); +} + int main(int argc, char *argv) { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + srand48(SPA_TIMESPEC_TO_NSEC(&ts)); + logger.log.level = SPA_LOG_LEVEL_TRACE; + cpu_flags = get_cpu_flags(); + printf("got CPU flags %d\n", cpu_flags); + test_1_N_MONO(); test_1_N_FC(); test_N_1(); @@ -232,5 +318,7 @@ test_5p1_N(); test_7p1_N(); + test_n_m_impl(); + return 0; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-peaks.c
Added
@@ -0,0 +1,128 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <time.h> + +#include <spa/support/log-impl.h> +#include <spa/debug/mem.h> + +SPA_LOG_IMPL(logger); + +static uint32_t cpu_flags; + +#include "test-helper.h" + +#include "peaks-ops.c" + +static void test_impl(void) +{ + struct peaks peaks; + unsigned int i; + float vals1038; + float min2 = { 0.0f, 0.0f }, max2 = { 0.0f, 0.0f }, absmax2 = { 0.0f, 0.0f }; + + for (i = 0; i < SPA_N_ELEMENTS(vals); i++) + valsi = (drand48() - 0.5f) * 2.5f; + + peaks_min_max_c(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, &min0, &max0); + printf("c peaks min:%f max:%f\n", min0, max0); + + absmax0 = peaks_abs_max_c(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, 0.0f); + printf("c peaks abs-max:%f\n", absmax0); + +#if defined(HAVE_SSE) + if (cpu_flags & SPA_CPU_FLAG_SSE) { + peaks_min_max_sse(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, &min1, &max1); + printf("sse peaks min:%f max:%f\n", min1, max1); + + absmax1 = peaks_abs_max_sse(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, 0.0f); + printf("sse peaks abs-max:%f\n", absmax1); + + spa_assert(min0 == min1); + spa_assert(max0 == max1); + spa_assert(absmax0 == absmax1); + } +#endif + +} + +static void test_min_max(void) +{ + struct peaks peaks; + const float vals = { 0.0f, 0.5f, -0.5f, 0.0f, 0.6f, -0.8f, -0.5f, 0.0f }; + float min = 0.0f, max = 0.0f; + + spa_zero(peaks); + peaks.log = &logger.log; + peaks.cpu_flags = cpu_flags; + peaks_init(&peaks); + + peaks_min_max(&peaks, vals, SPA_N_ELEMENTS(vals), &min, &max); + + spa_assert(min == -0.8f); + spa_assert(max == 0.6f); +} + +static void test_abs_max(void) +{ + struct peaks peaks; + const float vals = { 0.0f, 0.5f, -0.5f, 0.0f, 0.6f, -0.8f, -0.5f, 0.0f }; + float max = 0.0f; + + spa_zero(peaks); + peaks.log = &logger.log; + peaks.cpu_flags = cpu_flags; + peaks_init(&peaks); + + max = peaks_abs_max(&peaks, vals, SPA_N_ELEMENTS(vals), max); + + spa_assert(max == 0.8f); +} + +int main(int argc, char *argv) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + srand48(SPA_TIMESPEC_TO_NSEC(&ts)); + + logger.log.level = SPA_LOG_LEVEL_TRACE; + + cpu_flags = get_cpu_flags(); + printf("got CPU flags %d\n", cpu_flags); + + test_impl(); + + test_min_max(); + test_abs_max(); + + return 0; +}
View file
pipewire-0.3.58.tar.gz/spa/plugins/avb/avb-pcm.c -> pipewire-0.3.59.tar.gz/spa/plugins/avb/avb-pcm.c
Changed
@@ -877,7 +877,7 @@ SPA_AVBTP_PACKET_AAF_SET_SEQ_NUM(pdu, state->pdu_seq++); SPA_AVBTP_PACKET_AAF_SET_TIMESTAMP(pdu, ptime); - n = sendmsg(state->sockfd, &state->msg, 0); + n = sendmsg(state->sockfd, &state->msg, MSG_NOSIGNAL); if (n < 0 || n != (ssize_t)state->pdu_size) { spa_log_error(state->log, "sendmdg() failed: %m"); }
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c
Changed
@@ -34,7 +34,7 @@ #include <fdk-aac/aacdecoder_lib.h> #include "rtp.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" static struct spa_log *log; static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.aac"); @@ -65,7 +65,7 @@ int samplesize; }; -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { static const a2dp_aac_t a2dp_aac = { @@ -98,7 +98,7 @@ return sizeof(a2dp_aac); } -static const struct a2dp_codec_config +static const struct media_codec_config aac_frequencies = { { AAC_SAMPLING_FREQ_48000, 48000, 11 }, { AAC_SAMPLING_FREQ_44100, 44100, 10 }, @@ -114,7 +114,7 @@ { AAC_SAMPLING_FREQ_8000, 8000, 0 }, }; -static const struct a2dp_codec_config +static const struct media_codec_config aac_channel_modes = { { AAC_CHANNELS_2, 2, 1 }, { AAC_CHANNELS_1, 1, 0 }, @@ -130,9 +130,9 @@ } } -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_aac_t conf; @@ -154,7 +154,7 @@ else return -ENOTSUP; - if ((i = a2dp_codec_select_config(aac_frequencies, + if ((i = media_codec_select_config(aac_frequencies, SPA_N_ELEMENTS(aac_frequencies), AAC_GET_FREQUENCY(conf), info ? info->rate : A2DP_CODEC_DEFAULT_RATE @@ -162,7 +162,7 @@ return -ENOTSUP; AAC_SET_FREQUENCY(conf, aac_frequenciesi.config); - if ((i = a2dp_codec_select_config(aac_channel_modes, + if ((i = media_codec_select_config(aac_channel_modes, SPA_N_ELEMENTS(aac_channel_modes), conf.channels, info ? info->channels : A2DP_CODEC_DEFAULT_CHANNELS @@ -177,7 +177,7 @@ return sizeof(conf); } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -246,7 +246,7 @@ return *param == NULL ? -EIO : 1; } -static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_validate_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info) { @@ -296,7 +296,7 @@ return 0; } -static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings) +static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings) { struct props *p = calloc(1, sizeof(struct props)); const char *str; @@ -316,7 +316,7 @@ free(props); } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -630,7 +630,7 @@ spa_log_topic_init(log, &log_topic); } -const struct a2dp_codec a2dp_codec_aac = { +const struct media_codec a2dp_codec_aac = { .id = SPA_BLUETOOTH_AUDIO_CODEC_AAC, .codec_id = A2DP_CODEC_MPEG24, .name = "aac", @@ -654,7 +654,7 @@ .set_log = codec_set_log, }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "aac", &a2dp_codec_aac );
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-aptx.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-aptx.c
Changed
@@ -35,7 +35,7 @@ #include <freeaptx.h> #include "rtp.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" #define APTX_LL_LEVEL1(level) (((level) >> 8) & 0xFF) #define APTX_LL_LEVEL2(level) (((level) >> 0) & 0xFF) @@ -71,19 +71,19 @@ sbc_t msbc; }; -static inline bool codec_is_hd(const struct a2dp_codec *codec) +static inline bool codec_is_hd(const struct media_codec *codec) { return codec->vendor.codec_id == APTX_HD_CODEC_ID && codec->vendor.vendor_id == APTX_HD_VENDOR_ID; } -static inline bool codec_is_ll(const struct a2dp_codec *codec) +static inline bool codec_is_ll(const struct media_codec *codec) { return (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL) || (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX); } -static inline size_t codec_get_caps_size(const struct a2dp_codec *codec) +static inline size_t codec_get_caps_size(const struct media_codec *codec) { if (codec_is_hd(codec)) return sizeof(a2dp_aptx_hd_t); @@ -93,7 +93,7 @@ return sizeof(a2dp_aptx_t); } -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { size_t actual_conf_size = codec_get_caps_size(codec); @@ -119,7 +119,7 @@ return actual_conf_size; } -static const struct a2dp_codec_config +static const struct media_codec_config aptx_frequencies = { { APTX_SAMPLING_FREQ_48000, 48000, 3 }, { APTX_SAMPLING_FREQ_44100, 44100, 2 }, @@ -127,9 +127,9 @@ { APTX_SAMPLING_FREQ_16000, 16000, 0 }, }; -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_aptx_t conf; @@ -145,7 +145,7 @@ codec->vendor.codec_id != conf.info.codec_id) return -ENOTSUP; - if ((i = a2dp_codec_select_config(aptx_frequencies, + if ((i = media_codec_select_config(aptx_frequencies, SPA_N_ELEMENTS(aptx_frequencies), conf.frequency, info ? info->rate : A2DP_CODEC_DEFAULT_RATE @@ -163,9 +163,9 @@ return actual_conf_size; } -static int codec_select_config_ll(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config_ll(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_aptx_ll_ext_t conf = { 0 }; @@ -218,7 +218,7 @@ return actual_conf_size; } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -315,7 +315,7 @@ return this->codesize; } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -458,7 +458,7 @@ * When connected as SRC to SNK, aptX-LL sink may send back mSBC data. */ -static int msbc_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int msbc_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -479,7 +479,7 @@ return *param == NULL ? -EIO : 1; } -static int msbc_validate_config(const struct a2dp_codec *codec, uint32_t flags, +static int msbc_validate_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info) { @@ -508,7 +508,7 @@ return MSBC_DECODED_SIZE; } -static void *msbc_init(const struct a2dp_codec *codec, uint32_t flags, +static void *msbc_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -610,7 +610,7 @@ } -const struct a2dp_codec a2dp_codec_aptx = { +const struct media_codec a2dp_codec_aptx = { .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX, .codec_id = A2DP_CODEC_VENDOR, .vendor = { .vendor_id = APTX_VENDOR_ID, @@ -633,7 +633,7 @@ }; -const struct a2dp_codec a2dp_codec_aptx_hd = { +const struct media_codec a2dp_codec_aptx_hd = { .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD, .codec_id = A2DP_CODEC_VENDOR, .vendor = { .vendor_id = APTX_HD_VENDOR_ID, @@ -671,7 +671,7 @@ .increase_bitpool = codec_increase_bitpool -const struct a2dp_codec a2dp_codec_aptx_ll_0 = { +const struct media_codec a2dp_codec_aptx_ll_0 = { APTX_LL_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL, .vendor = { .vendor_id = APTX_LL_VENDOR_ID, @@ -680,7 +680,7 @@ .endpoint_name = "aptx_ll_0", }; -const struct a2dp_codec a2dp_codec_aptx_ll_1 = { +const struct media_codec a2dp_codec_aptx_ll_1 = { APTX_LL_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL, .vendor = { .vendor_id = APTX_LL_VENDOR_ID2, @@ -690,7 +690,7 @@ }; /* Voice channel mSBC, not a real A2DP codec */ -static const struct a2dp_codec aptx_ll_msbc = { +static const struct media_codec aptx_ll_msbc = { .codec_id = A2DP_CODEC_VENDOR, .name = "aptx_ll_msbc", .description = "aptX-LL mSBC", @@ -715,7 +715,7 @@ }; static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items); -const struct a2dp_codec a2dp_codec_aptx_ll_duplex_0 = { +const struct media_codec a2dp_codec_aptx_ll_duplex_0 = { APTX_LL_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX, .vendor = { .vendor_id = APTX_LL_VENDOR_ID, @@ -726,7 +726,7 @@ .info = &duplex_info, }; -const struct a2dp_codec a2dp_codec_aptx_ll_duplex_1 = { +const struct media_codec a2dp_codec_aptx_ll_duplex_1 = { APTX_LL_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX, .vendor = { .vendor_id = APTX_LL_VENDOR_ID2, @@ -737,7 +737,7 @@ .info = &duplex_info, }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "aptx", &a2dp_codec_aptx_hd, &a2dp_codec_aptx,
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-faststream.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-faststream.c
Changed
@@ -36,7 +36,7 @@ #include <sbc/sbc.h> -#include "a2dp-codecs.h" +#include "media-codecs.h" struct impl { sbc_t sbc; @@ -51,7 +51,7 @@ sbc_t sbc; }; -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { const a2dp_faststream_t a2dp_faststream = { @@ -69,20 +69,20 @@ return sizeof(a2dp_faststream); } -static const struct a2dp_codec_config +static const struct media_codec_config frequencies = { { FASTSTREAM_SINK_SAMPLING_FREQ_48000, 48000, 1 }, { FASTSTREAM_SINK_SAMPLING_FREQ_44100, 44100, 0 }, }; -static const struct a2dp_codec_config +static const struct media_codec_config duplex_frequencies = { { FASTSTREAM_SOURCE_SAMPLING_FREQ_16000, 16000, 0 }, }; -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_faststream_t conf; @@ -108,7 +108,7 @@ if (codec->duplex_codec) conf.direction |= FASTSTREAM_DIRECTION_SOURCE; - if ((i = a2dp_codec_select_config(frequencies, + if ((i = media_codec_select_config(frequencies, SPA_N_ELEMENTS(frequencies), conf.sink_frequency, info ? info->rate : A2DP_CODEC_DEFAULT_RATE @@ -116,7 +116,7 @@ return -ENOTSUP; conf.sink_frequency = frequenciesi.config; - if ((i = a2dp_codec_select_config(duplex_frequencies, + if ((i = media_codec_select_config(duplex_frequencies, SPA_N_ELEMENTS(duplex_frequencies), conf.source_frequency, 16000 @@ -129,7 +129,7 @@ return sizeof(conf); } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -209,7 +209,7 @@ return v; } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -372,7 +372,7 @@ * When connected as SRC to SNK, FastStream sink may send back SBC data. */ -static int duplex_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int duplex_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -411,7 +411,7 @@ return *param == NULL ? -EIO : 1; } -static int duplex_validate_config(const struct a2dp_codec *codec, uint32_t flags, +static int duplex_validate_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info) { @@ -441,7 +441,7 @@ return 0; } -static void *duplex_init(const struct a2dp_codec *codec, uint32_t flags, +static void *duplex_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -577,7 +577,7 @@ } /* Voice channel SBC, not a real A2DP codec */ -static const struct a2dp_codec duplex_codec = { +static const struct media_codec duplex_codec = { .codec_id = A2DP_CODEC_VENDOR, .name = "faststream_sbc", .description = "FastStream duplex SBC", @@ -614,7 +614,7 @@ .reduce_bitpool = codec_reduce_bitpool, \ .increase_bitpool = codec_increase_bitpool -static const struct a2dp_codec a2dp_codec_faststream = { +const struct media_codec a2dp_codec_faststream = { FASTSTREAM_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, .name = "faststream", @@ -625,7 +625,7 @@ }; static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items); -const struct a2dp_codec a2dp_codec_faststream_duplex = { +const struct media_codec a2dp_codec_faststream_duplex = { FASTSTREAM_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, .name = "faststream_duplex", @@ -633,7 +633,7 @@ .info = &duplex_info, }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "faststream", &a2dp_codec_faststream, &a2dp_codec_faststream_duplex
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c
Changed
@@ -41,7 +41,7 @@ #endif #include "rtp.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" #define BITRATE_MIN 96000 #define BITRATE_MAX 512000 @@ -86,7 +86,7 @@ int32_t buf2LC3PLUS_MAX_SAMPLES; }; -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { const a2dp_lc3plus_hr_t a2dp_lc3plus_hr = { @@ -102,9 +102,9 @@ return sizeof(a2dp_lc3plus_hr); } -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_lc3plus_hr_t conf; @@ -150,8 +150,8 @@ return sizeof(conf); } -static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings) +static int codec_caps_preference_cmp(const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info, const struct spa_dict *global_settings) { a2dp_lc3plus_hr_t conf1, conf2; a2dp_lc3plus_hr_t *conf; @@ -160,7 +160,7 @@ /* Order selected configurations by preference */ res1 = codec->select_config(codec, 0, caps1, caps1_size, info, NULL, (uint8_t *)&conf1); - res2 = codec->select_config(codec, 0, caps2, caps2_size, info, NULL, (uint8_t *)&conf2); + res2 = codec->select_config(codec, 0, caps2, caps2_size, info , NULL, (uint8_t *)&conf2); #define PREFER_EXPR(expr) \ do { \ @@ -190,7 +190,7 @@ #undef PREFER_BOOL } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -263,7 +263,7 @@ return *param == NULL ? -EIO : 1; } -static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_validate_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info) { @@ -342,7 +342,7 @@ return (size_t)this->mtu >= header_size + ceildiv(payload_size, max_fragments); } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -758,7 +758,7 @@ return 0; } -const struct a2dp_codec a2dp_codec_lc3plus_hr = { +const struct media_codec a2dp_codec_lc3plus_hr = { .id = SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR, .name = "lc3plus_hr", .codec_id = A2DP_CODEC_VENDOR, @@ -782,7 +782,7 @@ .increase_bitpool = codec_increase_bitpool }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "lc3plus", &a2dp_codec_lc3plus_hr );
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c
Changed
@@ -40,7 +40,7 @@ #endif #include "rtp.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" #define LDACBT_EQMID_AUTO -1 @@ -79,7 +79,7 @@ int frame_count; }; -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { static const a2dp_ldac_t a2dp_ldac = { .info.vendor_id = LDAC_VENDOR_ID, @@ -97,7 +97,7 @@ return sizeof(a2dp_ldac); } -static const struct a2dp_codec_config +static const struct media_codec_config ldac_frequencies = { { LDACBT_SAMPLING_FREQ_044100, 44100, 3 }, { LDACBT_SAMPLING_FREQ_048000, 48000, 2 }, @@ -105,16 +105,16 @@ { LDACBT_SAMPLING_FREQ_096000, 96000, 0 }, }; -static const struct a2dp_codec_config +static const struct media_codec_config ldac_channel_modes = { { LDACBT_CHANNEL_MODE_STEREO, 2, 2 }, { LDACBT_CHANNEL_MODE_DUAL_CHANNEL, 2, 1 }, { LDACBT_CHANNEL_MODE_MONO, 1, 0 }, }; -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_ldac_t conf; @@ -129,7 +129,7 @@ codec->vendor.codec_id != conf.info.codec_id) return -ENOTSUP; - if ((i = a2dp_codec_select_config(ldac_frequencies, + if ((i = media_codec_select_config(ldac_frequencies, SPA_N_ELEMENTS(ldac_frequencies), conf.frequency, info ? info->rate : A2DP_CODEC_DEFAULT_RATE @@ -137,7 +137,7 @@ return -ENOTSUP; conf.frequency = ldac_frequenciesi.config; - if ((i = a2dp_codec_select_config(ldac_channel_modes, + if ((i = media_codec_select_config(ldac_channel_modes, SPA_N_ELEMENTS(ldac_channel_modes), conf.channel_mode, info ? info->channels : A2DP_CODEC_DEFAULT_CHANNELS @@ -150,7 +150,7 @@ return sizeof(conf); } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -284,7 +284,7 @@ return LDACBT_EQMID_AUTO; } -static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings) +static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings) { struct props *p = calloc(1, sizeof(struct props)); const char *str; @@ -385,7 +385,7 @@ return prev_eqmid != p->eqmid; } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -570,7 +570,7 @@ return src_used; } -const struct a2dp_codec a2dp_codec_ldac = { +const struct media_codec a2dp_codec_ldac = { .id = SPA_BLUETOOTH_AUDIO_CODEC_LDAC, .codec_id = A2DP_CODEC_VENDOR, .vendor = { .vendor_id = LDAC_VENDOR_ID, @@ -598,7 +598,7 @@ .increase_bitpool = codec_increase_bitpool, }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "ldac", &a2dp_codec_ldac );
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c
Changed
@@ -44,7 +44,7 @@ #include <opus_multistream.h> #include "rtp.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" static struct spa_log *log; static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.opus"); @@ -395,7 +395,7 @@ props->bidi_application = OPUS_APPLICATION_RESTRICTED_LOWDELAY; } -static int set_channel_conf(const struct a2dp_codec *codec, a2dp_opus_05_t *caps, const struct props *props) +static int set_channel_conf(const struct media_codec *codec, a2dp_opus_05_t *caps, const struct props *props) { /* * Predefined codec profiles @@ -469,7 +469,7 @@ return 0; } -static void get_default_bitrates(const struct a2dp_codec *codec, bool bidi, int *min, int *max, int *init) +static void get_default_bitrates(const struct media_codec *codec, bool bidi, int *min, int *max, int *init) { int tmp; @@ -514,7 +514,7 @@ }; } -static int get_mapping(const struct a2dp_codec *codec, const a2dp_opus_05_direction_t *conf, +static int get_mapping(const struct media_codec *codec, const a2dp_opus_05_direction_t *conf, bool use_surround_encoder, uint8_t *streams_ret, uint8_t *coupled_streams_ret, const uint8_t **surround_mapping, uint32_t *positions) { @@ -576,7 +576,7 @@ return 0; } -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { a2dp_opus_05_t a2dp_opus_05 = { @@ -613,9 +613,9 @@ return sizeof(a2dp_opus_05); } -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE) { struct props props; @@ -715,8 +715,8 @@ return sizeof(conf); } -static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, +static int codec_caps_preference_cmp(const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info, const struct spa_dict *global_settings) { a2dp_opus_05_t conf1, conf2, cap1, cap2; @@ -768,12 +768,12 @@ #undef PREFER_BOOL } -static bool is_duplex_codec(const struct a2dp_codec *codec) +static bool is_duplex_codec(const struct media_codec *codec) { return codec->id == 0; } -static bool use_surround_encoder(const struct a2dp_codec *codec, bool is_sink) +static bool use_surround_encoder(const struct media_codec *codec, bool is_sink) { if (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO) return false; @@ -784,11 +784,11 @@ return !is_sink; } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { - const bool surround_encoder = use_surround_encoder(codec, flags & A2DP_CODEC_FLAG_SINK); + const bool surround_encoder = use_surround_encoder(codec, flags & MEDIA_CODEC_FLAG_SINK); a2dp_opus_05_t conf; a2dp_opus_05_direction_t *dir; struct spa_pod_frame f1; @@ -823,11 +823,11 @@ return *param == NULL ? -EIO : 1; } -static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_validate_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info) { - const bool surround_encoder = use_surround_encoder(codec, flags & A2DP_CODEC_FLAG_SINK); + const bool surround_encoder = use_surround_encoder(codec, flags & MEDIA_CODEC_FLAG_SINK); const a2dp_opus_05_direction_t *dir1, *dir2; const a2dp_opus_05_t *conf; @@ -898,7 +898,7 @@ } } -static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings) +static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings) { struct props *p; @@ -919,11 +919,11 @@ free(props); } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { - const bool surround_encoder = use_surround_encoder(codec, flags & A2DP_CODEC_FLAG_SINK); + const bool surround_encoder = use_surround_encoder(codec, flags & MEDIA_CODEC_FLAG_SINK); a2dp_opus_05_t *conf = config; a2dp_opus_05_direction_t *dir; struct impl *this = NULL; @@ -1380,21 +1380,21 @@ .start_decode = codec_start_decode, \ .decode = codec_decode -const struct a2dp_codec a2dp_codec_opus_05 = { +const struct media_codec a2dp_codec_opus_05 = { OPUS_05_COMMON_FULL_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05, .name = "opus_05", .description = "Opus", }; -const struct a2dp_codec a2dp_codec_opus_05_51 = { +const struct media_codec a2dp_codec_opus_05_51 = { OPUS_05_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51, .name = "opus_05_51", .description = "Opus 5.1 Surround", }; -const struct a2dp_codec a2dp_codec_opus_05_71 = { +const struct media_codec a2dp_codec_opus_05_71 = { OPUS_05_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, .name = "opus_05_71", @@ -1402,14 +1402,14 @@ }; /* Bidi return channel codec: doesn't have endpoints */ -const struct a2dp_codec a2dp_codec_opus_05_return = { +const struct media_codec a2dp_codec_opus_05_return = { OPUS_05_COMMON_FULL_DEFS, .id = 0, .name = "opus_05_duplex_bidi", .description = "Opus Duplex Bidi channel", }; -const struct a2dp_codec a2dp_codec_opus_05_duplex = { +const struct media_codec a2dp_codec_opus_05_duplex = { OPUS_05_COMMON_FULL_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, .name = "opus_05_duplex", @@ -1417,7 +1417,7 @@ .duplex_codec = &a2dp_codec_opus_05_return, }; -const struct a2dp_codec a2dp_codec_opus_05_pro = { +const struct media_codec a2dp_codec_opus_05_pro = { OPUS_05_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, .name = "opus_05_pro", @@ -1427,7 +1427,7 @@ .duplex_codec = &a2dp_codec_opus_05_return, }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "opus", &a2dp_codec_opus_05, &a2dp_codec_opus_05_51,
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codec-sbc.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-sbc.c
Changed
@@ -33,7 +33,7 @@ #include <sbc/sbc.h> #include "rtp.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" #define MAX_FRAME_COUNT 16 @@ -51,7 +51,7 @@ int max_bitpool; }; -static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE) { static const a2dp_sbc_t a2dp_sbc = { @@ -121,7 +121,7 @@ } -static const struct a2dp_codec_config +static const struct media_codec_config sbc_frequencies = { { SBC_SAMPLING_FREQ_48000, 48000, 3 }, { SBC_SAMPLING_FREQ_44100, 44100, 2 }, @@ -129,13 +129,13 @@ { SBC_SAMPLING_FREQ_16000, 16000, 0 }, }; -static const struct a2dp_codec_config +static const struct media_codec_config sbc_xq_frequencies = { { SBC_SAMPLING_FREQ_44100, 44100, 1 }, { SBC_SAMPLING_FREQ_48000, 48000, 0 }, }; -static const struct a2dp_codec_config +static const struct media_codec_config sbc_channel_modes = { { SBC_CHANNEL_MODE_JOINT_STEREO, 2, 3 }, { SBC_CHANNEL_MODE_STEREO, 2, 2 }, @@ -143,22 +143,22 @@ { SBC_CHANNEL_MODE_MONO, 1, 0 }, }; -static const struct a2dp_codec_config +static const struct media_codec_config sbc_xq_channel_modes = { { SBC_CHANNEL_MODE_DUAL_CHANNEL, 2, 2 }, { SBC_CHANNEL_MODE_JOINT_STEREO, 2, 1 }, { SBC_CHANNEL_MODE_STEREO, 2, 0 }, }; -static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_select_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info, + const struct media_codec_audio_info *info, const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE) { a2dp_sbc_t conf; int bitpool, i; size_t n; - const struct a2dp_codec_config *configs; + const struct media_codec_config *configs; bool xq = false; @@ -176,7 +176,7 @@ configs = sbc_frequencies; n = SPA_N_ELEMENTS(sbc_frequencies); } - if ((i = a2dp_codec_select_config(configs, n, conf.frequency, + if ((i = media_codec_select_config(configs, n, conf.frequency, info ? info->rate : A2DP_CODEC_DEFAULT_RATE )) < 0) return -ENOTSUP; @@ -189,7 +189,7 @@ configs = sbc_channel_modes; n = SPA_N_ELEMENTS(sbc_channel_modes); } - if ((i = a2dp_codec_select_config(configs, n, conf.channel_mode, + if ((i = media_codec_select_config(configs, n, conf.channel_mode, info ? info->channels : A2DP_CODEC_DEFAULT_CHANNELS )) < 0) return -ENOTSUP; @@ -229,8 +229,8 @@ return sizeof(conf); } -static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings) +static int codec_caps_preference_cmp(const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info, const struct spa_dict *global_settings) { a2dp_sbc_t conf1, conf2; a2dp_sbc_t *conf; @@ -275,7 +275,7 @@ #undef PREFER_BOOL } -static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_validate_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info) { @@ -356,7 +356,7 @@ return this->sbc.bitpool; } -static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, +static int codec_enum_config(const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -453,7 +453,7 @@ return this->codesize; } -static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, +static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) { @@ -638,7 +638,7 @@ return res; } -const struct a2dp_codec a2dp_codec_sbc = { +const struct media_codec a2dp_codec_sbc = { .id = SPA_BLUETOOTH_AUDIO_CODEC_SBC, .codec_id = A2DP_CODEC_SBC, .name = "sbc", @@ -660,7 +660,7 @@ .increase_bitpool = codec_increase_bitpool, }; -const struct a2dp_codec a2dp_codec_sbc_xq = { +const struct media_codec a2dp_codec_sbc_xq = { .id = SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ, .codec_id = A2DP_CODEC_SBC, .name = "sbc_xq", @@ -682,7 +682,7 @@ .increase_bitpool = codec_increase_bitpool, }; -A2DP_CODEC_EXPORT_DEF( +MEDIA_CODEC_EXPORT_DEF( "sbc", &a2dp_codec_sbc, &a2dp_codec_sbc_xq
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
@@ -78,7 +78,7 @@ struct spa_dbus *dbus; DBusConnection *conn; -#define DEFAULT_ENABLED_PROFILES (SPA_BT_PROFILE_HSP_HS | SPA_BT_PROFILE_HFP_AG) +#define DEFAULT_ENABLED_PROFILES (SPA_BT_PROFILE_HFP_HF | SPA_BT_PROFILE_HFP_AG) enum spa_bt_profile enabled_profiles; struct spa_source sco; @@ -259,6 +259,7 @@ #define RFCOMM_MESSAGE_MAX_LENGTH 256 +/* from HF/HS to AG */ SPA_PRINTF_FUNC(2, 3) static ssize_t rfcomm_send_cmd(const struct rfcomm *rfcomm, const char *format, ...) { @@ -279,7 +280,14 @@ spa_log_debug(backend->log, "RFCOMM >> %s", message); - messagelen = '\n'; + /* + * The format of an AT command from the HF to the AG shall be: <AT command><cr> + * - HFP 1.8, 4.34.1 + * + * The format for a command from the HS to the AG is thus: AT<cmd>=<value><cr> + * - HSP 1.2, 4.8.1 + */ + messagelen = '\r'; /* `message` is no longer null-terminated */ len = write(rfcomm->source.fd, message, len + 1); @@ -293,6 +301,7 @@ return len; } +/* from AG to HF/HS */ SPA_PRINTF_FUNC(2, 3) static ssize_t rfcomm_send_reply(const struct rfcomm *rfcomm, const char *format, ...) { @@ -313,6 +322,18 @@ spa_log_debug(backend->log, "RFCOMM >> %s", &message2); + /* + * The format of the OK code from the AG to the HF shall be: <cr><lf>OK<cr><lf> + * The format of the generic ERROR code from the AG to the HF shall be: <cr><lf>ERROR<cr><lf> + * The format of an unsolicited result code from the AG to the HF shall be: <cr><lf><result code><cr><lf> + * - HFP 1.8, 4.34.1 + * + * If the command is processed successfully, the resulting response from the AG to the HS is: <cr><lf>OK<cr><lf> + * If the command is not processed successfully, or is not recognized, + * the resulting response from the AG to the HS is: <cr><lf>ERROR<cr><lf> + * The format for an unsolicited result code (such as RING) from the AG to the HS is: <cr><lf><result code><cr><lf> + * - HSP 1.2, 4.8.1 + */ message0 = '\r'; message1 = '\n'; messagelen + 2 = '\r'; @@ -747,26 +768,21 @@ /* retrieve supported codecs */ /* response has the form AT+BAC=<codecID1>,<codecID2>,<codecIDx> strategy: split the string into tokens */ - static const char separators = "=,"; char* token; int cntr = 0; - token = strtok (buf, separators); - while (token != NULL) - { + while ((token = strsep(&buf, "=,"))) { + unsigned int codec_id; + /* skip token 0 i.e. the "AT+BAC=" part */ - if (cntr > 0) { - int codec_id; - sscanf (token, "%u", &codec_id); + if (cntr > 0 && sscanf(token, "%u", &codec_id) == 1) { spa_log_debug(backend->log, "RFCOMM AT+BAC found codec %u", codec_id); if (codec_id == HFP_AUDIO_CODEC_MSBC) { rfcomm->msbc_supported_by_hfp = true; spa_log_debug(backend->log, "RFCOMM headset supports mSBC codec"); } } - /* get next token */ - token = strtok (NULL, separators); cntr++; } @@ -809,7 +825,7 @@ } else if (!rfcomm->slc_configured) { spa_log_warn(backend->log, "RFCOMM receive command before SLC completed: %s", buf); rfcomm_send_reply(rfcomm, "ERROR"); - return false; + return true; } else if (sscanf(buf, "AT+BCS=%u", &selected_codec) == 1) { /* parse BCS(=Bluetooth Codec Selection) reply */ bool was_switching_codec = rfcomm->hfp_ag_switching_codec && (rfcomm->device != NULL); @@ -918,29 +934,18 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* buf) { - static const char separators = "\r\n:"; - struct impl *backend = rfcomm->backend; unsigned int features; unsigned int gain; unsigned int selected_codec; char* token; - token = strtok(buf, separators); - while (token != NULL) - { - if (spa_strstartswith(token, "+BRSF")) { - /* get next token */ - token = strtok(NULL, separators); - features = atoi(token); + while ((token = strsep(&buf, "\r\n"))) { + if (sscanf(token, "+BRSF:%u", &features) == 1) { if (((features & (SPA_BT_HFP_AG_FEATURE_CODEC_NEGOTIATION)) != 0) && rfcomm->msbc_supported_by_hfp) rfcomm->codec_negotiation_supported = true; - } else if (spa_strstartswith(token, "+BCS") && rfcomm->codec_negotiation_supported) { - /* get next token */ - token = strtok(NULL, separators); - selected_codec = atoi(token); - + } else if (sscanf(token, "+BCS:%u", &selected_codec) == 1 && rfcomm->codec_negotiation_supported) { if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC) { spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec); } else { @@ -965,24 +970,13 @@ } } } - } else if (spa_strstartswith(token, "+CIND")) { - /* get next token and discard it */ - token = strtok(NULL, separators); - } else if (spa_strstartswith(token, "+VGM")) { - /* get next token */ - token = strtok(NULL, separators); - gain = atoi(token); - + } else if (sscanf(token, "+VGM%*1:=%u", &gain) == 1) { if (gain <= SPA_BT_VOLUME_HS_MAX) { rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_TX, gain); } else { spa_log_debug(backend->log, "RFCOMM receive unsupported VGM gain: %s", token); } - } else if (spa_strstartswith(token, "+VGS")) { - /* get next token */ - token = strtok(NULL, separators); - gain = atoi(token); - + } else if (sscanf(token, "+VGS%*1:=%u", &gain) == 1) { if (gain <= SPA_BT_VOLUME_HS_MAX) { rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_RX, gain); } else { @@ -1041,8 +1035,6 @@ break; } } - /* get next token */ - token = strtok(NULL, separators); } return true;
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-caps.h
Added
@@ -0,0 +1,113 @@ +/* Spa BAP codec API + * + * Copyright © 2022 Collabora + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef SPA_BLUEZ5_BAP_CODEC_CAPS_H_ +#define SPA_BLUEZ5_BAP_CODEC_CAPS_H_ + +#define BAP_CODEC_LC3 0x06 + +#define LC3_TYPE_FREQ 0x01 +#define LC3_FREQ_8KHZ (1 << 0) +#define LC3_FREQ_11KHZ (1 << 1) +#define LC3_FREQ_16KHZ (1 << 2) +#define LC3_FREQ_22KHZ (1 << 3) +#define LC3_FREQ_24KHZ (1 << 4) +#define LC3_FREQ_32KHZ (1 << 5) +#define LC3_FREQ_44KHZ (1 << 6) +#define LC3_FREQ_48KHZ (1 << 7) +#define LC3_FREQ_ANY (LC3_FREQ_8KHZ | \ + LC3_FREQ_11KHZ | \ + LC3_FREQ_16KHZ | \ + LC3_FREQ_22KHZ | \ + LC3_FREQ_24KHZ | \ + LC3_FREQ_32KHZ | \ + LC3_FREQ_44KHZ | \ + LC3_FREQ_48KHZ) + +#define LC3_TYPE_DUR 0x02 +#define LC3_DUR_7_5 (1 << 0) +#define LC3_DUR_10 (1 << 1) +#define LC3_DUR_ANY (LC3_DUR_7_5 | \ + LC3_DUR_10) + +#define LC3_TYPE_CHAN 0x03 +#define LC3_CHAN_1 (1 << 0) +#define LC3_CHAN_2 (1 << 1) + +#define LC3_TYPE_FRAMELEN 0x04 +#define LC3_TYPE_BLKS 0x05 + +/* LC3 config parameters */ +#define LC3_CONFIG_FREQ_8KHZ 0x01 +#define LC3_CONFIG_FREQ_11KHZ 0x02 +#define LC3_CONFIG_FREQ_16KHZ 0x03 +#define LC3_CONFIG_FREQ_22KHZ 0x04 +#define LC3_CONFIG_FREQ_24KHZ 0x05 +#define LC3_CONFIG_FREQ_32KHZ 0x06 +#define LC3_CONFIG_FREQ_44KHZ 0x07 +#define LC3_CONFIG_FREQ_48KHZ 0x08 + +#define LC3_CONFIG_DURATION_7_5 0x00 +#define LC3_CONFIG_DURATION_10 0x01 + +#define LC3_CONFIG_CHNL_NOT_ALLOWED 0x00000000 +#define LC3_CONFIG_CHNL_FL 0x00000001 /* front left */ +#define LC3_CONFIG_CHNL_FR 0x00000002 /* front right */ +#define LC3_CONFIG_CHNL_FC 0x00000004 /* front center */ +#define LC3_CONFIG_CHNL_LFE 0x00000008 /* LFE */ +#define LC3_CONFIG_CHNL_BL 0x00000010 /* back left */ +#define LC3_CONFIG_CHNL_BR 0x00000020 /* back right */ +#define LC3_CONFIG_CHNL_FLC 0x00000040 /* front left center */ +#define LC3_CONFIG_CHNL_FRC 0x00000080 /* front right center */ +#define LC3_CONFIG_CHNL_BC 0x00000100 /* back center */ +#define LC3_CONFIG_CHNL_LFE2 0x00000200 /* LFE 2 */ +#define LC3_CONFIG_CHNL_SL 0x00000400 /* side left */ +#define LC3_CONFIG_CHNL_SR 0x00000800 /* side right */ +#define LC3_CONFIG_CHNL_TFL 0x00001000 /* top front left */ +#define LC3_CONFIG_CHNL_TFR 0x00002000 /* top front right */ +#define LC3_CONFIG_CHNL_TFC 0x00004000 /* top front center */ +#define LC3_CONFIG_CHNL_TC 0x00008000 /* top center */ +#define LC3_CONFIG_CHNL_TBL 0x00010000 /* top back left */ +#define LC3_CONFIG_CHNL_TBR 0x00020000 /* top back right */ +#define LC3_CONFIG_CHNL_TSL 0x00040000 /* top side left */ +#define LC3_CONFIG_CHNL_TSR 0x00080000 /* top side right */ +#define LC3_CONFIG_CHNL_TBC 0x00100000 /* top back center */ +#define LC3_CONFIG_CHNL_BFC 0x00200000 /* bottom front center */ +#define LC3_CONFIG_CHNL_BFL 0x00400000 /* bottom front left */ +#define LC3_CONFIG_CHNL_BFR 0x00800000 /* bottom front right */ +#define LC3_CONFIG_CHNL_FLW 0x01000000 /* front left wide */ +#define LC3_CONFIG_CHNL_FRW 0x02000000 /* front right wide */ +#define LC3_CONFIG_CHNL_LS 0x04000000 /* left surround */ +#define LC3_CONFIG_CHNL_RS 0x08000000 /* right surround */ + +#define LC3_MAX_CHANNELS 28 + +typedef struct { + uint8_t rate; + uint8_t frame_duration; + uint32_t channels; + uint16_t framelen; + uint8_t n_blks; +} __attribute__ ((packed)) bap_lc3_t; + +#endif
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c
Added
@@ -0,0 +1,772 @@ +/* Spa BAP LC3 codec + * + * Copyright © 2020 Wim Taymans + * Copyright © 2022 Pauli Virtanen + * Copyright © 2022 Collabora + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <bits/stdint-uintn.h> +#include <string.h> +#include <unistd.h> +#include <stddef.h> +#include <errno.h> +#include <arpa/inet.h> +#include <bluetooth/bluetooth.h> + +#include <spa/param/audio/format.h> +#include <spa/param/audio/format-utils.h> + +#include <lc3.h> + +#include "media-codecs.h" +#include "bap-codec-caps.h" + +struct impl { + lc3_encoder_t encLC3_MAX_CHANNELS; + lc3_decoder_t decLC3_MAX_CHANNELS; + + int mtu; + int samplerate; + int channels; + int frame_dus; + int framelen; + int samples; + unsigned int codesize; +}; + +struct ltv { + uint8_t len; + uint8_t type; + uint8_t value0; +} __packed; + +static int write_ltv(uint8_t *dest, uint8_t type, void* value, size_t len) +{ + struct ltv *ltv = (struct ltv *)dest; + + ltv->len = len + 1; + ltv->type = type; + memcpy(ltv->value, value, len); + + return len + 2; +} + +static int write_ltv_uint8(uint8_t *dest, uint8_t type, uint8_t value) +{ + return write_ltv(dest, type, &value, sizeof(value)); +} + +static int write_ltv_uint16(uint8_t *dest, uint8_t type, uint16_t value) +{ + return write_ltv(dest, type, &value, sizeof(value)); +} + +static int write_ltv_uint32(uint8_t *dest, uint8_t type, uint32_t value) +{ + return write_ltv(dest, type, &value, sizeof(value)); +} + +static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, + uint8_t capsA2DP_MAX_CAPS_SIZE) +{ + uint8_t *data = caps; + uint16_t framelen2 = {htobs(LC3_MIN_FRAME_BYTES), htobs(LC3_MAX_FRAME_BYTES)}; + + data += write_ltv_uint16(data, LC3_TYPE_FREQ, + htobs(LC3_FREQ_48KHZ | LC3_FREQ_24KHZ | LC3_FREQ_16KHZ | LC3_FREQ_8KHZ)); + data += write_ltv_uint8(data, LC3_TYPE_DUR, LC3_DUR_ANY); + data += write_ltv_uint8(data, LC3_TYPE_CHAN, LC3_CHAN_1 | LC3_CHAN_2); + data += write_ltv(data, LC3_TYPE_FRAMELEN, framelen, sizeof(framelen)); + data += write_ltv_uint8(data, LC3_TYPE_BLKS, 2); + + return data - caps; +} + +static bool parse_capabilities(bap_lc3_t *conf, const uint8_t *data, size_t data_size) +{ + uint16_t framelen_min = 0, framelen_max = 0; + + if (!data_size) + return false; + memset(conf, 0, sizeof(*conf)); + + conf->frame_duration = 0xFF; + + while (data_size > 0) { + struct ltv *ltv = (struct ltv *)data; + + if (ltv->len > data_size) + return false; + + switch (ltv->type) { + case LC3_TYPE_FREQ: + spa_return_val_if_fail(ltv->len == 3, false); + { + uint16_t rate = ltv->value0 + (ltv->value1 << 8); + if (rate & LC3_FREQ_48KHZ) + conf->rate = LC3_CONFIG_FREQ_48KHZ; + else if (rate & LC3_FREQ_24KHZ) + conf->rate = LC3_CONFIG_FREQ_24KHZ; + else if (rate & LC3_FREQ_16KHZ) + conf->rate = LC3_CONFIG_FREQ_16KHZ; + else if (rate & LC3_FREQ_8KHZ) + conf->rate = LC3_CONFIG_FREQ_8KHZ; + else + return false; + } + break; + case LC3_TYPE_DUR: + spa_return_val_if_fail(ltv->len == 2, false); + { + uint8_t duration = ltv->value0; + if (duration & LC3_DUR_10) + conf->frame_duration = LC3_CONFIG_DURATION_10; + else if (duration & LC3_DUR_7_5) + conf->frame_duration = LC3_CONFIG_DURATION_7_5; + else + return false; + } + break; + case LC3_TYPE_CHAN: + spa_return_val_if_fail(ltv->len == 2, false); + { + uint8_t channels = ltv->value0; + /* Only mono or stereo streams are currently supported, + * in both case Audio location is defined as both Front Left + * and Front Right, difference is done by the n_blks parameter. + */ + if ((channels & LC3_CHAN_2) || (channels & LC3_CHAN_1)) + conf->channels = LC3_CONFIG_CHNL_FR | LC3_CONFIG_CHNL_FL; + else + return false; + } + break; + case LC3_TYPE_FRAMELEN: + spa_return_val_if_fail(ltv->len == 5, false); + framelen_min = ltv->value0 + (ltv->value1 << 8); + framelen_max = ltv->value2 + (ltv->value3 << 8); + break; + case LC3_TYPE_BLKS: + spa_return_val_if_fail(ltv->len == 2, false); + conf->n_blks = ltv->value0; + if (!conf->n_blks) + return false; + break; + default: + return false; + } + data_size -= ltv->len + 1; + data += ltv->len + 1; + } + + if (framelen_min < LC3_MIN_FRAME_BYTES || framelen_max > LC3_MAX_FRAME_BYTES) + return false; + if (conf->frame_duration == 0xFF || !conf->rate) + return false; + if (!conf->channels) + conf->channels = LC3_CONFIG_CHNL_FL; + + switch (conf->rate) { + case LC3_CONFIG_FREQ_48KHZ: + if (conf->frame_duration == LC3_CONFIG_DURATION_7_5) + conf->framelen = 117; + else + conf->framelen = 120; + break; + case LC3_CONFIG_FREQ_24KHZ: + if (conf->frame_duration == LC3_CONFIG_DURATION_7_5) + conf->framelen = 45; + else + conf->framelen = 60;
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -100,7 +100,7 @@ uint32_t id; - const struct a2dp_codec * const * a2dp_codecs; + const struct media_codec * const * media_codecs; /* * Lists of BlueZ objects, kept up-to-date by following DBus events @@ -130,7 +130,9 @@ struct spa_dict global_settings; /* A reference audio info for A2DP codec configuration. */ - struct a2dp_codec_audio_info default_audio_info; + struct media_codec_audio_info default_audio_info; + + bool le_audio_supported; }; /* Stream endpoints owned by BlueZ for each device */ @@ -146,6 +148,7 @@ uint8_t *capabilities; int capabilities_len; bool delay_reporting; + bool acceptor; }; /* @@ -155,7 +158,7 @@ * with the desired capabilities. * The codec switch struct tracks candidates still to be tried. */ -struct spa_bt_a2dp_codec_switch { +struct spa_bt_media_codec_switch { struct spa_bt_device *device; struct spa_list device_link; @@ -172,10 +175,10 @@ * Called asynchronously, so endpoint paths instead of pointers (which may be * invalidated in the meantime). */ - const struct a2dp_codec **codecs; + const struct media_codec **codecs; char **paths; - const struct a2dp_codec **codec_iter; /**< outer iterator over codecs */ + const struct media_codec **codec_iter; /**< outer iterator over codecs */ char **path_iter; /**< inner iterator over endpoint paths */ uint16_t retries; @@ -430,10 +433,17 @@ } } -static int a2dp_codec_to_endpoint(const struct a2dp_codec *codec, - const char * endpoint, +static int media_codec_to_endpoint(const struct media_codec *codec, + enum spa_bt_media_direction direction, char** object_path) { + const char * endpoint; + + if (direction == SPA_BT_MEDIA_SOURCE) + endpoint = codec->bap ? BAP_SOURCE_ENDPOINT : A2DP_SOURCE_ENDPOINT; + else + endpoint = codec->bap ? BAP_SINK_ENDPOINT : A2DP_SINK_ENDPOINT; + *object_path = spa_aprintf("%s/%s", endpoint, codec->endpoint_name ? codec->endpoint_name : codec->name); if (*object_path == NULL) @@ -441,10 +451,10 @@ return 0; } -static const struct a2dp_codec *a2dp_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink) +static const struct media_codec *media_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink) { const char *ep_name; - const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs; + const struct media_codec * const * const media_codecs = monitor->media_codecs; int i; if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) { @@ -453,12 +463,19 @@ } else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/")) { ep_name = endpoint + strlen(A2DP_SOURCE_ENDPOINT "/"); *sink = false; + } else if (spa_strstartswith(endpoint, BAP_SOURCE_ENDPOINT "/")) { + ep_name = endpoint + strlen(BAP_SOURCE_ENDPOINT "/"); + *sink = false; + } else if (spa_strstartswith(endpoint, BAP_SINK_ENDPOINT "/")) { + ep_name = endpoint + strlen(BAP_SINK_ENDPOINT "/"); + *sink = true; } else { + *sink = true; return NULL; } - for (i = 0; a2dp_codecsi; i++) { - const struct a2dp_codec *codec = a2dp_codecsi; + for (i = 0; media_codecsi; i++) { + const struct media_codec *codec = media_codecsi; const char *codec_ep_name = codec->endpoint_name ? codec->endpoint_name : codec->name; if (spa_streq(ep_name, codec_ep_name)) @@ -467,18 +484,22 @@ return NULL; } -static int a2dp_endpoint_to_profile(const char *endpoint) +static int media_endpoint_to_profile(const char *endpoint) { if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) return SPA_BT_PROFILE_A2DP_SOURCE; else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/")) return SPA_BT_PROFILE_A2DP_SINK; + else if (spa_strstartswith(endpoint, BAP_SINK_ENDPOINT "/")) + return SPA_BT_PROFILE_BAP_SOURCE; + else if (spa_strstartswith(endpoint, BAP_SOURCE_ENDPOINT "/")) + return SPA_BT_PROFILE_BAP_SINK; else return SPA_BT_PROFILE_NULL; } -static bool is_a2dp_codec_enabled(struct spa_bt_monitor *monitor, const struct a2dp_codec *codec) +static bool is_media_codec_enabled(struct spa_bt_monitor *monitor, const struct media_codec *codec) { return spa_dict_lookup(&monitor->enabled_codecs, codec->name) != NULL; } @@ -492,7 +513,7 @@ DBusMessage *r; DBusError err; int size, res; - const struct a2dp_codec *codec; + const struct media_codec *codec; bool sink; dbus_error_init(&err); @@ -508,14 +529,14 @@ spa_log_info(monitor->log, "%p: %s select conf %d", monitor, path, size); spa_log_hexdump(monitor->log, SPA_LOG_LEVEL_DEBUG, 2, cap, (size_t)size); - codec = a2dp_endpoint_to_codec(monitor, path, &sink); + codec = media_endpoint_to_codec(monitor, path, &sink); if (codec != NULL) /* FIXME: We can't determine which device the SelectConfiguration() * call is associated with, therefore device settings are not passed. * This causes inconsistency with SelectConfiguration() triggered * by codec switching. */ - res = codec->select_config(codec, sink ? A2DP_CODEC_FLAG_SINK : 0, cap, size, &monitor->default_audio_info, + res = codec->select_config(codec, sink ? MEDIA_CODEC_FLAG_SINK : 0, cap, size, &monitor->default_audio_info, &monitor->global_settings, config); else res = -ENOTSUP; @@ -545,6 +566,171 @@ return DBUS_HANDLER_RESULT_HANDLED; } +static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant); +static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, const char* key, const char* variant_type_str, const char* array_type_str, int array_type_int, void* data, int data_size); +static struct spa_bt_remote_endpoint *remote_endpoint_find(struct spa_bt_monitor *monitor, const char *path); + +static DBusHandlerResult endpoint_select_properties(DBusConnection *conn, DBusMessage *m, void *userdata) +{ + struct spa_bt_monitor *monitor = userdata; + const char *path; + const char *object_path; + DBusMessageIter args, props, iter; + DBusMessage *r = NULL; + int size, res; + const struct media_codec *codec; + bool sink; + + if (!dbus_message_iter_init(m, &args) || !spa_streq(dbus_message_get_signature(m), "a{sv}")) { + spa_log_error(monitor->log, "Invalid signature for method SelectProperties()"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + dbus_message_iter_recurse(&args, &props); + if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + path = dbus_message_get_path(m); + + codec = media_endpoint_to_codec(monitor, path, &sink); + if (!codec) { + res = -ENOTSUP; + spa_log_error(monitor->log, "Unsupported codec: %d (%s)", + res, spa_strerror(res)); + if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", + "Unsupported codec")) == NULL) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto exit_send; + } + + /* Read transport properties */ + while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) { + const char *key;
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -51,7 +51,7 @@ #include <spa/debug/pod.h> #include "defs.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.device"); #undef SPA_LOG_TOPIC_DEFAULT @@ -73,6 +73,7 @@ DEVICE_PROFILE_AG = 1, DEVICE_PROFILE_A2DP = 2, DEVICE_PROFILE_HSP_HFP = 3, + DEVICE_PROFILE_BAP = 4, }; struct props { @@ -140,11 +141,11 @@ unsigned int save_profile:1; uint32_t prev_bt_connected_profiles; - const struct a2dp_codec **supported_codecs; + const struct media_codec **supported_codecs; size_t supported_codec_count; - struct dynamic_node dyn_a2dp_source; - struct dynamic_node dyn_a2dp_sink; + struct dynamic_node dyn_media_source; + struct dynamic_node dyn_media_sink; struct dynamic_node dyn_sco_source; struct dynamic_node dyn_sco_sink; @@ -167,9 +168,9 @@ } } -static void get_a2dp_codecs(struct impl *this, enum spa_bluetooth_audio_codec id, const struct a2dp_codec **codecs, size_t size) +static void get_media_codecs(struct impl *this, enum spa_bluetooth_audio_codec id, const struct media_codec **codecs, size_t size) { - const struct a2dp_codec * const *c; + const struct media_codec * const *c; spa_assert(size > 0); spa_assert(this->supported_codecs); @@ -184,18 +185,18 @@ *codecs = NULL; } -static const struct a2dp_codec *get_supported_a2dp_codec(struct impl *this, enum spa_bluetooth_audio_codec id, size_t *idx) +static const struct media_codec *get_supported_media_codec(struct impl *this, enum spa_bluetooth_audio_codec id, size_t *idx) { - const struct a2dp_codec *a2dp_codec = NULL; + const struct media_codec *media_codec = NULL; size_t i; for (i = 0; i < this->supported_codec_count; ++i) { if (this->supported_codecsi->id == id) { - a2dp_codec = this->supported_codecsi; + media_codec = this->supported_codecsi; if (idx) *idx = i; } } - return a2dp_codec; + return media_codec; } static unsigned int get_hfp_codec(enum spa_bluetooth_audio_codec id) @@ -245,10 +246,10 @@ static const char *get_codec_name(struct spa_bt_transport *t, bool a2dp_duplex) { - if (t->a2dp_codec != NULL) { - if (a2dp_duplex && t->a2dp_codec->duplex_codec) - return t->a2dp_codec->duplex_codec->name; - return t->a2dp_codec->name; + if (t->media_codec != NULL) { + if (a2dp_duplex && t->media_codec->duplex_codec) + return t->media_codec->duplex_codec->name; + return t->media_codec->name; } return get_hfp_codec_name(t->codec); } @@ -301,7 +302,7 @@ static float get_soft_volume_boost(struct node *node) { - const struct a2dp_codec *codec = node->transport ? node->transport->a2dp_codec : NULL; + const struct media_codec *codec = node->transport ? node->transport->media_codec : NULL; /* * For A2DP duplex, the duplex microphone channel sometimes does not appear @@ -351,6 +352,7 @@ /* PW is the controller for remote device. */ if (impl->profile != DEVICE_PROFILE_A2DP + && impl->profile != DEVICE_PROFILE_BAP && impl->profile != DEVICE_PROFILE_HSP_HFP) return false; @@ -406,16 +408,16 @@ static void get_channels(struct spa_bt_transport *t, bool a2dp_duplex, uint32_t *n_channels, uint32_t *channels) { - const struct a2dp_codec *codec; + const struct media_codec *codec; struct spa_audio_info info = { 0 }; - if (!a2dp_duplex || !t->a2dp_codec || !t->a2dp_codec->duplex_codec) { + if (!a2dp_duplex || !t->media_codec || !t->media_codec->duplex_codec) { *n_channels = t->n_channels; memcpy(channels, t->channels, t->n_channels * sizeof(uint32_t)); return; } - codec = t->a2dp_codec->duplex_codec; + codec = t->media_codec->duplex_codec; if (!codec->validate_config || codec->validate_config(codec, 0, @@ -514,7 +516,7 @@ spa_list_for_each(t, &device->transport_list, device_link) { bool codec_ok = codec == 0 || - (t->a2dp_codec != NULL && t->a2dp_codec->id == codec) || + (t->media_codec != NULL && t->media_codec->id == codec) || get_hfp_codec_id(t->codec) == codec; if ((t->profile & device->connected_profiles) && @@ -676,15 +678,15 @@ 1, SPA_NAME_API_BLUEZ5_SCO_SINK, false); } } - if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) { + if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_A2DP_SOURCE)) { t = find_transport(this, SPA_BT_PROFILE_A2DP_SOURCE, 0); if (t) { - this->props.codec = t->a2dp_codec->id; - emit_dynamic_node(&this->dyn_a2dp_source, this, t, + this->props.codec = t->media_codec->id; + emit_dynamic_node(&this->dyn_media_source, this, t, 2, SPA_NAME_API_BLUEZ5_A2DP_SOURCE, false); - if (t->a2dp_codec->duplex_codec) { - emit_dynamic_node(&this->dyn_a2dp_sink, this, t, + if (t->media_codec->duplex_codec) { + emit_dynamic_node(&this->dyn_media_sink, this, t, 3, SPA_NAME_API_BLUEZ5_A2DP_SINK, true); } } @@ -694,11 +696,11 @@ if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) { t = find_transport(this, SPA_BT_PROFILE_A2DP_SOURCE, 0); if (t) { - this->props.codec = t->a2dp_codec->id; - emit_dynamic_node(&this->dyn_a2dp_source, this, t, + this->props.codec = t->media_codec->id; + emit_dynamic_node(&this->dyn_media_source, this, t, DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_A2DP_SOURCE, false); - if (t->a2dp_codec->duplex_codec) { + if (t->media_codec->duplex_codec) { emit_node(this, t, DEVICE_ID_SINK, SPA_NAME_API_BLUEZ5_A2DP_SINK, true); } @@ -708,17 +710,45 @@ if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) { t = find_transport(this, SPA_BT_PROFILE_A2DP_SINK, this->props.codec); if (t) { - this->props.codec = t->a2dp_codec->id; + this->props.codec = t->media_codec->id; emit_node(this, t, DEVICE_ID_SINK, SPA_NAME_API_BLUEZ5_A2DP_SINK, false); - if (t->a2dp_codec->duplex_codec) { + if (t->media_codec->duplex_codec) { emit_node(this, t, DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_A2DP_SOURCE, true); } } } - if (get_supported_a2dp_codec(this, this->props.codec, NULL) == NULL) + if (get_supported_media_codec(this, this->props.codec, NULL) == NULL) + this->props.codec = 0; + break; + case DEVICE_PROFILE_BAP: + if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_BAP_SOURCE)) { + t = find_transport(this, SPA_BT_PROFILE_BAP_SOURCE, 0); + if (t) { + this->props.codec = t->media_codec->id; + if (t->bap_initiator) + emit_node(this, t, DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_MEDIA_SOURCE, false); + else + emit_dynamic_node(&this->dyn_media_source, this, t, + DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_MEDIA_SOURCE, false); + } + } + + if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_BAP_SINK)) { + t = find_transport(this, SPA_BT_PROFILE_BAP_SINK, this->props.codec); + if (t) {
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/codec-loader.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/codec-loader.c
Changed
@@ -29,7 +29,7 @@ #include "defs.h" #include "codec-loader.h" -#define A2DP_CODEC_LIB_BASE "bluez5/libspa-codec-bluez5-" +#define MEDIA_CODEC_LIB_BASE "bluez5/libspa-codec-bluez5-" /* AVDTP allows 0x3E endpoints, can't have more codecs than that */ #define MAX_CODECS 0x3E @@ -40,7 +40,7 @@ #define SPA_LOG_TOPIC_DEFAULT &log_topic struct impl { - const struct a2dp_codec *codecsMAX_CODECS + 1; + const struct media_codec *codecsMAX_CODECS + 1; struct spa_handle *handlesMAX_HANDLES; size_t n_codecs; size_t n_handles; @@ -48,9 +48,10 @@ struct spa_log *log; }; -static int codec_order(const struct a2dp_codec *c) +static int codec_order(const struct media_codec *c) { static const enum spa_bluetooth_audio_codec order = { + SPA_BLUETOOTH_AUDIO_CODEC_LC3, SPA_BLUETOOTH_AUDIO_CODEC_LDAC, SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD, SPA_BLUETOOTH_AUDIO_CODEC_APTX, @@ -78,8 +79,8 @@ static int codec_order_cmp(const void *a, const void *b) { - const struct a2dp_codec * const *ca = a; - const struct a2dp_codec * const *cb = b; + const struct media_codec * const *ca = a; + const struct media_codec * const *cb = b; int ia = codec_order(*ca); int ib = codec_order(*cb); if (*ca == *cb) @@ -87,7 +88,7 @@ return (ia == ib) ? (*ca < *cb ? -1 : 1) : ia - ib; } -static int load_a2dp_codecs_from(struct impl *impl, const char *factory_name, const char *libname) +static int load_media_codecs_from(struct impl *impl, const char *factory_name, const char *libname) { struct spa_handle *handle = NULL; void *iface; @@ -108,7 +109,7 @@ spa_log_debug(impl->log, "loading codecs from %s", factory_name); - if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Bluez5CodecA2DP, &iface)) < 0) { + if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Bluez5CodecMedia, &iface)) < 0) { spa_log_warn(impl->log, "Bluetooth codec plugin %s has no codec interface", factory_name); goto fail; @@ -116,15 +117,15 @@ bluez5_codec_a2dp = iface; - if (bluez5_codec_a2dp->iface.version != SPA_VERSION_BLUEZ5_CODEC_A2DP) { + if (bluez5_codec_a2dp->iface.version != SPA_VERSION_BLUEZ5_CODEC_MEDIA) { spa_log_warn(impl->log, "codec plugin %s has incompatible ABI version (%d != %d)", - factory_name, bluez5_codec_a2dp->iface.version, SPA_VERSION_BLUEZ5_CODEC_A2DP); + factory_name, bluez5_codec_a2dp->iface.version, SPA_VERSION_BLUEZ5_CODEC_MEDIA); res = -ENOENT; goto fail; } for (i = 0; bluez5_codec_a2dp->codecsi; ++i) { - const struct a2dp_codec *c = bluez5_codec_a2dp->codecsi; + const struct media_codec *c = bluez5_codec_a2dp->codecsi; size_t j; if (impl->n_codecs >= MAX_CODECS) { @@ -134,14 +135,14 @@ /* Don't load duplicate endpoints */ for (j = 0; j < impl->n_codecs; ++j) { - const struct a2dp_codec *c2 = impl->codecsj; + const struct media_codec *c2 = impl->codecsj; const char *ep1 = c->endpoint_name ? c->endpoint_name : c->name; const char *ep2 = c2->endpoint_name ? c2->endpoint_name : c2->name; if (spa_streq(ep1, ep2)) goto next_codec; } - spa_log_debug(impl->log, "loaded A2DP codec %s from %s", c->name, factory_name); + spa_log_debug(impl->log, "loaded media codec %s from %s", c->name, factory_name); if (c->set_log) c->set_log(impl->log); @@ -166,22 +167,23 @@ return res; } -const struct a2dp_codec * const *load_a2dp_codecs(struct spa_plugin_loader *loader, struct spa_log *log) +const struct media_codec * const *load_media_codecs(struct spa_plugin_loader *loader, struct spa_log *log) { struct impl *impl; bool has_sbc; size_t i; const struct { const char *factory; const char *lib; } plugins = { -#define A2DP_CODEC_FACTORY_LIB(basename) \ - { A2DP_CODEC_FACTORY_NAME(basename), A2DP_CODEC_LIB_BASE basename } - A2DP_CODEC_FACTORY_LIB("aac"), - A2DP_CODEC_FACTORY_LIB("aptx"), - A2DP_CODEC_FACTORY_LIB("faststream"), - A2DP_CODEC_FACTORY_LIB("ldac"), - A2DP_CODEC_FACTORY_LIB("sbc"), - A2DP_CODEC_FACTORY_LIB("lc3plus"), - A2DP_CODEC_FACTORY_LIB("opus") -#undef A2DP_CODEC_FACTORY_LIB +#define MEDIA_CODEC_FACTORY_LIB(basename) \ + { MEDIA_CODEC_FACTORY_NAME(basename), MEDIA_CODEC_LIB_BASE basename } + MEDIA_CODEC_FACTORY_LIB("aac"), + MEDIA_CODEC_FACTORY_LIB("aptx"), + MEDIA_CODEC_FACTORY_LIB("faststream"), + MEDIA_CODEC_FACTORY_LIB("ldac"), + MEDIA_CODEC_FACTORY_LIB("sbc"), + MEDIA_CODEC_FACTORY_LIB("lc3plus"), + MEDIA_CODEC_FACTORY_LIB("opus"), + MEDIA_CODEC_FACTORY_LIB("lc3") +#undef MEDIA_CODEC_FACTORY_LIB }; impl = calloc(sizeof(struct impl), 1); @@ -194,7 +196,7 @@ spa_log_topic_init(impl->log, &log_topic); for (i = 0; i < SPA_N_ELEMENTS(plugins); ++i) - load_a2dp_codecs_from(impl, pluginsi.factory, pluginsi.lib); + load_media_codecs_from(impl, pluginsi.factory, pluginsi.lib); has_sbc = false; for (i = 0; i < impl->n_codecs; ++i) @@ -203,19 +205,19 @@ if (!has_sbc) { spa_log_error(impl->log, "failed to load A2DP SBC codec from plugins"); - free_a2dp_codecs(impl->codecs); + free_media_codecs(impl->codecs); errno = ENOENT; return NULL; } - qsort(impl->codecs, impl->n_codecs, sizeof(const struct a2dp_codec *), codec_order_cmp); + qsort(impl->codecs, impl->n_codecs, sizeof(const struct media_codec *), codec_order_cmp); return impl->codecs; } -void free_a2dp_codecs(const struct a2dp_codec * const *a2dp_codecs) +void free_media_codecs(const struct media_codec * const *media_codecs) { - struct impl *impl = SPA_CONTAINER_OF(a2dp_codecs, struct impl, codecs); + struct impl *impl = SPA_CONTAINER_OF(media_codecs, struct impl, codecs); size_t i; for (i = 0; i < impl->n_handles; ++i)
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/codec-loader.h -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/codec-loader.h
Changed
@@ -31,9 +31,9 @@ #include <spa/support/plugin-loader.h> #include "a2dp-codec-caps.h" -#include "a2dp-codecs.h" +#include "media-codecs.h" -const struct a2dp_codec * const *load_a2dp_codecs(struct spa_plugin_loader *loader, struct spa_log *log); -void free_a2dp_codecs(const struct a2dp_codec * const *a2dp_codecs); +const struct media_codec * const *load_media_codecs(struct spa_plugin_loader *loader, struct spa_log *log); +void free_media_codecs(const struct media_codec * const *media_codecs); #endif
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/defs.h
Changed
@@ -141,6 +141,9 @@ #define SPA_BT_UUID_HSP_AG "00001112-0000-1000-8000-00805f9b34fb" #define SPA_BT_UUID_HFP_HF "0000111e-0000-1000-8000-00805f9b34fb" #define SPA_BT_UUID_HFP_AG "0000111f-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_PACS "00001850-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_BAP_SINK "00002bc9-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_BAP_SOURCE "00002bcb-0000-1000-8000-00805f9b34fb" #define PROFILE_HSP_AG "/Profile/HSPAG" #define PROFILE_HSP_HS "/Profile/HSPHS" @@ -158,9 +161,12 @@ #define HFP_AUDIO_CODEC_CVSD 0x01 #define HFP_AUDIO_CODEC_MSBC 0x02 -#define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint" -#define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink" -#define A2DP_SOURCE_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSource" +#define MEDIA_OBJECT_MANAGER_PATH "/MediaEndpoint" +#define A2DP_SINK_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/A2DPSink" +#define A2DP_SOURCE_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/A2DPSource" + +#define BAP_SINK_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/BAPSink" +#define BAP_SOURCE_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/BAPSource" #define SPA_BT_UNKNOWN_DELAY 0 @@ -172,19 +178,30 @@ #define MSBC_ENCODED_SIZE 60 /* 2 bytes header + 57 mSBC payload + 1 byte padding */ #define MSBC_PAYLOAD_SIZE 57 +enum spa_bt_media_direction { + SPA_BT_MEDIA_SOURCE, + SPA_BT_MEDIA_SINK, +}; + enum spa_bt_profile { SPA_BT_PROFILE_NULL = 0, - SPA_BT_PROFILE_A2DP_SINK = (1 << 0), - SPA_BT_PROFILE_A2DP_SOURCE = (1 << 1), - SPA_BT_PROFILE_HSP_HS = (1 << 2), - SPA_BT_PROFILE_HSP_AG = (1 << 3), - SPA_BT_PROFILE_HFP_HF = (1 << 4), - SPA_BT_PROFILE_HFP_AG = (1 << 5), + SPA_BT_PROFILE_BAP_SINK = (1 << 0), + SPA_BT_PROFILE_BAP_SOURCE = (1 << 1), + SPA_BT_PROFILE_A2DP_SINK = (1 << 2), + SPA_BT_PROFILE_A2DP_SOURCE = (1 << 3), + SPA_BT_PROFILE_HSP_HS = (1 << 4), + SPA_BT_PROFILE_HSP_AG = (1 << 5), + SPA_BT_PROFILE_HFP_HF = (1 << 6), + SPA_BT_PROFILE_HFP_AG = (1 << 7), SPA_BT_PROFILE_A2DP_DUPLEX = (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_A2DP_SOURCE), + SPA_BT_PROFILE_BAP_DUPLEX = (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE), SPA_BT_PROFILE_HEADSET_HEAD_UNIT = (SPA_BT_PROFILE_HSP_HS | SPA_BT_PROFILE_HFP_HF), SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY = (SPA_BT_PROFILE_HSP_AG | SPA_BT_PROFILE_HFP_AG), SPA_BT_PROFILE_HEADSET_AUDIO = (SPA_BT_PROFILE_HEADSET_HEAD_UNIT | SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY), + + SPA_BT_PROFILE_MEDIA_SINK = (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_BAP_SINK), + SPA_BT_PROFILE_MEDIA_SOURCE = (SPA_BT_PROFILE_A2DP_SOURCE | SPA_BT_PROFILE_BAP_SOURCE), }; static inline enum spa_bt_profile spa_bt_profile_from_uuid(const char *uuid) @@ -203,6 +220,10 @@ return SPA_BT_PROFILE_HFP_HF; else if (strcasecmp(uuid, SPA_BT_UUID_HFP_AG) == 0) return SPA_BT_PROFILE_HFP_AG; + else if (strcasecmp(uuid, SPA_BT_UUID_BAP_SINK) == 0) + return SPA_BT_PROFILE_BAP_SINK; + else if (strcasecmp(uuid, SPA_BT_UUID_BAP_SOURCE) == 0) + return SPA_BT_PROFILE_BAP_SOURCE; else return 0; } @@ -303,6 +324,12 @@ return "headset-audio-gateway"; case SPA_BT_PROFILE_HEADSET_AUDIO: return "headset-audio"; + case SPA_BT_PROFILE_BAP_SOURCE: + return "bap-source"; + case SPA_BT_PROFILE_BAP_SINK: + return "bap-sink"; + case SPA_BT_PROFILE_BAP_DUPLEX: + return "bap-duplex"; default: break; } @@ -412,7 +439,7 @@ return SPA_BT_FORM_FACTOR_UNKNOWN; } -struct spa_bt_a2dp_codec_switch; +struct spa_bt_media_codec_switch; struct spa_bt_transport; struct spa_bt_device_events { @@ -482,16 +509,16 @@ DBusPendingCall *battery_pending_call; }; -struct a2dp_codec; +struct media_codec; struct spa_bt_device *spa_bt_device_find(struct spa_bt_monitor *monitor, const char *path); struct spa_bt_device *spa_bt_device_find_by_address(struct spa_bt_monitor *monitor, const char *remote_address, const char *local_address); int spa_bt_device_add_profile(struct spa_bt_device *device, enum spa_bt_profile profile); int spa_bt_device_connect_profile(struct spa_bt_device *device, enum spa_bt_profile profile); int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force); -int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec * const *codecs); -bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink); -const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink); +int spa_bt_device_ensure_media_codec(struct spa_bt_device *device, const struct media_codec * const *codecs); +bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const struct media_codec *codec, bool sink); +const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_bt_device *device, size_t *count, bool sink); int spa_bt_device_ensure_hfp_codec(struct spa_bt_device *device, unsigned int codec); int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int codec); int spa_bt_device_release_transports(struct spa_bt_device *device); @@ -570,11 +597,13 @@ struct spa_list device_link; enum spa_bt_profile profile; enum spa_bt_transport_state state; - const struct a2dp_codec *a2dp_codec; + const struct media_codec *media_codec; unsigned int codec; void *configuration; int configuration_len; char *endpoint_path; + bool bap_initiator; + struct spa_list bap_transport_linked; uint32_t n_channels; uint32_t channels64;
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-codecs.c
Added
@@ -0,0 +1,209 @@ +/* + * BlueALSA - bluez-a2dp.c + * Copyright (c) 2016-2017 Arkadiusz Bokowy + * + * This file is a part of bluez-alsa. + * + * This project is licensed under the terms of the MIT license. + * + */ + +#include <spa/utils/string.h> + +#include "media-codecs.h" + +int media_codec_select_config(const struct media_codec_config configs, size_t n, + uint32_t cap, int preferred_value) +{ + size_t i; + int *scores, res; + unsigned int max_priority; + + if (n == 0) + return -EINVAL; + + scores = calloc(n, sizeof(int)); + if (scores == NULL) + return -errno; + + max_priority = configs0.priority; + for (i = 1; i < n; ++i) { + if (configsi.priority > max_priority) + max_priority = configsi.priority; + } + + for (i = 0; i < n; ++i) { + if (!(configsi.config & cap)) { + scoresi = -1; + continue; + } + if (configsi.value == preferred_value) + scoresi = 100 * (max_priority + 1); + else if (configsi.value > preferred_value) + scoresi = 10 * (max_priority + 1); + else + scoresi = 1; + + scoresi *= configsi.priority + 1; + } + + res = 0; + for (i = 1; i < n; ++i) { + if (scoresi > scoresres) + res = i; + } + + if (scoresres < 0) + res = -EINVAL; + + free(scores); + return res; +} + +bool media_codec_check_caps(const struct media_codec *codec, unsigned int codec_id, + const void *caps, size_t caps_size, + const struct media_codec_audio_info *info, + const struct spa_dict *global_settings) +{ + uint8_t configA2DP_MAX_CAPS_SIZE; + int res; + + if (codec_id != codec->codec_id) + return false; + + if (caps == NULL) + return false; + + res = codec->select_config(codec, 0, caps, caps_size, info, global_settings, config); + if (res < 0) + return false; + + return ((size_t)res == caps_size); +} + +#ifdef CODEC_PLUGIN + +struct impl { + struct spa_handle handle; + struct spa_bluez5_codec_a2dp bluez5_codec_a2dp; +}; + +static int +impl_get_interface(struct spa_handle *handle, const char *type, void **interface) +{ + struct impl *this; + + spa_return_val_if_fail(handle != NULL, -EINVAL); + spa_return_val_if_fail(interface != NULL, -EINVAL); + + this = (struct impl *) handle; + + if (spa_streq(type, SPA_TYPE_INTERFACE_Bluez5CodecMedia)) + *interface = &this->bluez5_codec_a2dp; + else + return -ENOENT; + + return 0; +} + +static int +impl_clear(struct spa_handle *handle) +{ + spa_return_val_if_fail(handle != NULL, -EINVAL); + return 0; +} + +static size_t +impl_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params) +{ + return sizeof(struct impl); +} + +static int +impl_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) +{ + struct impl *this; + + spa_return_val_if_fail(factory != NULL, -EINVAL); + spa_return_val_if_fail(handle != NULL, -EINVAL); + + handle->get_interface = impl_get_interface; + handle->clear = impl_clear; + + this = (struct impl *) handle; + + this->bluez5_codec_a2dp.codecs = codec_plugin_media_codecs; + this->bluez5_codec_a2dp.iface = SPA_INTERFACE_INIT( + SPA_TYPE_INTERFACE_Bluez5CodecMedia, + SPA_VERSION_BLUEZ5_CODEC_MEDIA, + NULL, + this); + + return 0; +} + +static const struct spa_interface_info impl_interfaces = { + {SPA_TYPE_INTERFACE_Bluez5CodecMedia,}, +}; + +static int +impl_enum_interface_info(const struct spa_handle_factory *factory, + const struct spa_interface_info **info, + uint32_t *index) +{ + spa_return_val_if_fail(factory != NULL, -EINVAL); + spa_return_val_if_fail(info != NULL, -EINVAL); + spa_return_val_if_fail(index != NULL, -EINVAL); + + switch (*index) { + case 0: + *info = &impl_interfaces*index; + break; + default: + return 0; + } + (*index)++; + + return 1; +} + +static const struct spa_dict_item handle_info_items = { + { SPA_KEY_FACTORY_DESCRIPTION, "Bluetooth codec plugin" }, +}; + +static const struct spa_dict handle_info = SPA_DICT_INIT_ARRAY(handle_info_items); + +static struct spa_handle_factory handle_factory = { + SPA_VERSION_HANDLE_FACTORY, + NULL, + &handle_info, + impl_get_size, + impl_init, + impl_enum_interface_info, +}; + +SPA_EXPORT +int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) +{ + spa_return_val_if_fail(factory != NULL, -EINVAL); + spa_return_val_if_fail(index != NULL, -EINVAL); + + if (handle_factory.name == NULL) + handle_factory.name = codec_plugin_factory_name; + + switch (*index) { + case 0:
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-codecs.h
Added
@@ -0,0 +1,184 @@ +/* Spa A2DP codec API + * + * Copyright © 2020 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef SPA_BLUEZ5_A2DP_CODECS_H_ +#define SPA_BLUEZ5_A2DP_CODECS_H_ + +#include <stdint.h> +#include <stddef.h> + +#include <spa/param/audio/format.h> +#include <spa/param/bluetooth/audio.h> +#include <spa/utils/names.h> +#include <spa/support/plugin.h> +#include <spa/pod/pod.h> +#include <spa/pod/builder.h> +#include <spa/support/log.h> + +#include "a2dp-codec-caps.h" + +/* + * The codec plugin SPA interface is private. The version should be incremented + * when any of the structs or semantics change. + */ + +#define SPA_TYPE_INTERFACE_Bluez5CodecMedia SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:Media:Private" + +#define SPA_VERSION_BLUEZ5_CODEC_MEDIA 5 + +struct spa_bluez5_codec_a2dp { + struct spa_interface iface; + const struct media_codec * const *codecs; /**< NULL terminated array */ +}; + +#define MEDIA_CODEC_FACTORY_NAME(basename) (SPA_NAME_API_CODEC_BLUEZ5_MEDIA "." basename) + +#ifdef CODEC_PLUGIN +#define MEDIA_CODEC_EXPORT_DEF(basename,...) \ + const char *codec_plugin_factory_name = MEDIA_CODEC_FACTORY_NAME(basename); \ + static const struct media_codec * const codec_plugin_media_codec_list = { __VA_ARGS__, NULL }; \ + const struct media_codec * const * const codec_plugin_media_codecs = codec_plugin_media_codec_list; + +extern const struct media_codec * const * const codec_plugin_media_codecs; +extern const char *codec_plugin_factory_name; +#endif + +#define MEDIA_CODEC_FLAG_SINK (1 << 0) + +#define A2DP_CODEC_DEFAULT_RATE 48000 +#define A2DP_CODEC_DEFAULT_CHANNELS 2 + +enum { + NEED_FLUSH_NO = 0, + NEED_FLUSH_ALL = 1, + NEED_FLUSH_FRAGMENT = 2, +}; + +struct media_codec_audio_info { + uint32_t rate; + uint32_t channels; +}; + +struct codec_qos { + uint32_t interval; + bool framing; + char *phy; + uint16_t sdu; + uint8_t retransmission; + uint16_t latency; + uint32_t delay; +}; + +struct media_codec { + enum spa_bluetooth_audio_codec id; + uint8_t codec_id; + a2dp_vendor_codec_t vendor; + + bool bap; + + const char *name; + const char *description; + const char *endpoint_name; /**< Endpoint name. If NULL, same as name */ + const struct spa_dict *info; + + const size_t send_buf_size; + + const struct media_codec *duplex_codec; /**< Codec for non-standard A2DP duplex channel */ + + struct spa_log *log; + + int (*fill_caps) (const struct media_codec *codec, uint32_t flags, + uint8_t capsA2DP_MAX_CAPS_SIZE); + int (*select_config) (const struct media_codec *codec, uint32_t flags, + const void *caps, size_t caps_size, + const struct media_codec_audio_info *info, + const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE); + int (*enum_config) (const struct media_codec *codec, uint32_t flags, + const void *caps, size_t caps_size, uint32_t id, uint32_t idx, + struct spa_pod_builder *builder, struct spa_pod **param); + int (*validate_config) (const struct media_codec *codec, uint32_t flags, + const void *caps, size_t caps_size, + struct spa_audio_info *info); + void (*get_qos)(const struct media_codec *codec, + const void *config, size_t config_size, + struct codec_qos *qos); + + /** qsort comparison sorting caps in order of preference for the codec. + * Used in codec switching to select best remote endpoints. + * The caps handed in correspond to this codec_id, but are + * otherwise not checked beforehand. + */ + int (*caps_preference_cmp) (const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info, + const struct spa_dict *global_settings); + + void *(*init_props) (const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings); + void (*clear_props) (void *); + int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx, + struct spa_pod_builder *builder, struct spa_pod **param); + int (*set_props) (void *props, const struct spa_pod *param); + + void *(*init) (const struct media_codec *codec, uint32_t flags, void *config, size_t config_size, + const struct spa_audio_info *info, void *props, size_t mtu); + void (*deinit) (void *data); + + int (*update_props) (void *data, void *props); + + int (*get_block_size) (void *data); + + int (*abr_process) (void *data, size_t unsent); + + int (*start_encode) (void *data, + void *dst, size_t dst_size, uint16_t seqnum, uint32_t timestamp); + int (*encode) (void *data, + const void *src, size_t src_size, + void *dst, size_t dst_size, + size_t *dst_out, int *need_flush); + + int (*start_decode) (void *data, + const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp); + int (*decode) (void *data, + const void *src, size_t src_size, + void *dst, size_t dst_size, + size_t *dst_out); + + int (*reduce_bitpool) (void *data); + int (*increase_bitpool) (void *data); + + void (*set_log) (struct spa_log *global_log); +}; + +struct media_codec_config { + uint32_t config; + int value; + unsigned int priority; +}; + +int media_codec_select_config(const struct media_codec_config configs, size_t n, + uint32_t cap, int preferred_value); + +bool media_codec_check_caps(const struct media_codec *codec, unsigned int codec_id, + const void *caps, size_t caps_size, const struct media_codec_audio_info *info, + const struct spa_dict *global_settings); + +#endif
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-sink.c
Added
@@ -0,0 +1,1854 @@ +/* Spa Media Sink + * + * Copyright © 2018 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <unistd.h> +#include <stddef.h> +#include <stdio.h> +#include <arpa/inet.h> +#include <sys/ioctl.h> + +#include <spa/support/plugin.h> +#include <spa/support/loop.h> +#include <spa/support/log.h> +#include <spa/support/system.h> +#include <spa/utils/list.h> +#include <spa/utils/keys.h> +#include <spa/utils/names.h> +#include <spa/utils/result.h> +#include <spa/utils/string.h> +#include <spa/monitor/device.h> + +#include <spa/node/node.h> +#include <spa/node/utils.h> +#include <spa/node/io.h> +#include <spa/node/keys.h> +#include <spa/param/param.h> +#include <spa/param/latency-utils.h> +#include <spa/param/audio/format.h> +#include <spa/param/audio/format-utils.h> +#include <spa/pod/filter.h> + +#include <sbc/sbc.h> + +#include "defs.h" +#include "rtp.h" +#include "media-codecs.h" + +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.sink.media"); +#undef SPA_LOG_TOPIC_DEFAULT +#define SPA_LOG_TOPIC_DEFAULT &log_topic + +#define DEFAULT_CLOCK_NAME "clock.system.monotonic" + +struct props { + uint32_t min_latency; + uint32_t max_latency; + int64_t latency_offset; + char clock_name64; +}; + +#define FILL_FRAMES 2 +#define MAX_BUFFERS 32 +#define MIN_LATENCY 128 +#define MAX_LATENCY 8192 +#define BUFFER_SIZE (MAX_LATENCY*8) + +struct buffer { + uint32_t id; +#define BUFFER_FLAG_OUT (1<<0) + uint32_t flags; + struct spa_buffer *buf; + struct spa_meta_header *h; + struct spa_list link; +}; + +struct port { + struct spa_audio_info current_format; + uint32_t frame_size; + unsigned int have_format:1; + + uint64_t info_all; + struct spa_port_info info; + struct spa_io_buffers *io; + struct spa_latency_info latency; +#define IDX_EnumFormat 0 +#define IDX_Meta 1 +#define IDX_IO 2 +#define IDX_Format 3 +#define IDX_Buffers 4 +#define IDX_Latency 5 +#define N_PORT_PARAMS 6 + struct spa_param_info paramsN_PORT_PARAMS; + + struct buffer buffersMAX_BUFFERS; + uint32_t n_buffers; + + struct spa_list free; + struct spa_list ready; + + size_t ready_offset; +}; + +struct impl { + struct spa_handle handle; + struct spa_node node; + + struct spa_log *log; + struct spa_loop *data_loop; + struct spa_system *data_system; + + struct spa_hook_list hooks; + struct spa_callbacks callbacks; + + uint64_t info_all; + struct spa_node_info info; +#define IDX_PropInfo 0 +#define IDX_Props 1 +#define N_NODE_PARAMS 2 + struct spa_param_info paramsN_NODE_PARAMS; + struct props props; + + struct spa_bt_transport *transport; + struct spa_hook transport_listener; + + struct port port; + + unsigned int started:1; + unsigned int following:1; + unsigned int is_output:1; + + unsigned int is_duplex:1; + + struct spa_source source; + int timerfd; + struct spa_source flush_source; + struct spa_source flush_timer_source; + int flush_timerfd; + + struct spa_io_clock *clock; + struct spa_io_position *position; + + uint64_t current_time; + uint64_t next_time; + uint64_t last_error; + + const struct media_codec *codec; + bool codec_props_changed; + void *codec_props; + void *codec_data; + struct spa_audio_info codec_format; + + int need_flush; + bool fragment; + uint64_t fragment_timeout; + uint32_t block_size; + uint8_t bufferBUFFER_SIZE; + uint32_t buffer_used; + uint32_t header_size; + uint32_t frame_count; + uint16_t seqnum; + uint32_t timestamp; + uint64_t sample_count; + uint8_t tmp_bufferBUFFER_SIZE; + uint32_t tmp_buffer_used; + uint32_t fd_buffer_size; + + /* Times */ + uint64_t start_time; + uint64_t total_samples; +}; + +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) + +static void reset_props(struct impl *this, struct props *props) +{ + props->min_latency = MIN_LATENCY; + props->max_latency = MAX_LATENCY; + props->latency_offset = 0; + strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name)); +} + +static int impl_node_enum_params(void *object, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) +{ + struct impl *this = object; + struct spa_pod *param; + struct spa_pod_builder b = { 0 }; + uint8_t buffer1024;
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-source.c
Added
@@ -0,0 +1,1663 @@ +/* Spa Media Source + * + * Copyright © 2018 Wim Taymans + * Copyright © 2019 Collabora Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <unistd.h> +#include <stddef.h> +#include <stdio.h> +#include <time.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <spa/support/plugin.h> +#include <spa/support/loop.h> +#include <spa/support/log.h> +#include <spa/support/system.h> +#include <spa/utils/list.h> +#include <spa/utils/keys.h> +#include <spa/utils/names.h> +#include <spa/utils/result.h> +#include <spa/utils/string.h> +#include <spa/monitor/device.h> + +#include <spa/node/node.h> +#include <spa/node/utils.h> +#include <spa/node/io.h> +#include <spa/node/keys.h> +#include <spa/param/param.h> +#include <spa/param/latency-utils.h> +#include <spa/param/audio/format.h> +#include <spa/param/audio/format-utils.h> +#include <spa/pod/filter.h> + +#include "defs.h" +#include "rtp.h" +#include "media-codecs.h" + +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.source.media"); +#undef SPA_LOG_TOPIC_DEFAULT +#define SPA_LOG_TOPIC_DEFAULT &log_topic + +#include "decode-buffer.h" + +#define DEFAULT_CLOCK_NAME "clock.system.monotonic" + +struct props { + char clock_name64; +}; + +#define FILL_FRAMES 2 +#define MAX_BUFFERS 32 + +struct buffer { + uint32_t id; + unsigned int outstanding:1; + struct spa_buffer *buf; + struct spa_meta_header *h; + struct spa_list link; +}; + +struct port { + struct spa_audio_info current_format; + uint32_t frame_size; + unsigned int have_format:1; + + uint64_t info_all; + struct spa_port_info info; + struct spa_io_buffers *io; + struct spa_io_rate_match *rate_match; + struct spa_latency_info latency; +#define IDX_EnumFormat 0 +#define IDX_Meta 1 +#define IDX_IO 2 +#define IDX_Format 3 +#define IDX_Buffers 4 +#define IDX_Latency 5 +#define N_PORT_PARAMS 6 + struct spa_param_info paramsN_PORT_PARAMS; + + struct buffer buffersMAX_BUFFERS; + uint32_t n_buffers; + + struct spa_list free; + struct spa_list ready; + + struct spa_bt_decode_buffer buffer; +}; + +struct impl { + struct spa_handle handle; + struct spa_node node; + + struct spa_log *log; + struct spa_loop *data_loop; + struct spa_system *data_system; + + struct spa_hook_list hooks; + struct spa_callbacks callbacks; + + uint32_t quantum_limit; + + uint64_t info_all; + struct spa_node_info info; +#define IDX_PropInfo 0 +#define IDX_Props 1 +#define IDX_NODE_IO 2 +#define N_NODE_PARAMS 3 + struct spa_param_info paramsN_NODE_PARAMS; + struct props props; + + struct spa_bt_transport *transport; + struct spa_hook transport_listener; + + struct port port; + + unsigned int started:1; + unsigned int transport_acquired:1; + unsigned int following:1; + unsigned int matching:1; + unsigned int resampling:1; + + unsigned int is_input:1; + unsigned int is_duplex:1; + unsigned int use_duplex_source:1; + + int fd; + struct spa_source source; + + struct spa_source timer_source; + int timerfd; + + struct spa_io_clock *clock; + struct spa_io_position *position; + + uint64_t current_time; + uint64_t next_time; + + const struct media_codec *codec; + bool codec_props_changed; + void *codec_props; + void *codec_data; + struct spa_audio_info codec_format; + + uint8_t buffer_read4096; + struct timespec now; + uint64_t sample_count; + + int duplex_timerfd; + uint64_t duplex_timeout; +}; + +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) + +static void reset_props(struct props *props) +{ + strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name)); +} + +static int impl_node_enum_params(void *object, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) +{ + struct impl *this = object; + struct spa_pod *param; + struct spa_pod_builder b = { 0 }; + uint8_t buffer1024; + struct spa_result_node_params result; + uint32_t count = 0, index_offset = 0; + bool enum_codec = false; + + spa_return_val_if_fail(this != NULL, -EINVAL); + spa_return_val_if_fail(num != 0, -EINVAL); + + result.id = id; + result.next = start; + next: + result.index = result.next++; +
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/meson.build
Changed
@@ -17,9 +17,9 @@ bluez5_sources = 'plugin.c', 'codec-loader.c', - 'a2dp-codecs.c', - 'a2dp-sink.c', - 'a2dp-source.c', + 'media-codecs.c', + 'media-sink.c', + 'media-source.c', 'sco-sink.c', 'sco-source.c', 'sco-io.c', @@ -59,7 +59,7 @@ codec_args = '-DCODEC_PLUGIN' bluez_codec_sbc = shared_library('spa-codec-bluez5-sbc', - 'a2dp-codec-sbc.c', 'a2dp-codecs.c' , + 'a2dp-codec-sbc.c', 'media-codecs.c' , include_directories : configinc , c_args : codec_args, dependencies : spa_dep, sbc_dep , @@ -67,7 +67,7 @@ install_dir : spa_plugindir / 'bluez5') bluez_codec_faststream = shared_library('spa-codec-bluez5-faststream', - 'a2dp-codec-faststream.c', 'a2dp-codecs.c' , + 'a2dp-codec-faststream.c', 'media-codecs.c' , include_directories : configinc , c_args : codec_args, dependencies : spa_dep, sbc_dep , @@ -76,7 +76,7 @@ if fdk_aac_dep.found() bluez_codec_aac = shared_library('spa-codec-bluez5-aac', - 'a2dp-codec-aac.c', 'a2dp-codecs.c' , + 'a2dp-codec-aac.c', 'media-codecs.c' , include_directories : configinc , c_args : codec_args, dependencies : spa_dep, fdk_aac_dep , @@ -86,7 +86,7 @@ if aptx_dep.found() bluez_codec_aptx = shared_library('spa-codec-bluez5-aptx', - 'a2dp-codec-aptx.c', 'a2dp-codecs.c' , + 'a2dp-codec-aptx.c', 'media-codecs.c' , include_directories : configinc , c_args : codec_args, dependencies : spa_dep, aptx_dep, sbc_dep , @@ -102,7 +102,7 @@ ldac_dep += ldac_abr_dep endif bluez_codec_ldac = shared_library('spa-codec-bluez5-ldac', - 'a2dp-codec-ldac.c', 'a2dp-codecs.c' , + 'a2dp-codec-ldac.c', 'media-codecs.c' , include_directories : configinc , c_args : ldac_args, dependencies : spa_dep, ldac_dep , @@ -112,7 +112,7 @@ if get_option('bluez5-codec-lc3plus').allowed() and lc3plus_dep.found() bluez_codec_lc3plus = shared_library('spa-codec-bluez5-lc3plus', - 'a2dp-codec-lc3plus.c', 'a2dp-codecs.c' , + 'a2dp-codec-lc3plus.c', 'media-codecs.c' , include_directories : configinc , c_args : codec_args, dependencies : spa_dep, lc3plus_dep, mathlib , @@ -124,10 +124,20 @@ opus_args = codec_args opus_dep = opus_dep bluez_codec_opus = shared_library('spa-codec-bluez5-opus', - 'a2dp-codec-opus.c', 'a2dp-codecs.c' , + 'a2dp-codec-opus.c', 'media-codecs.c' , include_directories : configinc , c_args : opus_args, dependencies : spa_dep, opus_dep, mathlib , install : true, install_dir : spa_plugindir / 'bluez5') endif + +if get_option('bluez5-codec-lc3').allowed() and lc3_dep.found() + bluez_codec_lc3 = shared_library('spa-codec-bluez5-lc3', + 'bap-codec-lc3.c', 'media-codecs.c' , + include_directories : configinc , + c_args : codec_args, + dependencies : spa_dep, lc3_dep, mathlib , + install : true, + install_dir : spa_plugindir / 'bluez5') +endif
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/plugin.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/plugin.c
Changed
@@ -29,10 +29,12 @@ extern const struct spa_handle_factory spa_bluez5_dbus_factory; extern const struct spa_handle_factory spa_bluez5_device_factory; -extern const struct spa_handle_factory spa_a2dp_sink_factory; -extern const struct spa_handle_factory spa_a2dp_source_factory; +extern const struct spa_handle_factory spa_media_sink_factory; +extern const struct spa_handle_factory spa_media_source_factory; extern const struct spa_handle_factory spa_sco_sink_factory; extern const struct spa_handle_factory spa_sco_source_factory; +extern const struct spa_handle_factory spa_a2dp_sink_factory; +extern const struct spa_handle_factory spa_a2dp_source_factory; SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) @@ -48,10 +50,10 @@ *factory = &spa_bluez5_device_factory; break; case 2: - *factory = &spa_a2dp_sink_factory; + *factory = &spa_media_sink_factory; break; case 3: - *factory = &spa_a2dp_source_factory; + *factory = &spa_media_source_factory; break; case 4: *factory = &spa_sco_sink_factory; @@ -59,6 +61,12 @@ case 5: *factory = &spa_sco_source_factory; break; + case 6: + *factory = &spa_a2dp_sink_factory; + break; + case 7: + *factory = &spa_a2dp_source_factory; + break; default: return 0; }
View file
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/quirks.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/quirks.c
Changed
@@ -56,7 +56,6 @@ #include <spa/utils/json.h> #include <spa/utils/string.h> -#include "a2dp-codecs.h" #include "defs.h" static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.quirks");
View file
pipewire-0.3.58.tar.gz/spa/plugins/libcamera/libcamera-device.cpp -> pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-device.cpp
Changed
@@ -54,30 +54,29 @@ using namespace libcamera; -struct props { - char device128; - char device_name128; -}; - -static void reset_props(struct props *props) -{ - spa_zero(*props); -} +namespace { struct impl { struct spa_handle handle; - struct spa_device device; + struct spa_device device = {}; struct spa_log *log; - struct props props; + std::string device_id; struct spa_hook_list hooks; - CameraManager *manager; + std::shared_ptr<CameraManager> manager; std::shared_ptr<Camera> camera; + + impl(spa_log *log, + std::shared_ptr<CameraManager> manager, + std::shared_ptr<Camera> camera, + std::string device_id); }; +} + static std::string cameraModel(const Camera *camera) { const ControlList &props = camera->properties(); @@ -120,11 +119,11 @@ info.change_mask = SPA_DEVICE_CHANGE_MASK_PROPS; #define ADD_ITEM(key, value) itemsn_items++ = SPA_DICT_ITEM_INIT(key, value) - snprintf(path, sizeof(path), "libcamera:%s", impl->props.device); + snprintf(path, sizeof(path), "libcamera:%s", impl->device_id.c_str()); ADD_ITEM(SPA_KEY_OBJECT_PATH, path); ADD_ITEM(SPA_KEY_DEVICE_API, "libcamera"); ADD_ITEM(SPA_KEY_MEDIA_CLASS, "Video/Device"); - ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, impl->props.device); + ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, impl->device_id.c_str()); if (auto location = cameraLoc(impl->camera.get())) ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location); @@ -132,7 +131,7 @@ snprintf(model, sizeof(model), "%s", cameraModel(impl->camera.get()).c_str()); ADD_ITEM(SPA_KEY_DEVICE_PRODUCT_NAME, model); ADD_ITEM(SPA_KEY_DEVICE_DESCRIPTION, model); - snprintf(name, sizeof(name), "libcamera_device.%s", impl->props.device); + snprintf(name, sizeof(name), "libcamera_device.%s", impl->device_id.c_str()); ADD_ITEM(SPA_KEY_DEVICE_NAME, name); #undef ADD_ITEM @@ -235,13 +234,30 @@ static int impl_clear(struct spa_handle *handle) { - struct impl *impl = (struct impl *) handle; - if (impl->manager) - libcamera_manager_release(impl->manager); - impl->manager = NULL; + std::destroy_at(reinterpret_cast<impl *>(handle)); return 0; } +impl::impl(spa_log *log, + std::shared_ptr<CameraManager> manager, + std::shared_ptr<Camera> camera, + std::string device_id) + : handle({ SPA_VERSION_HANDLE, impl_get_interface, impl_clear }), + log(log), + device_id(std::move(device_id)), + manager(std::move(manager)), + camera(std::move(camera)) +{ + libcamera_log_topic_init(log); + + spa_hook_list_init(&hooks); + + device.iface = SPA_INTERFACE_INIT( + SPA_TYPE_INTERFACE_Device, + SPA_VERSION_DEVICE, + &impl_device, this); +} + static size_t impl_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params) @@ -256,44 +272,32 @@ const struct spa_support *support, uint32_t n_support) { - struct impl *impl; const char *str; int res; spa_return_val_if_fail(factory != NULL, -EINVAL); spa_return_val_if_fail(handle != NULL, -EINVAL); - handle->get_interface = impl_get_interface; - handle->clear = impl_clear, impl = (struct impl *) handle; - - impl->log = (struct spa_log*) spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); - libcamera_log_topic_init(impl->log); - - spa_hook_list_init(&impl->hooks); - - impl->device.iface = SPA_INTERFACE_INIT( - SPA_TYPE_INTERFACE_Device, - SPA_VERSION_DEVICE, - &impl_device, impl); + auto log = static_cast<spa_log *>(spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log)); - reset_props(&impl->props); + auto manager = libcamera_manager_acquire(res); + if (!manager) { + spa_log_error(log, "can't start camera manager: %s", spa_strerror(res)); + return res; + } + std::string device_id; if (info && (str = spa_dict_lookup(info, SPA_KEY_API_LIBCAMERA_PATH))) - strncpy(impl->props.device, str, sizeof(impl->props.device)); - - impl->manager = libcamera_manager_acquire(); - if (impl->manager == NULL) { - res = -errno; - spa_log_error(impl->log, "can't start camera manager: %s", spa_strerror(res)); - return res; - } + device_id = str; - impl->camera = impl->manager->get(impl->props.device); - if (impl->camera == NULL) { - spa_log_error(impl->log, "unknown camera id %s", impl->props.device); - libcamera_manager_release(impl->manager); + auto camera = manager->get(device_id); + if (!camera) { + spa_log_error(log, "unknown camera id %s", device_id.c_str()); return -ENOENT; } + + new (handle) impl(log, std::move(manager), std::move(camera), std::move(device_id)); + return 0; }
View file
pipewire-0.3.58.tar.gz/spa/plugins/libcamera/libcamera-manager.cpp -> pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-manager.cpp
Changed
@@ -29,7 +29,10 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> - +#include <utility> +#include <mutex> +#include <optional> +#include <queue> #include <libcamera/camera.h> #include <libcamera/camera_manager.h> @@ -54,67 +57,65 @@ #define MAX_DEVICES 64 -struct global { - int ref; - CameraManager *manager; -}; - -static struct global global; +namespace { struct device { uint32_t id; std::shared_ptr<Camera> camera; }; -typedef struct impl { +struct impl { struct spa_handle handle; - struct spa_device device; + struct spa_device device = {}; struct spa_log *log; - struct spa_loop *main_loop; + struct spa_loop_utils *loop_utils; struct spa_hook_list hooks; - uint64_t info_all; - struct spa_device_info info; + static constexpr uint64_t info_all = SPA_DEVICE_CHANGE_MASK_FLAGS | SPA_DEVICE_CHANGE_MASK_PROPS; + struct spa_device_info info = SPA_DEVICE_INFO_INIT(); - CameraManager *manager; + std::shared_ptr<CameraManager> manager; void addCamera(std::shared_ptr<libcamera::Camera> camera); - void removeCamera(std::shared_ptr<libcamera::Camera> camera); + void removeCamera(std::shared_ptr<libcamera::Camera> camera); struct device devicesMAX_DEVICES; - uint32_t n_devices; -} Impl; + uint32_t n_devices = 0; -int libcamera_manager_release(CameraManager *manager) -{ - if (global.manager != manager) - return -EINVAL; + struct hotplug_event { + enum class type { add, remove } type; + std::shared_ptr<Camera> camera; + }; - if (--global.ref == 0) { - global.manager->stop(); - delete global.manager; - global.manager = NULL; + std::mutex hotplug_events_lock; + std::queue<hotplug_event> hotplug_events; + struct spa_source *hotplug_event_source; + + impl(spa_log *log, spa_loop_utils *loop_utils, spa_source *hotplug_event_source); + + ~impl() + { + spa_loop_utils_destroy_source(loop_utils, hotplug_event_source); } - return 0; +}; + } -CameraManager *libcamera_manager_acquire(void) +static std::weak_ptr<CameraManager> global_manager; + +std::shared_ptr<CameraManager> libcamera_manager_acquire(int& res) { - int res; + if (auto manager = global_manager.lock()) + return manager; - if (global.ref++ == 0) { - global.manager = new CameraManager(); - if (global.manager == NULL) - return NULL; + auto manager = std::make_shared<CameraManager>(); + if ((res = manager->start()) < 0) + return {}; - if ((res = global.manager->start()) < 0) { - libcamera_manager_release(global.manager); - errno = -res; - return NULL; - } - } - return global.manager; + global_manager = manager; + + return manager; } static struct device *add_device(struct impl *impl, std::shared_ptr<Camera> camera) @@ -127,15 +128,15 @@ id = impl->n_devices++; device = &impl->devicesid; device->id = id; - device->camera = camera; + device->camera = std::move(camera); return device; } -static struct device *find_device(struct impl *impl, std::shared_ptr<Camera> camera) +static struct device *find_device(struct impl *impl, const Camera *camera) { uint32_t i; for (i = 0; i < impl->n_devices; i++) { - if (impl->devicesi.camera == camera) + if (impl->devicesi.camera.get() == camera) return &impl->devicesi; } return NULL; @@ -143,12 +144,14 @@ static void remove_device(struct impl *impl, struct device *device) { - *device = impl->devices--impl->n_devices; + device->camera.reset(); + *device = std::move(impl->devices--impl->n_devices); } static void clear_devices(struct impl *impl) { - impl->n_devices = 0; + while (impl->n_devices > 0) + impl->devices--impl->n_devices.camera.reset(); } static int emit_object_info(struct impl *impl, struct device *device) @@ -176,66 +179,119 @@ ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, path); #undef ADD_ITEM - dict = SPA_DICT_INIT(items, n_items); - info.props = &dict; - spa_device_emit_object_info(&impl->hooks, id, &info); + dict = SPA_DICT_INIT(items, n_items); + info.props = &dict; + spa_device_emit_object_info(&impl->hooks, id, &info); return 1; } -void Impl::addCamera(std::shared_ptr<Camera> camera) +static void try_add_camera(struct impl *impl, std::shared_ptr<Camera> camera) { - struct impl *impl = this; struct device *device; - spa_log_info(impl->log, "new camera"); - - if ((device = find_device(impl, camera)) != NULL) + if ((device = find_device(impl, camera.get())) != NULL) return; - if ((device = add_device(impl, camera)) == NULL) + if ((device = add_device(impl, std::move(camera))) == NULL) return; + spa_log_info(impl->log, "camera added: %s", device->camera->id().c_str()); emit_object_info(impl, device); } -void Impl::removeCamera(std::shared_ptr<Camera> camera) +static void try_remove_camera(struct impl *impl, const Camera *camera) { - struct impl *impl = this; struct device *device; - spa_log_info(impl->log, "camera removed"); if ((device = find_device(impl, camera)) == NULL) return; + spa_log_info(impl->log, "camera removed: %s", device->camera->id().c_str()); remove_device(impl, device); } -static int start_monitor(struct impl *impl)
View file
pipewire-0.3.58.tar.gz/spa/plugins/libcamera/libcamera-manager.hpp -> pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-manager.hpp
Changed
@@ -22,11 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ -#include <libcamera/camera_manager.h> - -#include <linux/media.h> +#include <memory> -using namespace libcamera; +#include <libcamera/camera_manager.h> -CameraManager *libcamera_manager_acquire(void); -int libcamera_manager_release(CameraManager *manager); +std::shared_ptr<libcamera::CameraManager> libcamera_manager_acquire(int& res);
View file
pipewire-0.3.58.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -31,6 +31,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <deque> +#include <optional> #include <spa/support/plugin.h> #include <spa/support/log.h> @@ -60,15 +61,9 @@ #include "libcamera.h" #include "libcamera-manager.hpp" -struct props { - char device128; - char device_name128; -}; +using namespace libcamera; -static void reset_props(struct props *props) -{ - spa_zero(*props); -} +namespace { #define MAX_BUFFERS 32 #define MASK_BUFFERS 31 @@ -97,75 +92,97 @@ struct port { struct impl *impl; - bool have_format; - struct spa_video_info current_format; - struct spa_fraction rate; + std::optional<spa_video_info> current_format; + + struct spa_fraction rate = {}; StreamConfiguration streamConfig; - uint32_t memtype; + uint32_t memtype = 0; struct control controlsMAX_CONTROLS; - uint32_t n_controls; + uint32_t n_controls = 0; struct buffer buffersMAX_BUFFERS; - uint32_t n_buffers; + uint32_t n_buffers = 0; struct spa_list queue; - struct spa_ringbuffer ring; + struct spa_ringbuffer ring = SPA_RINGBUFFER_INIT(); uint32_t ring_idsMAX_BUFFERS; - uint64_t info_all; - struct spa_port_info info; - struct spa_io_buffers *io; - struct spa_io_sequence *control; + static constexpr uint64_t info_all = SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_PARAMS; + struct spa_port_info info = SPA_PORT_INFO_INIT(); + struct spa_io_buffers *io = nullptr; + struct spa_io_sequence *control = nullptr; struct spa_param_info params8; - uint32_t fmt_index; - bool next_fmt; + uint32_t fmt_index = 0; PixelFormat enum_fmt; - uint32_t size_index; - bool next_size; + uint32_t size_index = 0; + + port(struct impl *impl) + : impl(impl) + { + spa_list_init(&queue); + + params0 = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ); + params1 = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); + params2 = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); + params3 = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ); + params4 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); + params5 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); + + info.flags = SPA_PORT_FLAG_LIVE | SPA_PORT_FLAG_PHYSICAL | SPA_PORT_FLAG_TERMINAL; + info.params = params; + info.n_params = 6; + } }; struct impl { struct spa_handle handle; - struct spa_node node; + struct spa_node node = {}; struct spa_log *log; struct spa_loop *data_loop; struct spa_system *system; - uint64_t info_all; - struct spa_node_info info; + static constexpr uint64_t info_all = + SPA_NODE_CHANGE_MASK_FLAGS | + SPA_NODE_CHANGE_MASK_PROPS | + SPA_NODE_CHANGE_MASK_PARAMS; + struct spa_node_info info = SPA_NODE_INFO_INIT(); struct spa_param_info params8; - struct props props; + + std::string device_id; + std::string device_name; struct spa_hook_list hooks; - struct spa_callbacks callbacks; + struct spa_callbacks callbacks = {}; - struct port out_ports1; + std::array<port, 1> out_ports; - struct spa_io_position *position; - struct spa_io_clock *clock; + struct spa_io_position *position = nullptr; + struct spa_io_clock *clock = nullptr; - CameraManager *manager; + std::shared_ptr<CameraManager> manager; std::shared_ptr<Camera> camera; - FrameBufferAllocator *allocator; + FrameBufferAllocator *allocator = nullptr; std::vector<std::unique_ptr<libcamera::Request>> requestPool; std::deque<libcamera::Request *> pendingRequests; void requestComplete(libcamera::Request *request); - unsigned int have_config; std::unique_ptr<CameraConfiguration> config; - struct spa_source source; + struct spa_source source = {}; - unsigned int active:1; - unsigned int acquired:1; + bool active = false; + bool acquired = false; + + impl(spa_log *log, spa_loop *data_loop, spa_system *system, + std::shared_ptr<CameraManager> manager, std::shared_ptr<Camera> camera, std::string device_id); }; -typedef struct impl Impl; +} #define CHECK_PORT(impl,direction,port_id) ((direction) == SPA_DIRECTION_OUTPUT && (port_id) == 0) @@ -198,22 +215,20 @@ switch (id) { case SPA_PARAM_PropInfo: { - struct props *p = &impl->props; - switch (result.index) { case 0: param = (struct spa_pod*)spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device), SPA_PROP_INFO_description, SPA_POD_String("The libcamera device"), - SPA_PROP_INFO_type, SPA_POD_String(p->device)); + SPA_PROP_INFO_type, SPA_POD_String(impl->device_id.c_str())); break; case 1: param = (struct spa_pod*)spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName), SPA_PROP_INFO_description, SPA_POD_String("The libcamera device name"), - SPA_PROP_INFO_type, SPA_POD_String(p->device_name)); + SPA_PROP_INFO_type, SPA_POD_String(impl->device_name.c_str())); break; default: return 0; @@ -222,14 +237,12 @@ } case SPA_PARAM_Props: { - struct props *p = &impl->props; - switch (result.index) { case 0: param = (struct spa_pod*)spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, - SPA_PROP_device, SPA_POD_String(p->device), - SPA_PROP_deviceName, SPA_POD_String(p->device_name)); + SPA_PROP_device, SPA_POD_String(impl->device_id.c_str()), + SPA_PROP_deviceName, SPA_POD_String(impl->device_name.c_str())); break; default: return 0; @@ -262,15 +275,22 @@ switch (id) { case SPA_PARAM_Props: {
View file
pipewire-0.3.58.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
@@ -40,7 +40,7 @@ if (impl->acquired) return 0; - spa_log_info(impl->log, "open camera %s", impl->props.device); + spa_log_info(impl->log, "open camera %s", impl->device_id.c_str()); impl->camera->acquire(); impl->allocator = new FrameBufferAllocator(impl->camera); @@ -54,10 +54,10 @@ struct port *port = &impl->out_ports0; if (!impl->acquired) return 0; - if (impl->active || port->have_format) + if (impl->active || port->current_format) return 0; - spa_log_info(impl->log, "close camera %s", impl->props.device); + spa_log_info(impl->log, "close camera %s", impl->device_id.c_str()); delete impl->allocator; impl->allocator = nullptr; @@ -69,13 +69,12 @@ static void spa_libcamera_get_config(struct impl *impl) { - if (impl->have_config) + if (impl->config) return; StreamRoles roles; roles.push_back(VideoRecording); impl->config = impl->camera->generateConfiguration(roles); - impl->have_config = true; } static int spa_libcamera_buffer_recycle(struct impl *impl, struct port *port, uint32_t buffer_id) @@ -91,10 +90,10 @@ if (buffer_id >= impl->requestPool.size()) { spa_log_warn(impl->log, "invalid buffer_id %u >= %zu", buffer_id, impl->requestPool.size()); - return -EINVAL; - } + return -EINVAL; + } Request *request = impl->requestPoolbuffer_id.get(); - Stream *stream = port->streamConfig.stream(); + Stream *stream = port->streamConfig.stream(); FrameBuffer *buffer = impl->allocator->buffers(stream)buffer_id.get(); if ((res = request->addBuffer(stream, buffer)) < 0) { spa_log_warn(impl->log, "can't add buffer %u for request: %s", @@ -104,7 +103,7 @@ if (!impl->active) { impl->pendingRequests.push_back(request); return 0; - } else { + } else { if ((res = impl->camera->queueRequest(request)) < 0) { spa_log_warn(impl->log, "can't queue buffer %u: %s", buffer_id, spa_strerror(res)); @@ -119,7 +118,7 @@ int res; if ((res = impl->allocator->allocate(port->streamConfig.stream())) < 0) - return res; + return res; for (unsigned int i = 0; i < count; i++) { std::unique_ptr<Request> request = impl->camera->createRequest(i); @@ -129,7 +128,7 @@ } impl->requestPool.push_back(std::move(request)); } - return res; + return res; } static void freeBuffers(struct impl *impl, struct port *port) @@ -419,8 +418,6 @@ if ((res = allocBuffers(impl, port, port->streamConfig.bufferCount)) < 0) goto error; - port->have_format = true; - port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_RATE; port->info.flags = SPA_PORT_FLAG_CAN_ALLOC_BUFFERS | SPA_PORT_FLAG_LIVE | @@ -607,7 +604,7 @@ } -void Impl::requestComplete(libcamera::Request *request) +void impl::requestComplete(libcamera::Request *request) { struct impl *impl = this; struct port *port = &impl->out_ports0; @@ -618,12 +615,12 @@ spa_log_debug(impl->log, "request complete"); if ((request->status() == Request::RequestCancelled)) { - spa_log_debug(impl->log, "Request was cancelled"); - return; - } + spa_log_debug(impl->log, "Request was cancelled"); + return; + } FrameBuffer *buffer = request->findBuffer(stream); if (buffer == nullptr) { - spa_log_warn(impl->log, "unknown buffer"); + spa_log_warn(impl->log, "unknown buffer"); return; } const FrameMetadata &fmd = buffer->metadata(); @@ -664,7 +661,7 @@ struct port *port = &impl->out_ports0; int res; - if (!port->have_format) { + if (!port->current_format) { spa_log_error(impl->log, "Exting %s with -EIO", __FUNCTION__); return -EIO; } @@ -674,15 +671,15 @@ impl->camera->requestCompleted.connect(impl, &impl::requestComplete); - spa_log_info(impl->log, "starting camera %s", impl->props.device); + spa_log_info(impl->log, "starting camera %s", impl->device_id.c_str()); if ((res = impl->camera->start()) < 0) return res == -EACCES ? -EBUSY : res; for (Request *req : impl->pendingRequests) { - if ((res = impl->camera->queueRequest(req)) < 0) + if ((res = impl->camera->queueRequest(req)) < 0) return res == -EACCES ? -EBUSY : res; - } - impl->pendingRequests.clear(); + } + impl->pendingRequests.clear(); impl->source.func = libcamera_on_fd_events; impl->source.data = impl; @@ -724,7 +721,7 @@ return 0; } - spa_log_info(impl->log, "stopping camera %s", impl->props.device); + spa_log_info(impl->log, "stopping camera %s", impl->device_id.c_str()); impl->pendingRequests.clear(); if ((res = impl->camera->stop()) < 0)
View file
pipewire-0.3.58.tar.gz/spa/plugins/support/logger.c -> pipewire-0.3.59.tar.gz/spa/plugins/support/logger.c
Changed
@@ -357,7 +357,7 @@ if ((str = spa_dict_lookup(info, SPA_KEY_LOG_LEVEL)) != NULL) this->log.level = atoi(str); if ((str = spa_dict_lookup(info, SPA_KEY_LOG_FILE)) != NULL) { - this->file = fopen(str, "w"); + this->file = fopen(str, "we"); if (this->file == NULL) fprintf(stderr, "Warning: failed to open file %s: (%m)", str); else
View file
pipewire-0.3.58.tar.gz/spa/plugins/videoconvert/videoadapter.c -> pipewire-0.3.59.tar.gz/spa/plugins/videoconvert/videoadapter.c
Changed
@@ -823,12 +823,12 @@ case SPA_NODE_COMMAND_Suspend: configure_format(this, 0, NULL); SPA_FALLTHROUGH - case SPA_NODE_COMMAND_Flush: - this->io_buffers.status = SPA_STATUS_OK; - SPA_FALLTHROUGH case SPA_NODE_COMMAND_Pause: this->started = false; break; + case SPA_NODE_COMMAND_Flush: + this->io_buffers.status = SPA_STATUS_OK; + break; default: break; }
View file
pipewire-0.3.59.tar.gz/src/examples/audio-capture.c
Added
@@ -0,0 +1,206 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + title + Audio capture using \ref pw_stream "pw_stream". + title + */ + +#include <stdio.h> +#include <errno.h> +#include <math.h> +#include <signal.h> + +#include <spa/param/audio/format-utils.h> + +#include <pipewire/pipewire.h> + +struct data { + struct pw_main_loop *loop; + struct pw_stream *stream; + + struct spa_audio_info format; +}; + +/* our data processing function is in general: + * + * struct pw_buffer *b; + * b = pw_stream_dequeue_buffer(stream); + * + * .. consume stuff in the buffer ... + * + * pw_stream_queue_buffer(stream, b); + */ +static void on_process(void *userdata) +{ + struct data *data = userdata; + struct pw_buffer *b; + struct spa_buffer *buf; + float *samples, max; + uint32_t c, n, n_channels, n_samples, peak; + + if ((b = pw_stream_dequeue_buffer(data->stream)) == NULL) { + pw_log_warn("out of buffers: %m"); + return; + } + + buf = b->buffer; + if ((samples = buf->datas0.data) == NULL) + return; + + n_channels = data->format.info.raw.channels; + n_samples = buf->datas0.chunk->size / sizeof(float); + + fprintf(stdout, "captured %d samples\n", n_samples / n_channels); + for (c = 0; c < data->format.info.raw.channels; c++) { + max = 0.0f; + for (n = c; n < n_samples; n += n_channels) + max = fmaxf(max, fabsf(samplesn)); + + peak = SPA_CLAMP(max * 30, 0, 39); + + fprintf(stdout, "channel %d: |%*s%*s| peak:%f\n", + c, peak+1, "*", 40 - peak, "", max); + } + /* move cursor up */ + fprintf(stdout, "%c%dA", 0x1b, n_channels + 1); + fflush(stdout); + + pw_stream_queue_buffer(data->stream, b); +} + +/* Be notified when the stream param changes. We're only looking at the + * format changes. + */ +static void +on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param) +{ + struct data *data = _data; + + /* NULL means to clear the format */ + if (param == NULL || id != SPA_PARAM_Format) + return; + + if (spa_format_parse(param, &data->format.media_type, &data->format.media_subtype) < 0) + return; + + /* only accept raw audio */ + if (data->format.media_type != SPA_MEDIA_TYPE_audio || + data->format.media_subtype != SPA_MEDIA_SUBTYPE_raw) + return; + + /* call a helper function to parse the format for us. */ + spa_format_audio_raw_parse(param, &data->format.info.raw); + + fprintf(stdout, "capturing rate:%d channels:%d\n", + data->format.info.raw.rate, data->format.info.raw.channels); + +} + +static const struct pw_stream_events stream_events = { + PW_VERSION_STREAM_EVENTS, + .param_changed = on_stream_param_changed, + .process = on_process, +}; + +static void do_quit(void *userdata, int signal_number) +{ + struct data *data = userdata; + pw_main_loop_quit(data->loop); +} + +int main(int argc, char *argv) +{ + struct data data = { 0, }; + const struct spa_pod *params1; + uint8_t buffer1024; + struct pw_properties *props; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + + pw_init(&argc, &argv); + + /* make a main loop. If you already have another main loop, you can add + * the fd of this pipewire mainloop to it. */ + data.loop = pw_main_loop_new(NULL); + + pw_loop_add_signal(pw_main_loop_get_loop(data.loop), SIGINT, do_quit, &data); + pw_loop_add_signal(pw_main_loop_get_loop(data.loop), SIGTERM, do_quit, &data); + + /* Create a simple stream, the simple stream manages the core and remote + * objects for you if you don't need to deal with them. + * + * If you plan to autoconnect your stream, you need to provide at least + * media, category and role properties. + * + * Pass your events and a user_data pointer as the last arguments. This + * will inform you about the stream state. The most important event + * you need to listen to is the process event where you need to produce + * the data. + */ + props = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio", + PW_KEY_MEDIA_CATEGORY, "Capture", + PW_KEY_MEDIA_ROLE, "Music", + NULL); + if (argc > 1) + /* Set stream target if given on command line */ + pw_properties_set(props, PW_KEY_TARGET_OBJECT, argv1); + + /* uncomment if you want to capture from the sink monitor ports */ + /* pw_properties_set(props, PW_KEY_STREAM_CAPTURE_SINK, "true"); */ + + data.stream = pw_stream_new_simple( + pw_main_loop_get_loop(data.loop), + "audio-capture", + props, + &stream_events, + &data); + + /* Make one parameter with the supported formats. The SPA_PARAM_EnumFormat + * id means that this is a format enumeration (of 1 value). + * We leave the channels and rate empty to accept the native graph + * rate and channels. */ + params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, + &SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32)); + + /* Now connect this stream. We ask that our process function is + * called in a realtime thread. */ + pw_stream_connect(data.stream, + PW_DIRECTION_INPUT, + PW_ID_ANY, + PW_STREAM_FLAG_AUTOCONNECT | + PW_STREAM_FLAG_MAP_BUFFERS | + PW_STREAM_FLAG_RT_PROCESS, + params, 1); + + /* and wait while we let things run */ + pw_main_loop_run(data.loop);
View file
pipewire-0.3.58.tar.gz/src/examples/meson.build -> pipewire-0.3.59.tar.gz/src/examples/meson.build
Changed
@@ -3,6 +3,7 @@ 'audio-src', 'audio-dsp-src', 'audio-dsp-filter', + 'audio-capture', 'video-play', 'video-src', 'video-dsp-play',
View file
pipewire-0.3.58.tar.gz/src/modules/module-avb/stream.c -> pipewire-0.3.59.tar.gz/src/modules/module-avb/stream.c
Changed
@@ -136,7 +136,7 @@ p->timestamp = ptime; p->dbc = dbc; - n = sendmsg(stream->source->fd, &stream->msg, 0); + n = sendmsg(stream->source->fd, &stream->msg, MSG_NOSIGNAL); if (n < 0 || n != (ssize_t)stream->pdu_size) { pw_log_error("sendmsg() failed %zd != %zd: %m", n, stream->pdu_size);
View file
pipewire-0.3.58.tar.gz/src/modules/module-client-node/v0/ext-client-node.h -> pipewire-0.3.59.tar.gz/src/modules/module-client-node/v0/ext-client-node.h
Changed
@@ -140,9 +140,9 @@ #define PW_CLIENT_NODE0_MESSAGE_TYPE(message) (((struct pw_client_node0_message*)(message))->body.type.value) -#define PW_CLIENT_NODE0_MESSAGE_INIT(message) (struct pw_client_node0_message) \ +#define PW_CLIENT_NODE0_MESSAGE_INIT(message) ((struct pw_client_node0_message) \ { { { sizeof(struct pw_client_node0_message_body), SPA_TYPE_Struct } }, \ - { SPA_POD_INIT_Int(message) } } + { SPA_POD_INIT_Int(message) } }) #define PW_CLIENT_NODE0_MESSAGE_INIT_FULL(type,size,message,...) (type) \ { { { size, SPA_TYPE_Struct } }, \
View file
pipewire-0.3.58.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.59.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -519,13 +519,13 @@ struct graph_port { const struct fc_descriptor *desc; - void *hndl; + void **hndl; uint32_t port; }; struct graph_hndl { const struct fc_descriptor *desc; - void *hndl; + void **hndl; }; struct graph { @@ -577,6 +577,10 @@ struct graph graph; }; +static int graph_instantiate(struct graph *graph); +static void graph_cleanup(struct graph *graph); + + static void capture_destroy(void *d) { struct impl *impl = d; @@ -587,18 +591,24 @@ static void capture_process(void *d) { struct impl *impl = d; + pw_stream_trigger_process(impl->playback); +} + +static void playback_process(void *d) +{ + struct impl *impl = d; struct pw_buffer *in, *out; struct graph *graph = &impl->graph; - uint32_t i, outsize = 0, n_hndl = graph->n_hndl; + uint32_t i, insize = 0, outsize = 0, n_hndl = graph->n_hndl; int32_t stride = 0; struct graph_port *port; struct spa_data *bd; if ((in = pw_stream_dequeue_buffer(impl->capture)) == NULL) - pw_log_debug("out of capture buffers: %m"); + pw_log_debug("%p: out of capture buffers: %m", impl); if ((out = pw_stream_dequeue_buffer(impl->playback)) == NULL) - pw_log_debug("out of playback buffers: %m"); + pw_log_debug("%p: out of playback buffers: %m", impl); if (in == NULL || out == NULL) goto done; @@ -614,12 +624,14 @@ port = i < graph->n_input ? &graph->inputi : NULL; if (port && port->desc) - port->desc->connect_port(port->hndl, port->port, + port->desc->connect_port(*port->hndl, port->port, SPA_PTROFF(bd->data, offs, void)); - outsize = i == 0 ? size : SPA_MIN(outsize, size); + insize = i == 0 ? size : SPA_MIN(insize, size); stride = SPA_MAX(stride, bd->chunk->stride); } + outsize = insize; + for (i = 0; i < out->buffer->n_datas; i++) { bd = &out->buffer->datasi; @@ -628,7 +640,7 @@ port = i < graph->n_output ? &graph->outputi : NULL; if (port && port->desc) - port->desc->connect_port(port->hndl, port->port, bd->data); + port->desc->connect_port(*port->hndl, port->port, bd->data); else memset(bd->data, 0, outsize); @@ -636,9 +648,13 @@ bd->chunk->size = outsize; bd->chunk->stride = stride; } + + pw_log_trace_fp("%p: stride:%d in:%d out:%d requested:%"PRIu64" (%"PRIu64")", impl, + stride, insize, outsize, out->requested, out->requested * stride); + for (i = 0; i < n_hndl; i++) { struct graph_hndl *hndl = &graph->hndli; - hndl->desc->run(hndl->hndl, outsize / sizeof(float)); + hndl->desc->run(*hndl->hndl, outsize / sizeof(float)); } done: @@ -646,8 +662,6 @@ pw_stream_queue_buffer(impl->capture, in); if (out != NULL) pw_stream_queue_buffer(impl->playback, out); - - pw_stream_trigger_process(impl->playback); } static float get_default(struct impl *impl, struct descriptor *desc, uint32_t p) @@ -746,11 +760,12 @@ struct fc_port *p = &d->portsport->p; float def, min, max; char name512; + uint32_t rate = impl->rate ? impl->rate : 48000; if (p->hint & FC_HINT_SAMPLE_RATE) { - def = p->def * impl->rate; - min = p->min * impl->rate; - max = p->max * impl->rate; + def = p->def * rate; + min = p->min * rate; + max = p->max * rate; } else { def = p->def; min = p->min; @@ -908,13 +923,14 @@ for (i = 0; i < graph->n_hndl; i++) { struct graph_hndl *hndl = &graph->hndli; const struct fc_descriptor *d = hndl->desc; + if (hndl->hndl == NULL || *hndl->hndl == NULL) + continue; if (d->deactivate) - d->deactivate(hndl->hndl); + d->deactivate(*hndl->hndl); if (d->activate) - d->activate(hndl->hndl); + d->activate(*hndl->hndl); } } - static void param_props_changed(struct impl *impl, const struct spa_pod *param) { struct spa_pod_object *obj = (struct spa_pod_object *) param; @@ -989,8 +1005,15 @@ switch (id) { case SPA_PARAM_Format: - if (param == NULL) - graph_reset(graph); + if (param == NULL) { + graph_cleanup(graph); + } else { + struct spa_audio_info_raw info; + spa_zero(info); + spa_format_audio_raw_parse(param, &info); + impl->rate = info.rate; + graph_instantiate(graph); + } break; case SPA_PARAM_Props: if (param != NULL) @@ -1020,6 +1043,7 @@ static const struct pw_stream_events out_stream_events = { PW_VERSION_STREAM_EVENTS, .destroy = playback_destroy, + .process = playback_process, .state_changed = state_changed, .param_changed = param_changed }; @@ -1477,6 +1501,7 @@ bool have_config = false; uint32_t i; int res; + float *data; while (spa_json_get_string(json, key, sizeof(key)) > 0) { if (spa_streq("type", key)) { @@ -1551,6 +1576,14 @@ port->idx = i; port->external = SPA_ID_INVALID; port->p = desc->outputi; + if ((data = port->audio_datai) == NULL) { + data = calloc(1, MAX_SAMPLES * sizeof(float)); + if (data == NULL) { + pw_log_error("cannot create port data: %m"); + return -errno; + } + } + port->audio_datai = data; spa_list_init(&port->link_list); } for (i = 0; i < desc->n_control; i++) { @@ -1581,21 +1614,31 @@ return 0; } -static void node_free(struct node *node) +static void node_cleanup(struct node *node) { - uint32_t i, j; const struct fc_descriptor *d = node->desc->desc; + uint32_t i; - spa_list_remove(&node->link);
View file
pipewire-0.3.58.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
@@ -52,7 +52,7 @@ }; static void *builtin_instantiate(const struct fc_descriptor * Descriptor, - unsigned long *SampleRate, int index, const char *config) + unsigned long SampleRate, int index, const char *config) { struct builtin *impl; @@ -60,7 +60,7 @@ if (impl == NULL) return NULL; - impl->rate = *SampleRate; + impl->rate = SampleRate; return impl; } @@ -576,7 +576,7 @@ } static void * convolver_instantiate(const struct fc_descriptor * Descriptor, - unsigned long *SampleRate, int index, const char *config) + unsigned long SampleRate, int index, const char *config) { struct convolver_impl *impl; float *samples; @@ -588,6 +588,7 @@ int blocksize = 0, tailsize = 0; int delay = 0; float gain = 1.0f; + unsigned long rate; if (config == NULL) return NULL; @@ -647,8 +648,13 @@ samples = create_dirac(filename, gain, delay, offset, length, &n_samples); } else { + rate = SampleRate; samples = read_samples(filename, gain, delay, offset, - length, channel, SampleRate, &n_samples); + length, channel, &rate, &n_samples); + if (rate != SampleRate) { + pw_log_warn("Convolver samplerate %lu doesn't match filter rate %lu. " + "Consider forcing a filter rate.", rate, SampleRate); + } } if (samples == NULL) return NULL; @@ -664,7 +670,7 @@ if (impl == NULL) goto error; - impl->rate = *SampleRate; + impl->rate = SampleRate; impl->conv = convolver_new(blocksize, tailsize, samples, n_samples); if (impl->conv == NULL) @@ -750,7 +756,7 @@ } static void *delay_instantiate(const struct fc_descriptor * Descriptor, - unsigned long *SampleRate, int index, const char *config) + unsigned long SampleRate, int index, const char *config) { struct delay_impl *impl; struct spa_json it2; @@ -782,7 +788,7 @@ if (impl == NULL) return NULL; - impl->rate = *SampleRate; + impl->rate = SampleRate; impl->buffer_samples = max_delay * impl->rate; pw_log_info("%lu %d", impl->rate, impl->buffer_samples);
View file
pipewire-0.3.58.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c -> pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c
Changed
@@ -47,10 +47,10 @@ }; static void *ladspa_instantiate(const struct fc_descriptor *desc, - unsigned long *SampleRate, int index, const char *config) + unsigned long SampleRate, int index, const char *config) { struct descriptor *d = (struct descriptor *)desc; - return d->d->instantiate(d->d, *SampleRate); + return d->d->instantiate(d->d, SampleRate); } static const LADSPA_Descriptor *find_desc(LADSPA_Descriptor_Function desc_func, const char *name)
View file
pipewire-0.3.58.tar.gz/src/modules/module-filter-chain/lv2_plugin.c -> pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/lv2_plugin.c
Changed
@@ -298,7 +298,7 @@ } static void *lv2_instantiate(const struct fc_descriptor *desc, - unsigned long *SampleRate, int index, const char *config) + unsigned long SampleRate, int index, const char *config) { struct descriptor *d = (struct descriptor*)desc; struct plugin *p = d->p; @@ -308,7 +308,7 @@ static const int32_t min_block_length = 1; static const int32_t max_block_length = 8192; static const int32_t seq_size = 32768; - float fsample_rate = *SampleRate; + float fsample_rate = SampleRate; i = calloc(1, sizeof(*i)); if (i == NULL) @@ -350,7 +350,7 @@ i->options_feature.data = i->options; i->featuresn_features++ = &i->options_feature; - i->instance = lilv_plugin_instantiate(p->p, *SampleRate, i->features); + i->instance = lilv_plugin_instantiate(p->p, SampleRate, i->features); if (i->instance == NULL) { free(i); return NULL;
View file
pipewire-0.3.58.tar.gz/src/modules/module-filter-chain/plugin.h -> pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/plugin.h
Changed
@@ -72,7 +72,7 @@ struct fc_port *ports; void *(*instantiate) (const struct fc_descriptor *desc, - unsigned long *SampleRate, int index, const char *config); + unsigned long SampleRate, int index, const char *config); void (*cleanup) (void *instance);
View file
pipewire-0.3.58.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.59.tar.gz/src/modules/module-loopback.c
Changed
@@ -179,6 +179,12 @@ static void capture_process(void *d) { struct impl *impl = d; + pw_stream_trigger_process(impl->playback); +} + +static void playback_process(void *d) +{ + struct impl *impl = d; struct pw_buffer *in, *out; uint32_t i; @@ -225,8 +231,6 @@ pw_stream_queue_buffer(impl->capture, in); if (out != NULL) pw_stream_queue_buffer(impl->playback, out); - - pw_stream_trigger_process(impl->playback); } static void param_latency_changed(struct impl *impl, const struct spa_pod *param, @@ -305,6 +309,7 @@ static const struct pw_stream_events out_stream_events = { PW_VERSION_STREAM_EVENTS, .destroy = playback_destroy, + .process = playback_process, .state_changed = stream_state_changed, .param_changed = playback_param_changed, }; @@ -399,12 +404,20 @@ static void impl_destroy(struct impl *impl) { + /* disconnect both streams before destroying any of them */ + if (impl->capture) + pw_stream_disconnect(impl->capture); + if (impl->playback) + pw_stream_disconnect(impl->playback); + if (impl->capture) pw_stream_destroy(impl->capture); if (impl->playback) pw_stream_destroy(impl->playback); + if (impl->core && impl->do_disconnect) pw_core_disconnect(impl->core); + pw_properties_free(impl->capture_props); pw_properties_free(impl->playback_props); free(impl); @@ -518,6 +531,8 @@ pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "loopback-%u-%u", pid, id); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); + if (pw_properties_get(props, "resample.prefill") == NULL) + pw_properties_set(props, "resample.prefill", "true"); if ((str = pw_properties_get(props, "capture.props")) != NULL) pw_properties_update_string(impl->capture_props, str, strlen(str)); @@ -533,6 +548,7 @@ copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_NAME); + copy_props(impl, props, "resample.prefill"); if ((str = pw_properties_get(props, PW_KEY_NODE_NAME)) == NULL) { pw_properties_setf(props, PW_KEY_NODE_NAME,
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-native/connection.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/connection.c
Changed
@@ -221,7 +221,10 @@ struct cmsghdr *cmsg = NULL; struct msghdr msg = { 0 }; struct iovec iov1; - char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int)); + union { + char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int)); + struct cmsghdr align; + } cmsgbuf; int n_fds = 0; size_t avail; @@ -231,7 +234,7 @@ iov0.iov_len = avail; msg.msg_iov = iov; msg.msg_iovlen = 1; - msg.msg_control = cmsgbuf; + msg.msg_control = &cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); msg.msg_flags = MSG_CMSG_CLOEXEC | MSG_DONTWAIT; @@ -755,7 +758,10 @@ struct msghdr msg = { 0 }; struct iovec iov1; struct cmsghdr *cmsg; - char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int)); + union { + char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int)); + struct cmsghdr align; + } cmsgbuf; int res = 0, *fds; uint32_t fds_len, to_close, n_fds, outfds, i; struct buffer *buf; @@ -786,7 +792,7 @@ msg.msg_iovlen = 1; if (outfds > 0) { - msg.msg_control = cmsgbuf; + msg.msg_control = &cmsgbuf; msg.msg_controllen = CMSG_SPACE(fds_len); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET;
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-native/defs.h -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/defs.h
Changed
@@ -31,13 +31,19 @@ void (*done_callback) (void *data, int res), void *data); -static inline void *get_first_pod_from_data(void *data, size_t maxsize, off_t offset) +static inline void *get_first_pod_from_data(void *data, uint32_t maxsize, uint64_t offset) { void *pod; - if (offset + sizeof(struct spa_pod) > maxsize) + if (maxsize <= offset) return NULL; + + /* spa_pod_parser_advance() rounds up, so round down here to compensate */ + maxsize = SPA_ROUND_DOWN_N(maxsize - offset, 8); + if (maxsize < sizeof(struct spa_pod)) + return NULL; + pod = SPA_PTROFF(data, offset, void); - if (offset + SPA_POD_SIZE(pod) > maxsize) + if (SPA_POD_BODY_SIZE(pod) > maxsize - sizeof(struct spa_pod)) return NULL; return pod; }
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-native/protocol-footer.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/protocol-footer.c
Changed
@@ -45,7 +45,7 @@ unsigned int started:1; }; -#define FOOTER_BUILDER_INIT(builder) (struct footer_builder) { builder } +#define FOOTER_BUILDER_INIT(builder) ((struct footer_builder) { (builder) }) static void start_footer_entry(struct footer_builder *fb, uint32_t opcode) {
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-native/protocol-native.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/protocol-native.c
Changed
@@ -219,13 +219,13 @@ spa_pod_parser_get(prs, \ SPA_POD_Int(&(n_params)), NULL) < 0) \ return -EINVAL; \ - params = NULL; \ - if (n_params > 0) { \ + (params) = NULL; \ + if ((n_params) > 0) { \ uint32_t i; \ - if (n_params > MAX_PARAM_INFO) \ + if ((n_params) > MAX_PARAM_INFO) \ return -ENOSPC; \ - params = alloca(n_params * sizeof(struct spa_param_info)); \ - for (i = 0; i < n_params; i++) { \ + (params) = alloca((n_params) * sizeof(struct spa_param_info)); \ + for (i = 0; i < (n_params); i++) { \ if (spa_pod_parser_get(prs, \ SPA_POD_Id(&(params)i.id), \ SPA_POD_Int(&(params)i.flags), NULL) < 0) \ @@ -240,18 +240,18 @@ do { \ if (spa_pod_parser_push_struct(prs, f) < 0 || \ spa_pod_parser_get(prs, \ - SPA_POD_Int(&n_permissions), NULL) < 0) \ + SPA_POD_Int(&(n_permissions)), NULL) < 0) \ return -EINVAL; \ - permissions = NULL; \ - if (n_permissions > 0) { \ + (permissions) = NULL; \ + if ((n_permissions) > 0) { \ uint32_t i; \ - if (n_permissions > MAX_PERMISSIONS) \ + if ((n_permissions) > MAX_PERMISSIONS) \ return -ENOSPC; \ - permissions = alloca(n_permissions * sizeof(struct pw_permission)); \ - for (i = 0; i < n_permissions; i++) { \ + (permissions) = alloca((n_permissions) * sizeof(struct pw_permission)); \ + for (i = 0; i < (n_permissions); i++) { \ if (spa_pod_parser_get(prs, \ - SPA_POD_Int(&permissionsi.id), \ - SPA_POD_Int(&permissionsi.permissions), NULL) < 0) \ + SPA_POD_Int(&(permissions)i.id), \ + SPA_POD_Int(&(permissions)i.permissions), NULL) < 0) \ return -EINVAL; \ } \ } \
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-native/v0/protocol-native.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/v0/protocol-native.c
Changed
@@ -415,7 +415,7 @@ (iter) <= SPA_PTROFF((body), (_size)-(body)->value.size, __typeof__(*iter)); \ (iter) = SPA_PTROFF((iter), (body)->value.size, __typeof__(*iter))) -#define SPA0_POD_PROP_N_VALUES(b,size) ((size - sizeof(struct spa_pod_prop_body0)) / (b)->value.size) +#define SPA0_POD_PROP_N_VALUES(b,size) (((size) - sizeof(struct spa_pod_prop_body0)) / (b)->value.size) static int remap_from_v2(uint32_t type, void *body, uint32_t size, struct pw_impl_client *client, struct spa_pod_builder *builder)
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/manager.c
Changed
@@ -35,13 +35,13 @@ #define MAX_PARAMS 32 -#define manager_emit_sync(m) spa_hook_list_call(&m->hooks, struct pw_manager_events, sync, 0) -#define manager_emit_added(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, added, 0, o) -#define manager_emit_updated(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, updated, 0, o) -#define manager_emit_removed(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, removed, 0, o) -#define manager_emit_metadata(m,o,s,k,t,v) spa_hook_list_call(&m->hooks, struct pw_manager_events, metadata,0,o,s,k,t,v) -#define manager_emit_disconnect(m) spa_hook_list_call(&m->hooks, struct pw_manager_events, disconnect, 0) -#define manager_emit_object_data_timeout(m,o,k) spa_hook_list_call(&m->hooks, struct pw_manager_events, object_data_timeout,0,o,k) +#define manager_emit_sync(m) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, sync, 0) +#define manager_emit_added(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, added, 0, o) +#define manager_emit_updated(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, updated, 0, o) +#define manager_emit_removed(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, removed, 0, o) +#define manager_emit_metadata(m,o,s,k,t,v) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, metadata,0,o,s,k,t,v) +#define manager_emit_disconnect(m) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, disconnect, 0) +#define manager_emit_object_data_timeout(m,o,k) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, object_data_timeout,0,o,k) struct object;
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -89,7 +89,7 @@ #define MAX_FORMATS 32 /* The max amount of data we send in one block when capturing. In PulseAudio this * size is derived from the mempool PA_MEMPOOL_SLOT_SIZE */ -#define MAX_FRAGSIZE (64*1024) +#define MAX_BLOCK (64*1024) #define TEMPORARY_MOVE_TIMEOUT (SPA_NSEC_PER_SEC) @@ -455,7 +455,7 @@ static uint64_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *attr, uint32_t rate, struct spa_fraction *lat) { - uint32_t frame_size, max_prebuf, minreq, latency, max_latency; + uint32_t frame_size, max_prebuf, minreq, latency, max_latency, maxlength; struct defs *defs = &s->impl->defs; if ((frame_size = s->frame_size) == 0) @@ -463,24 +463,26 @@ if (frame_size == 0) frame_size = 4; - pw_log_info("%s maxlength:%u tlength:%u minreq:%u prebuf:%u", + maxlength = SPA_ROUND_DOWN(MAXLENGTH, frame_size); + + pw_log_info("%s maxlength:%u tlength:%u minreq:%u prebuf:%u max:%u", s->client->name, attr->maxlength, attr->tlength, - attr->minreq, attr->prebuf); + attr->minreq, attr->prebuf, maxlength); minreq = frac_to_bytes_round_up(s->min_req, &s->ss); max_latency = defs->quantum_limit * frame_size; - if (attr->maxlength == (uint32_t) -1 || attr->maxlength > MAXLENGTH) - attr->maxlength = MAXLENGTH; - attr->maxlength = SPA_ROUND_UP(attr->maxlength, frame_size); + if (attr->maxlength == (uint32_t) -1 || attr->maxlength > maxlength) + attr->maxlength = maxlength; + else + attr->maxlength = SPA_ROUND_DOWN(attr->maxlength, frame_size); minreq = SPA_MIN(minreq, attr->maxlength); if (attr->tlength == (uint32_t) -1) attr->tlength = frac_to_bytes_round_up(s->default_tlength, &s->ss); - attr->tlength = SPA_MIN(attr->tlength, attr->maxlength); + attr->tlength = SPA_CLAMP(attr->tlength, minreq, attr->maxlength); attr->tlength = SPA_ROUND_UP(attr->tlength, frame_size); - attr->tlength = SPA_MAX(attr->tlength, minreq); if (attr->minreq == (uint32_t) -1) { uint32_t process = frac_to_bytes_round_up(s->default_req, &s->ss); @@ -655,39 +657,46 @@ static uint64_t fix_record_buffer_attr(struct stream *s, struct buffer_attr *attr, uint32_t rate, struct spa_fraction *lat) { - uint32_t frame_size, minfrag, latency; + uint32_t frame_size, minfrag, latency, maxlength; if ((frame_size = s->frame_size) == 0) frame_size = sample_spec_frame_size(&s->ss); if (frame_size == 0) frame_size = 4; + maxlength = SPA_ROUND_DOWN(MAXLENGTH, frame_size); + pw_log_info("%s maxlength:%u fragsize:%u framesize:%u", s->client->name, attr->maxlength, attr->fragsize, frame_size); - if (attr->maxlength == (uint32_t) -1 || attr->maxlength > MAXLENGTH) - attr->maxlength = MAXLENGTH; - attr->maxlength -= attr->maxlength % frame_size; + if (attr->maxlength == (uint32_t) -1 || attr->maxlength > maxlength) + attr->maxlength = maxlength; + else + attr->maxlength = SPA_ROUND_DOWN(attr->maxlength, frame_size); attr->maxlength = SPA_MAX(attr->maxlength, frame_size); minfrag = frac_to_bytes_round_up(s->min_frag, &s->ss); if (attr->fragsize == (uint32_t) -1 || attr->fragsize == 0) attr->fragsize = frac_to_bytes_round_up(s->default_frag, &s->ss); - attr->fragsize = SPA_MIN(attr->fragsize, attr->maxlength); + attr->fragsize = SPA_CLAMP(attr->fragsize, minfrag, attr->maxlength); attr->fragsize = SPA_ROUND_UP(attr->fragsize, frame_size); - attr->fragsize = SPA_MAX(attr->fragsize, minfrag); attr->tlength = attr->minreq = attr->prebuf = 0; - /* make sure can queue at least to fragsize without overruns */ - if (attr->maxlength < attr->fragsize * 4) + /* make sure we can queue at least to fragsize without overruns */ + if (attr->maxlength < attr->fragsize * 4) { attr->maxlength = attr->fragsize * 4; + if (attr->maxlength > maxlength) { + attr->maxlength = maxlength; + attr->fragsize = SPA_ROUND_DOWN(maxlength / 4, frame_size); + } + } - latency = attr->fragsize / frame_size; + latency = attr->fragsize; - lat->num = latency; + lat->num = latency / frame_size; lat->denom = rate; clamp_latency(s, lat); @@ -1341,7 +1350,8 @@ pw_log_trace("avail:%d index:%u", avail, index); while ((uint32_t)avail >= stream->attr.fragsize) { - towrite = SPA_MIN(avail, MAX_FRAGSIZE); + towrite = SPA_MIN(avail, MAX_BLOCK); + towrite = SPA_MIN(towrite, stream->attr.fragsize); towrite = SPA_ROUND_DOWN(towrite, stream->frame_size); msg = message_alloc(impl, stream->channel, towrite); @@ -1421,7 +1431,7 @@ spa_ringbuffer_read_data(&stream->ring, stream->buffer, MAXLENGTH, index % MAXLENGTH, - p, avail); + p, SPA_MIN((uint32_t)avail, size)); index += avail; } pd.playing_for = size;
View file
pipewire-0.3.58.tar.gz/src/modules/module-protocol-pulse/utils.c -> pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/utils.c
Changed
@@ -195,7 +195,7 @@ strcat(pid_file, "/pid"); - if ((f = fopen(pid_file, "w")) == NULL) { + if ((f = fopen(pid_file, "we")) == NULL) { res = -errno; pw_log_error("failed to open pid file: %m"); return res;
View file
pipewire-0.3.58.tar.gz/src/modules/module-raop-discover.c -> pipewire-0.3.59.tar.gz/src/modules/module-raop-discover.c
Changed
@@ -113,7 +113,7 @@ const char *domain; }; -#define TUNNEL_INFO(...) (struct tunnel_info){ __VA_ARGS__ } +#define TUNNEL_INFO(...) ((struct tunnel_info){ __VA_ARGS__ }) struct tunnel { struct spa_list link;
View file
pipewire-0.3.58.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.59.tar.gz/src/modules/module-raop-sink.c
Changed
@@ -421,6 +421,7 @@ switch (impl->codec) { case CODEC_PCM: + case CODEC_ALAC: len = write_codec_pcm(dst, impl->buffer, n_frames); break; default: @@ -463,6 +464,7 @@ switch (impl->codec) { case CODEC_PCM: + case CODEC_ALAC: len = write_codec_pcm(dst, impl->buffer, n_frames); break; default: @@ -1756,6 +1758,8 @@ str = "PCM"; if (spa_streq(str, "PCM")) impl->codec = CODEC_PCM; + else if (spa_streq(str, "ALAC")) + impl->codec = CODEC_ALAC; else { pw_log_error( "can't handle codec type %s", str); res = -EINVAL;
View file
pipewire-0.3.58.tar.gz/src/modules/module-raop/rtsp-client.c -> pipewire-0.3.59.tar.gz/src/modules/module-raop/rtsp-client.c
Changed
@@ -314,8 +314,8 @@ return -EPROTO; *value++ = '\0'; - while (*value == ' ') - value++; + + value = pw_strip(value, " "); pw_properties_set(client->headers, key, value); }
View file
pipewire-0.3.58.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.h -> pipewire-0.3.59.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.h
Changed
@@ -25,6 +25,7 @@ #ifndef MODULE_SESSION_MANAGER_ENDPOINT_LINK_H #define MODULE_SESSION_MANAGER_ENDPOINT_LINK_H +#include <stdint.h> #ifdef __cplusplus extern "C" {
View file
pipewire-0.3.58.tar.gz/src/modules/module-session-manager/client-session/session.h -> pipewire-0.3.59.tar.gz/src/modules/module-session-manager/client-session/session.h
Changed
@@ -25,6 +25,7 @@ #ifndef MODULE_SESSION_MANAGER_SESSION_H #define MODULE_SESSION_MANAGER_SESSION_H +#include <stdint.h> #ifdef __cplusplus extern "C" {
View file
pipewire-0.3.58.tar.gz/src/modules/module-zeroconf-discover.c -> pipewire-0.3.59.tar.gz/src/modules/module-zeroconf-discover.c
Changed
@@ -109,7 +109,7 @@ const char *domain; }; -#define TUNNEL_INFO(...) (struct tunnel_info){ __VA_ARGS__ } +#define TUNNEL_INFO(...) ((struct tunnel_info){ __VA_ARGS__ }) struct tunnel { struct spa_list link;
View file
pipewire-0.3.58.tar.gz/src/pipewire/array.h -> pipewire-0.3.59.tar.gz/src/pipewire/array.h
Changed
@@ -52,7 +52,7 @@ size_t extend; /**< number of bytes to extend with */ }; -#define PW_ARRAY_INIT(extend) (struct pw_array) { NULL, 0, 0, extend } +#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) @@ -67,17 +67,17 @@ #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_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); \ + 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); \ + for ((pos) = (__typeof__(pos)) pw_array_first(array); \ pw_array_check(array, pos); \ - pos = (__typeof__(pos)) pw_array_first(array)) + (pos) = (__typeof__(pos)) pw_array_first(array)) #define pw_array_remove(a,p) \ ({ \
View file
pipewire-0.3.58.tar.gz/src/pipewire/context.c -> pipewire-0.3.59.tar.gz/src/pipewire/context.c
Changed
@@ -1205,7 +1205,7 @@ if (settings->clock_rate_update_mode == CLOCK_RATE_UPDATE_MODE_HARD) suspend_driver(context, n); } else { - if (n->info.state >= PW_NODE_STATE_IDLE) + if (n->info.state >= PW_NODE_STATE_SUSPENDED) suspend_driver(context, n); } /* we're setting the pending rate. This will become the new @@ -1263,7 +1263,7 @@ n->current_pending = false; } - pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'", + pw_log_debug("%p: driver %p running:%d passive:%d quantum:%u '%s'", context, n, running, n->passive, quantum, n->name); /* first change the node states of the followers to the new target */
View file
pipewire-0.3.58.tar.gz/src/pipewire/filter.c -> pipewire-0.3.59.tar.gz/src/pipewire/filter.c
Changed
@@ -1179,7 +1179,7 @@ struct pw_filter *filter; int count; }; -#define MATCH_INIT(f) (struct match){ .filter = f } +#define MATCH_INIT(f) ((struct match){ .filter = (f) }) static int execute_match(void *data, const char *location, const char *action, const char *val, size_t len)
View file
pipewire-0.3.58.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.59.tar.gz/src/pipewire/impl-node.c
Changed
@@ -188,12 +188,12 @@ pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this); } -static int pause_node(struct pw_impl_node *this) +static int idle_node(struct pw_impl_node *this) { struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); int res = 0; - pw_log_debug("%p: pause node state:%s pending:%s pause-on-idle:%d", this, + pw_log_debug("%p: idle node state:%s pending:%s pause-on-idle:%d", this, pw_node_state_as_string(this->info.state), pw_node_state_as_string(impl->pending_state), impl->pause_on_idle); @@ -201,6 +201,9 @@ if (impl->pending_state <= PW_NODE_STATE_IDLE) return 0; + if (!impl->pause_on_idle) + return 0; + node_deactivate(this); res = spa_node_send_command(this->node, @@ -247,7 +250,8 @@ if (impl->pending_state >= PW_NODE_STATE_RUNNING) return 0; - pw_log_debug("%p: start node", this); + pw_log_debug("%p: start node driving:%d driver:%d added:%d", this, + this->driving, this->driver, this->added); if (!(this->driving && this->driver)) { impl->pending_play = true; @@ -357,6 +361,9 @@ switch (state) { case PW_NODE_STATE_RUNNING: + pw_log_debug("%p: start node driving:%d driver:%d added:%d", node, + node->driving, node->driver, node->added); + if (node->driving && node->driver) { res = spa_node_send_command(node->node, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start)); @@ -438,6 +445,9 @@ p->state = PW_IMPL_PORT_STATE_CONFIGURE; } + pw_log_debug("%p: suspend node driving:%d driver:%d added:%d", this, + this->driving, this->driver, this->added); + res = spa_node_send_command(this->node, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend)); if (res == -ENOTSUP) @@ -2185,8 +2195,7 @@ break; case PW_NODE_STATE_IDLE: - if (impl->pause_on_idle) - res = pause_node(node); + res = idle_node(node); break; case PW_NODE_STATE_RUNNING: @@ -2215,8 +2224,7 @@ state < PW_NODE_STATE_RUNNING && impl->pending_play) { impl->pending_play = false; - spa_node_send_command(node->node, - &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Pause)); + idle_node(node); } pw_work_queue_cancel(impl->work, node, impl->pending_id); node->info.state = impl->pending_state;
View file
pipewire-0.3.58.tar.gz/src/pipewire/log.h -> pipewire-0.3.59.tar.gz/src/pipewire/log.h
Changed
@@ -116,7 +116,7 @@ */ #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__) + static struct spa_log_topic *(var) = &(var##__LINE__) /** * Declare a static log topic named \a var. @@ -131,7 +131,7 @@ */ #define PW_LOG_TOPIC(var, topic) \ struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \ - struct spa_log_topic *var = &(var##__LINE__) + struct spa_log_topic *(var) = &(var##__LINE__) #define PW_LOG_TOPIC_INIT(var) \ spa_log_topic_init(pw_log_get(), var);
View file
pipewire-0.3.58.tar.gz/src/pipewire/map.h -> pipewire-0.3.59.tar.gz/src/pipewire/map.h
Changed
@@ -85,7 +85,7 @@ }; /** \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 } +#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.
View file
pipewire-0.3.58.tar.gz/src/pipewire/permission.h -> pipewire-0.3.59.tar.gz/src/pipewire/permission.h
Changed
@@ -66,7 +66,7 @@ uint32_t permissions; /**< bitmask of above permissions */ }; -#define PW_PERMISSION_INIT(id,p) (struct pw_permission){ (id), (p) } +#define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) }) #define PW_PERMISSION_FORMAT "%c%c%c%c" #define PW_PERMISSION_ARGS(permission) \
View file
pipewire-0.3.58.tar.gz/src/pipewire/private.h -> pipewire-0.3.59.tar.gz/src/pipewire/private.h
Changed
@@ -177,7 +177,7 @@ return NULL; } -#define pw_protocol_emit_destroy(p) spa_hook_list_call(&p->listener_list, struct pw_protocol_events, destroy, 0) +#define pw_protocol_emit_destroy(p) spa_hook_list_call(&(p)->listener_list, struct pw_protocol_events, destroy, 0) struct pw_protocol { struct spa_list link; /**< link in context protocol_list */ @@ -805,7 +805,7 @@ #define pw_impl_port_emit_param_changed(p,i) pw_impl_port_emit(p, param_changed, 1, i) #define pw_impl_port_emit_latency_changed(p) pw_impl_port_emit(p, latency_changed, 2) -#define PW_IMPL_PORT_IS_CONTROL(port) SPA_FLAG_MASK(port->flags, \ +#define PW_IMPL_PORT_IS_CONTROL(port) SPA_FLAG_MASK((port)->flags, \ PW_IMPL_PORT_FLAG_BUFFERS|PW_IMPL_PORT_FLAG_CONTROL,\ PW_IMPL_PORT_FLAG_CONTROL) struct pw_impl_port {
View file
pipewire-0.3.58.tar.gz/src/pipewire/stream.c -> pipewire-0.3.59.tar.gz/src/pipewire/stream.c
Changed
@@ -400,6 +400,28 @@ return NULL; } +static inline uint32_t update_requested(struct stream *impl) +{ + uint32_t index, id, res = 0; + struct buffer *buffer; + struct spa_io_rate_match *r = impl->rate_match; + + if (spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index) < 1) + return 0; + + id = impl->dequeued.idsindex & MASK_BUFFERS; + buffer = &impl->buffersid; + if (r) { + buffer->this.requested = r->size; + res = r->size > 0 ? 1 : 0; + } else { + buffer->this.requested = impl->quantum; + res = 1; + } + pw_log_trace_fp("%p: update buffer:%u size:%"PRIu64, impl, id, buffer->this.requested); + return res; +} + static int do_call_process(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) @@ -411,9 +433,11 @@ return 0; } -static void call_process(struct stream *impl) +static inline void call_process(struct stream *impl) { pw_log_trace_fp("%p: call process rt:%u", impl, impl->process_rt); + if (impl->direction == SPA_DIRECTION_OUTPUT && update_requested(impl) <= 0) + return; if (impl->process_rt) spa_callbacks_call(&impl->rt_callbacks, struct pw_stream_events, process, 0); else @@ -563,28 +587,6 @@ return 0; } -static inline uint32_t update_requested(struct stream *impl) -{ - uint32_t index, id, res = 0; - struct buffer *buffer; - struct spa_io_rate_match *r = impl->rate_match; - - if (spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index) < 1) - return 0; - - id = impl->dequeued.idsindex & MASK_BUFFERS; - buffer = &impl->buffersid; - if (r) { - buffer->this.requested = r->size; - res = r->size > 0 ? 1 : 0; - } else { - buffer->this.requested = impl->quantum; - res = 1; - } - pw_log_trace_fp("%p: update buffer:%u size:%"PRIu64, impl, id, buffer->this.requested); - return res; -} - static int impl_send_command(void *object, const struct spa_command *command) { struct stream *impl = object; @@ -612,10 +614,8 @@ if (impl->direction == SPA_DIRECTION_INPUT) impl->io->status = SPA_STATUS_NEED_DATA; - else if (!impl->process_rt && !impl->driving) { - if (update_requested(impl) > 0) - call_process(impl); - } + else if (!impl->process_rt && !impl->driving) + call_process(impl); stream_set_state(stream, PW_STREAM_STATE_STREAMING, NULL); } @@ -1081,8 +1081,7 @@ /* we're not draining, not a driver check if we need to get * more buffers */ if (ask_more) { - if (update_requested(impl) > 0) - call_process(impl); + call_process(impl); /* realtime, we can try again now if there is something. * non-realtime, we will have to try in the next round */ if (impl->process_rt && @@ -1403,7 +1402,7 @@ struct pw_stream *stream; int count; }; -#define MATCH_INIT(s) (struct match){ .stream = s } +#define MATCH_INIT(s) ((struct match){ .stream = (s) }) static int execute_match(void *data, const char *location, const char *action, const char *val, size_t len) @@ -2352,7 +2351,7 @@ int res; if (impl->direction == SPA_DIRECTION_OUTPUT) { if (impl->process_rt) - spa_callbacks_call(&impl->rt_callbacks, struct pw_stream_events, process, 0); + call_process(impl); res = impl->node_methods.process(impl); } else { res = SPA_STATUS_NEED_DATA; @@ -2386,11 +2385,9 @@ if (!impl->driving && !impl->trigger) { res = trigger_request_process(impl); } else { - if (impl->direction == SPA_DIRECTION_OUTPUT && - !impl->process_rt) { - pw_loop_invoke(impl->context->main_loop, - do_call_process, 1, NULL, 0, false, impl); - } + if (!impl->process_rt) + call_process(impl); + res = pw_loop_invoke(impl->context->data_loop, do_trigger_process, 1, NULL, 0, false, impl); }
View file
pipewire-0.3.58.tar.gz/src/pipewire/thread-loop.c -> pipewire-0.3.59.tar.gz/src/pipewire/thread-loop.c
Changed
@@ -91,7 +91,7 @@ #define CHECK(expression,label) \ do { \ - if ((errno = expression) != 0) { \ + if ((errno = (expression)) != 0) { \ res = -errno; \ pw_log_error(#expression ": %s", strerror(errno)); \ goto label; \
View file
pipewire-0.3.58.tar.gz/src/pipewire/thread.c -> pipewire-0.3.59.tar.gz/src/pipewire/thread.c
Changed
@@ -37,7 +37,7 @@ #define CHECK(expression,label) \ do { \ - if ((errno = expression) != 0) { \ + if ((errno = (expression)) != 0) { \ res = -errno; \ pw_log_error(#expression ": %s", strerror(errno)); \ goto label; \
View file
pipewire-0.3.58.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.59.tar.gz/src/tools/pw-cli.c
Changed
@@ -2374,8 +2374,8 @@ fprintf(stderr, "Error: \"%s\"\n", error); free(error); } + data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0); while (!data.quit && data.current) { - data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0); pw_main_loop_run(data.loop); if (!monitor) break;
View file
pipewire-0.3.58.tar.gz/src/tools/pw-dot.c -> pipewire-0.3.59.tar.gz/src/tools/pw-dot.c
Changed
@@ -514,7 +514,7 @@ fputs(d->dot_str, stdout); } else { /* open the file */ - fp = fopen(path, "w"); + fp = fopen(path, "we"); if (fp == NULL) { printf("open error: could not open %s for writing\n", path); return -1;
View file
pipewire-0.3.58.tar.gz/src/tools/pw-profiler.c -> pipewire-0.3.59.tar.gz/src/tools/pw-profiler.c
Changed
@@ -262,7 +262,7 @@ printf("\ndumping scripts for %d followers\n", d->n_followers); - out = fopen("Timing1.plot", "w"); + out = fopen("Timing1.plot", "we"); if (out == NULL) { pw_log_error("Can't open Timing1.plot: %m"); } else { @@ -282,7 +282,7 @@ fclose(out); } - out = fopen("Timing2.plot", "w"); + out = fopen("Timing2.plot", "we"); if (out == NULL) { pw_log_error("Can't open Timing2.plot: %m"); } else { @@ -298,7 +298,7 @@ fclose(out); } - out = fopen("Timing3.plot", "w"); + out = fopen("Timing3.plot", "we"); if (out == NULL) { pw_log_error("Can't open Timing3.plot: %m"); } else { @@ -328,7 +328,7 @@ fclose(out); } - out = fopen("Timing4.plot", "w"); + out = fopen("Timing4.plot", "we"); if (out == NULL) { pw_log_error("Can't open Timing4.plot: %m"); } else { @@ -355,7 +355,7 @@ fclose(out); } - out = fopen("Timing5.plot", "w"); + out = fopen("Timing5.plot", "we"); if (out == NULL) { pw_log_error("Can't open Timing5.plot: %m"); } else { @@ -381,7 +381,7 @@ "unset output\n"); fclose(out); } - out = fopen("Timings.html", "w"); + out = fopen("Timings.html", "we"); if (out == NULL) { pw_log_error("Can't open Timings.html: %m"); } else { @@ -409,7 +409,7 @@ fclose(out); } - out = fopen("generate_timings.sh", "w"); + out = fopen("generate_timings.sh", "we"); if (out == NULL) { pw_log_error("Can't open generate_timings.sh: %m"); } else { @@ -624,7 +624,7 @@ data.filename = opt_output; - data.output = fopen(data.filename, "w"); + data.output = fopen(data.filename, "we"); if (data.output == NULL) { fprintf(stderr, "Can't open file %s: %m\n", data.filename); return -1;
View file
pipewire-0.3.58.tar.gz/test/pwtest.c -> pipewire-0.3.59.tar.gz/test/pwtest.c
Changed
@@ -835,7 +835,7 @@ #ifdef __linux__ { FILE *f; - f = fopen("/proc/sys/fs/pipe-max-size", "r"); + f = fopen("/proc/sys/fs/pipe-max-size", "re"); if (f) { if (fscanf(f, "%d", &r) == 1) pipe_max_size = SPA_MIN(r, pipe_max_size); @@ -1244,7 +1244,7 @@ /* Marker file to avoid removing a random directory during cleanup */ r = spa_scnprintf(path, sizeof(path), "%s/pwtest.dir", dir); spa_assert_se((size_t)r == strlen(dir) + 11); - fp = fopen(path, "w"); + fp = fopen(path, "we"); spa_assert_se(fp); fprintf(fp, "pwtest\n"); fclose(fp);
View file
pipewire-0.3.58.tar.gz/test/test-config.c -> pipewire-0.3.59.tar.gz/test/test-config.c
Changed
@@ -35,7 +35,7 @@ char *basename; pwtest_mkstemp(path); - fp = fopen(path, "w"); + fp = fopen(path, "we"); fputs("data = x", fp); fclose(fp);
View file
pipewire-0.3.58.tar.gz/test/test-logger.c -> pipewire-0.3.59.tar.gz/test/test-logger.c
Changed
@@ -63,7 +63,7 @@ /* Print a line expected to be truncated */ spa_log_error(iface, "MARK: %1100s", "foo"); - fp = fopen(fname, "r"); + fp = fopen(fname, "re"); while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strstr(buffer, "MARK:")) { const char *suffix = ".. (truncated)\n"; @@ -110,7 +110,7 @@ * tty so expect none despite colors being enabled */ spa_log_error(iface, "MARK\n"); - fp = fopen(fname, "r"); + fp = fopen(fname, "re"); while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strstr(buffer, "MARK")) { mark_line_found = true; @@ -157,7 +157,7 @@ if (level < SPA_LOG_LEVEL_TRACE) pw_log(level + 1, "ABOVE"); - fp = fopen(fname, "r"); + fp = fopen(fname, "re"); while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strstr(buffer, "CURRENT")) current_level_found = true; @@ -427,7 +427,7 @@ spa_logt_info(iface, &topic, "MARK\n"); - fp = fopen(fname, "r"); + fp = fopen(fname, "re"); while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strstr(buffer, "MARK")) { mark_line_found = true; @@ -602,7 +602,7 @@ /* Now check that the line is in the chained file logger too */ spa_memzero(buffer, sizeof(buffer)); mark_line_found = false; - fp = fopen(fname, "r"); + fp = fopen(fname, "re"); while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strstr(buffer, token)) { mark_line_found = true;
View file
pipewire-0.3.58.tar.gz/test/test-properties.c -> pipewire-0.3.59.tar.gz/test/test-properties.c
Changed
@@ -484,7 +484,7 @@ dict = SPA_DICT_INIT(items, 2); pwtest_mkstemp(tmpfile); - fp = fopen(tmpfile, "w"); + fp = fopen(tmpfile, "we"); pwtest_ptr_notnull(fp); r = pw_properties_serialize_dict(fp, &dict, 0); pwtest_int_eq(r, 1);
View file
pipewire-0.3.58.tar.gz/test/test-spa-pod.c -> pipewire-0.3.59.tar.gz/test/test-spa-pod.c
Changed
@@ -1639,6 +1639,54 @@ return PWTEST_PASS; } +static int handle_overflow(void *data, uint32_t size) +{ + uint32_t *d = data; + (*d)++; + return -ENOSPC; +} + +static struct spa_pod_builder_callbacks overflow_cb = { + SPA_VERSION_POD_BUILDER_CALLBACKS, + .overflow = handle_overflow +}; + +PWTEST(pod_overflow2) +{ + uint8_t buffer1024; + struct spa_pod_builder b = { 0 }; + struct spa_pod_builder_state state; + struct spa_pod_frame f2; + uint32_t idx, overflow_count = 0; + struct spa_pod *pod; + + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_set_callbacks(&b, &overflow_cb, &overflow_count); + + spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); + spa_pod_builder_add(&b, + SPA_PROP_INFO_id, SPA_POD_Id(32567359), + SPA_PROP_INFO_type, SPA_POD_CHOICE_ENUM_Int(1, 0), + SPA_PROP_INFO_description, SPA_POD_String("DV Timings"), + 0); + + spa_pod_builder_get_state(&b, &state), + + spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0); + spa_pod_builder_push_struct(&b, &f1); + + for (idx = 0; idx < 512; idx++) { + spa_pod_builder_int(&b, idx); + spa_pod_builder_string(&b, "foo"); + } + spa_assert_se(b.state.offset > sizeof(buffer)); + pod = spa_pod_builder_pop(&b, &f1); + spa_assert_se(pod == NULL); + spa_assert_se(overflow_count == 1); + + return PWTEST_PASS; +} + PWTEST_SUITE(spa_pod) { pwtest_add(pod_abi_sizes, PWTEST_NOARG); @@ -1652,6 +1700,7 @@ pwtest_add(pod_parser2, PWTEST_NOARG); pwtest_add(pod_static, PWTEST_NOARG); pwtest_add(pod_overflow, PWTEST_NOARG); + pwtest_add(pod_overflow2, PWTEST_NOARG); return PWTEST_PASS; }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.